From 72fc765454466a974e28c3e34522e2f51e965d07 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 29 Aug 2025 20:04:48 -0400 Subject: [PATCH 001/477] new models yay --- src/backend/src/prisma/schema.prisma | 94 ++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 69a8c8031f..0e14e22708 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -256,6 +256,12 @@ model User { deletedOtherReimbursementProductReasons Reimbursement_Product_Other_Reason[] @relation(name: "deletedOtherReimbursementProductReasons") reimbursementRequestComments Reimbursement_Request_Comment[] @relation(name: "createdReimbursementRequestComments") deletedReimbursementRequestComments Reimbursement_Request_Comment[] @relation(name: "deletedReimbursementRequestComments") + createdMachinery Machinery[] @relation(name: "machineryCreator") + deletedMachinery Machinery[] @relation(name: "machineryDeleter") + createdShops Shop[] @relation(name: "shopCreator") + deletedShops Shop[] @relation(name: "shopDeleter") + approvedEvents Event[] @relation(name: "eventApprover") + eventsAttended Event[] @relation(name: "eventAttender") deletedSponsorTiers Sponsor_Tier[] } @@ -507,6 +513,7 @@ model Work_Package { duration Int blockedBy WBS_Element[] @relation(name: "blockedBy") stage Work_Package_Stage? + event Event[] } model Link_Type { @@ -867,6 +874,91 @@ model Manufacturer { @@unique([name, organizationId], name: "uniqueManufacturer") } +model Shop { + id String @id @default(uuid()) + name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "shopCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") + machinery Machinery[] + description String @default("") + events Event[] +} + +model Machinery { + id String @id @default(uuid()) + name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "machineryCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "machineryDeleter") + quantity Int @default(0) + shop Shop[] + events Event[] +} + +model Event { + id String @id @default(uuid()) + title String + eventTypeId String + type EventType @relation(fields: [eventTypeId], references: [id]) + approved Boolean? + approvedByUserId String? + approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") + // Meeting times are an integer between 0 and 11 from 10am - 10pm for the date scheduled at hour intervals + meetingTimes Int[] + initialDateScheduled DateTime @db.Date + allDay Boolean @default(false) + recurring Boolean @default(false) + memberId String? + members User? @relation(fields: [memberId], references: [userId], name: "eventAttender") + location String? + zoomLink String? + availabilities Availability[] + Shop Shop? @relation(fields: [shopId], references: [id]) + shopId String? + machineryId String? + Machinery Machinery? @relation(fields: [machineryId], references: [id]) + workPackagaeId String? + workPackage Work_Package? @relation(fields: [workPackagaeId], references: [workPackageId]) + description String? +} + +model Calendar { + id String @id @default(uuid()) + name String + description String @default("") + colorHexCode String + eventTypes EventType[] +} + +model EventType { + id String @id @default(uuid()) + name String + calendarId String + calendar Calendar @relation(fields: [calendarId], references: [id]) + // Meeting times are an integer between 0 and 11 from 10am - 10pm for the date scheduled at hour intervals + meetingTimes Boolean? + initialDateScheduled Boolean? + allDay Boolean? + recurring Boolean? + members Boolean? + location Boolean? + zoomLink Boolean? + availabilities Boolean? + shop Boolean? + machinery Boolean? + workPackage Boolean? + documents Boolean? + description Boolean? + events Event[] +} + model Team_Type { teamTypeId String @id @default(uuid()) name String @@ -924,6 +1016,8 @@ model Availability { availabilityId String @id @default(uuid()) scheduleSettingsId String scheduleSettings Schedule_Settings @relation(fields: [scheduleSettingsId], references: [drScheduleSettingsId]) + eventId String? + Event Event? @relation(fields: [eventId], references: [id]) // Availibilies are integers between 0 and 11 from 10am - 10pm for a given day at hour intervals see meetingTime field in Design_Review availability Int[] From e923284687b55967bc18f1a6a232c74e8c78c8ee Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 29 Aug 2025 20:12:45 -0400 Subject: [PATCH 002/477] typo --- src/backend/src/prisma/schema.prisma | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 0e14e22708..d555005137 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -924,8 +924,8 @@ model Event { shopId String? machineryId String? Machinery Machinery? @relation(fields: [machineryId], references: [id]) - workPackagaeId String? - workPackage Work_Package? @relation(fields: [workPackagaeId], references: [workPackageId]) + workPackageId String? + workPackage Work_Package? @relation(fields: [workPackageId], references: [workPackageId]) description String? } From 2c9fde754334931cf1b6fefa92a8fd508a56f77f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 29 Aug 2025 20:14:45 -0400 Subject: [PATCH 003/477] date created/deleted --- src/backend/src/prisma/schema.prisma | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index d555005137..03c3f169d7 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -904,6 +904,8 @@ model Machinery { model Event { id String @id @default(uuid()) + dateCreated DateTime @default(now()) + dateDeleted DateTime? title String eventTypeId String type EventType @relation(fields: [eventTypeId], references: [id]) @@ -932,16 +934,20 @@ model Event { model Calendar { id String @id @default(uuid()) name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? description String @default("") colorHexCode String eventTypes EventType[] } model EventType { - id String @id @default(uuid()) + id String @id @default(uuid()) name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? calendarId String - calendar Calendar @relation(fields: [calendarId], references: [id]) + calendar Calendar @relation(fields: [calendarId], references: [id]) // Meeting times are an integer between 0 and 11 from 10am - 10pm for the date scheduled at hour intervals meetingTimes Boolean? initialDateScheduled Boolean? From bbdc27072169fd64902e8721d6fbf34eaf5f66ac Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 29 Aug 2025 21:05:33 -0400 Subject: [PATCH 004/477] migration --- .../20250830002452_calendar/migration.sql | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql diff --git a/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql b/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql new file mode 100644 index 0000000000..276836d524 --- /dev/null +++ b/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql @@ -0,0 +1,141 @@ +-- AlterTable +ALTER TABLE "public"."Availability" ADD COLUMN "eventId" TEXT; + +-- CreateTable +CREATE TABLE "public"."Shop" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "description" TEXT NOT NULL DEFAULT '', + + CONSTRAINT "Shop_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."Machinery" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "quantity" INTEGER NOT NULL DEFAULT 0, + + CONSTRAINT "Machinery_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."Event" ( + "id" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "title" TEXT NOT NULL, + "eventTypeId" TEXT NOT NULL, + "approved" BOOLEAN, + "approvedByUserId" TEXT, + "meetingTimes" INTEGER[], + "initialDateScheduled" DATE NOT NULL, + "allDay" BOOLEAN NOT NULL DEFAULT false, + "recurring" BOOLEAN NOT NULL DEFAULT false, + "memberId" TEXT, + "location" TEXT, + "zoomLink" TEXT, + "shopId" TEXT, + "machineryId" TEXT, + "workPackageId" TEXT, + "description" TEXT, + + CONSTRAINT "Event_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."Calendar" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "description" TEXT NOT NULL DEFAULT '', + "colorHexCode" TEXT NOT NULL, + + CONSTRAINT "Calendar_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."EventType" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "calendarId" TEXT NOT NULL, + "meetingTimes" BOOLEAN, + "initialDateScheduled" BOOLEAN, + "allDay" BOOLEAN, + "recurring" BOOLEAN, + "members" BOOLEAN, + "location" BOOLEAN, + "zoomLink" BOOLEAN, + "availabilities" BOOLEAN, + "shop" BOOLEAN, + "machinery" BOOLEAN, + "workPackage" BOOLEAN, + "documents" BOOLEAN, + "description" BOOLEAN, + + CONSTRAINT "EventType_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "public"."_MachineryToShop" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_MachineryToShop_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE INDEX "_MachineryToShop_B_index" ON "public"."_MachineryToShop"("B"); + +-- AddForeignKey +ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "public"."EventType"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_approvedByUserId_fkey" FOREIGN KEY ("approvedByUserId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_memberId_fkey" FOREIGN KEY ("memberId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_workPackageId_fkey" FOREIGN KEY ("workPackageId") REFERENCES "public"."Work_Package"("workPackageId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_calendarId_fkey" FOREIGN KEY ("calendarId") REFERENCES "public"."Calendar"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Machinery"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("id") ON DELETE CASCADE ON UPDATE CASCADE; From 60ddec0a185d797c1b8857dd690be342a1cbe252 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 30 Aug 2025 01:44:14 -0400 Subject: [PATCH 005/477] requested changes --- src/backend/src/prisma/schema.prisma | 58 ++++++++++++++++++---------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 03c3f169d7..069d898cbc 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -262,6 +262,12 @@ model User { deletedShops Shop[] @relation(name: "shopDeleter") approvedEvents Event[] @relation(name: "eventApprover") eventsAttended Event[] @relation(name: "eventAttender") + createdEvents Event[] @relation(name: "eventCreator") + deletedEvents Event[] @relation(name: "eventDeleter") + createdCalendars Calendar[] @relation(name: "calendarCreator") + deletedCalendars Calendar[] @relation(name: "calendarDeleter") + createdEventTypes EventType[] @relation(name: "eventTypeCreator") + deletedEventTypes EventType[] @relation(name: "eventTypeDeleter") deletedSponsorTiers Sponsor_Tier[] } @@ -513,7 +519,7 @@ model Work_Package { duration Int blockedBy WBS_Element[] @relation(name: "blockedBy") stage Work_Package_Stage? - event Event[] + events Event[] } model Link_Type { @@ -875,7 +881,7 @@ model Manufacturer { } model Shop { - id String @id @default(uuid()) + shopId String @id @default(uuid()) name String dateCreated DateTime @default(now()) dateDeleted DateTime? @@ -889,7 +895,7 @@ model Shop { } model Machinery { - id String @id @default(uuid()) + machineryId String @id @default(uuid()) name String dateCreated DateTime @default(now()) dateDeleted DateTime? @@ -898,17 +904,21 @@ model Machinery { userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "machineryDeleter") quantity Int @default(0) - shop Shop[] + shops Shop[] events Event[] } model Event { - id String @id @default(uuid()) + eventId String @id @default(uuid()) dateCreated DateTime @default(now()) dateDeleted DateTime? title String + userCreatedId String + userCreated User @relation(name: "eventCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventDeleter") eventTypeId String - type EventType @relation(fields: [eventTypeId], references: [id]) + eventType EventType @relation(fields: [eventTypeId], references: [eventTypeId]) approved Boolean? approvedByUserId String? approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") @@ -916,38 +926,46 @@ model Event { meetingTimes Int[] initialDateScheduled DateTime @db.Date allDay Boolean @default(false) - recurring Boolean @default(false) + recurringInterval Int // the number of days between each meeting (0 = no recurring) memberId String? - members User? @relation(fields: [memberId], references: [userId], name: "eventAttender") + members User[] @relation(name: "eventAttender") location String? zoomLink String? availabilities Availability[] - Shop Shop? @relation(fields: [shopId], references: [id]) + shop Shop? @relation(fields: [shopId], references: [shopId]) shopId String? machineryId String? - Machinery Machinery? @relation(fields: [machineryId], references: [id]) + machinery Machinery? @relation(fields: [machineryId], references: [machineryId]) workPackageId String? workPackage Work_Package? @relation(fields: [workPackageId], references: [workPackageId]) description String? } model Calendar { - id String @id @default(uuid()) - name String - dateCreated DateTime @default(now()) - dateDeleted DateTime? - description String @default("") - colorHexCode String - eventTypes EventType[] + calendarId String @id @default(uuid()) + name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "calendarCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "calendarDeleter") + description String @default("") + colorHexCode String + eventTypes EventType[] } model EventType { - id String @id @default(uuid()) + eventTypeId String @id @default(uuid()) name String dateCreated DateTime @default(now()) dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") calendarId String - calendar Calendar @relation(fields: [calendarId], references: [id]) + calendar Calendar @relation(fields: [calendarId], references: [calendarId]) // Meeting times are an integer between 0 and 11 from 10am - 10pm for the date scheduled at hour intervals meetingTimes Boolean? initialDateScheduled Boolean? @@ -1023,7 +1041,7 @@ model Availability { scheduleSettingsId String scheduleSettings Schedule_Settings @relation(fields: [scheduleSettingsId], references: [drScheduleSettingsId]) eventId String? - Event Event? @relation(fields: [eventId], references: [id]) + event Event? @relation(fields: [eventId], references: [eventId]) // Availibilies are integers between 0 and 11 from 10am - 10pm for a given day at hour intervals see meetingTime field in Design_Review availability Int[] From fe7515f2772f0e620fd6cf600fc5ae8ec6d1750d Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 30 Aug 2025 01:46:24 -0400 Subject: [PATCH 006/477] migration fix --- .../20250830002452_calendar/migration.sql | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql b/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql index 276836d524..76ff9804db 100644 --- a/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql @@ -139,3 +139,146 @@ ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_A_fkey" -- AddForeignKey ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +/* + Warnings: + + - The primary key for the `Calendar` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `id` on the `Calendar` table. All the data in the column will be lost. + - The primary key for the `Event` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `id` on the `Event` table. All the data in the column will be lost. + - You are about to drop the column `recurring` on the `Event` table. All the data in the column will be lost. + - The primary key for the `EventType` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `id` on the `EventType` table. All the data in the column will be lost. + - The primary key for the `Machinery` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `id` on the `Machinery` table. All the data in the column will be lost. + - The primary key for the `Shop` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `id` on the `Shop` table. All the data in the column will be lost. + - The required column `calendarId` was added to the `Calendar` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. + - Added the required column `userCreatedId` to the `Calendar` table without a default value. This is not possible if the table is not empty. + - The required column `eventId` was added to the `Event` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. + - Added the required column `recurringInterval` to the `Event` table without a default value. This is not possible if the table is not empty. + - Added the required column `userCreatedId` to the `Event` table without a default value. This is not possible if the table is not empty. + - The required column `eventTypeId` was added to the `EventType` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. + - Added the required column `userCreatedId` to the `EventType` table without a default value. This is not possible if the table is not empty. + - The required column `machineryId` was added to the `Machinery` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. + - The required column `shopId` was added to the `Shop` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. + +*/ +-- DropForeignKey +ALTER TABLE "public"."Availability" DROP CONSTRAINT "Availability_eventId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_eventTypeId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_machineryId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_memberId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_shopId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."EventType" DROP CONSTRAINT "EventType_calendarId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_MachineryToShop" DROP CONSTRAINT "_MachineryToShop_A_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_MachineryToShop" DROP CONSTRAINT "_MachineryToShop_B_fkey"; + +-- AlterTable +ALTER TABLE "public"."Calendar" DROP CONSTRAINT "Calendar_pkey", +DROP COLUMN "id", +ADD COLUMN "calendarId" TEXT NOT NULL, +ADD COLUMN "userCreatedId" TEXT NOT NULL, +ADD COLUMN "userDeletedId" TEXT, +ADD CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId"); + +-- AlterTable +ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_pkey", +DROP COLUMN "id", +DROP COLUMN "recurring", +ADD COLUMN "eventId" TEXT NOT NULL, +ADD COLUMN "recurringInterval" INTEGER NOT NULL, +ADD COLUMN "userCreatedId" TEXT NOT NULL, +ADD COLUMN "userDeletedId" TEXT, +ADD CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId"); + +-- AlterTable +ALTER TABLE "public"."EventType" DROP CONSTRAINT "EventType_pkey", +DROP COLUMN "id", +ADD COLUMN "eventTypeId" TEXT NOT NULL, +ADD COLUMN "userCreatedId" TEXT NOT NULL, +ADD COLUMN "userDeletedId" TEXT, +ADD CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId"); + +-- AlterTable +ALTER TABLE "public"."Machinery" DROP CONSTRAINT "Machinery_pkey", +DROP COLUMN "id", +ADD COLUMN "machineryId" TEXT NOT NULL, +ADD CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId"); + +-- AlterTable +ALTER TABLE "public"."Shop" DROP CONSTRAINT "Shop_pkey", +DROP COLUMN "id", +ADD COLUMN "shopId" TEXT NOT NULL, +ADD CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId"); + +-- CreateTable +CREATE TABLE "public"."_eventAttender" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_eventAttender_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "public"."EventType"("eventTypeId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("shopId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("machineryId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_calendarId_fkey" FOREIGN KEY ("calendarId") REFERENCES "public"."Calendar"("calendarId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; \ No newline at end of file From 176ab6f67ac7aabe475a4526d348c9a4caaad383 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 30 Aug 2025 01:51:24 -0400 Subject: [PATCH 007/477] minor update --- .../20250830002452_calendar/migration.sql | 284 ------------------ .../20250830055112_calendar/migration.sql | 180 +++++++++++ src/backend/src/prisma/schema.prisma | 1 + 3 files changed, 181 insertions(+), 284 deletions(-) delete mode 100644 src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql create mode 100644 src/backend/src/prisma/migrations/20250830055112_calendar/migration.sql diff --git a/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql b/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql deleted file mode 100644 index 76ff9804db..0000000000 --- a/src/backend/src/prisma/migrations/20250830002452_calendar/migration.sql +++ /dev/null @@ -1,284 +0,0 @@ --- AlterTable -ALTER TABLE "public"."Availability" ADD COLUMN "eventId" TEXT; - --- CreateTable -CREATE TABLE "public"."Shop" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "description" TEXT NOT NULL DEFAULT '', - - CONSTRAINT "Shop_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "public"."Machinery" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "quantity" INTEGER NOT NULL DEFAULT 0, - - CONSTRAINT "Machinery_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "public"."Event" ( - "id" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "title" TEXT NOT NULL, - "eventTypeId" TEXT NOT NULL, - "approved" BOOLEAN, - "approvedByUserId" TEXT, - "meetingTimes" INTEGER[], - "initialDateScheduled" DATE NOT NULL, - "allDay" BOOLEAN NOT NULL DEFAULT false, - "recurring" BOOLEAN NOT NULL DEFAULT false, - "memberId" TEXT, - "location" TEXT, - "zoomLink" TEXT, - "shopId" TEXT, - "machineryId" TEXT, - "workPackageId" TEXT, - "description" TEXT, - - CONSTRAINT "Event_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "public"."Calendar" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "description" TEXT NOT NULL DEFAULT '', - "colorHexCode" TEXT NOT NULL, - - CONSTRAINT "Calendar_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "public"."EventType" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "calendarId" TEXT NOT NULL, - "meetingTimes" BOOLEAN, - "initialDateScheduled" BOOLEAN, - "allDay" BOOLEAN, - "recurring" BOOLEAN, - "members" BOOLEAN, - "location" BOOLEAN, - "zoomLink" BOOLEAN, - "availabilities" BOOLEAN, - "shop" BOOLEAN, - "machinery" BOOLEAN, - "workPackage" BOOLEAN, - "documents" BOOLEAN, - "description" BOOLEAN, - - CONSTRAINT "EventType_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "public"."_MachineryToShop" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_MachineryToShop_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateIndex -CREATE INDEX "_MachineryToShop_B_index" ON "public"."_MachineryToShop"("B"); - --- AddForeignKey -ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "public"."EventType"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_approvedByUserId_fkey" FOREIGN KEY ("approvedByUserId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_memberId_fkey" FOREIGN KEY ("memberId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_workPackageId_fkey" FOREIGN KEY ("workPackageId") REFERENCES "public"."Work_Package"("workPackageId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_calendarId_fkey" FOREIGN KEY ("calendarId") REFERENCES "public"."Calendar"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("id") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Machinery"("id") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("id") ON DELETE CASCADE ON UPDATE CASCADE; - -/* - Warnings: - - - The primary key for the `Calendar` table will be changed. If it partially fails, the table could be left without primary key constraint. - - You are about to drop the column `id` on the `Calendar` table. All the data in the column will be lost. - - The primary key for the `Event` table will be changed. If it partially fails, the table could be left without primary key constraint. - - You are about to drop the column `id` on the `Event` table. All the data in the column will be lost. - - You are about to drop the column `recurring` on the `Event` table. All the data in the column will be lost. - - The primary key for the `EventType` table will be changed. If it partially fails, the table could be left without primary key constraint. - - You are about to drop the column `id` on the `EventType` table. All the data in the column will be lost. - - The primary key for the `Machinery` table will be changed. If it partially fails, the table could be left without primary key constraint. - - You are about to drop the column `id` on the `Machinery` table. All the data in the column will be lost. - - The primary key for the `Shop` table will be changed. If it partially fails, the table could be left without primary key constraint. - - You are about to drop the column `id` on the `Shop` table. All the data in the column will be lost. - - The required column `calendarId` was added to the `Calendar` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. - - Added the required column `userCreatedId` to the `Calendar` table without a default value. This is not possible if the table is not empty. - - The required column `eventId` was added to the `Event` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. - - Added the required column `recurringInterval` to the `Event` table without a default value. This is not possible if the table is not empty. - - Added the required column `userCreatedId` to the `Event` table without a default value. This is not possible if the table is not empty. - - The required column `eventTypeId` was added to the `EventType` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. - - Added the required column `userCreatedId` to the `EventType` table without a default value. This is not possible if the table is not empty. - - The required column `machineryId` was added to the `Machinery` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. - - The required column `shopId` was added to the `Shop` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. - -*/ --- DropForeignKey -ALTER TABLE "public"."Availability" DROP CONSTRAINT "Availability_eventId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_eventTypeId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_machineryId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_memberId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_shopId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."EventType" DROP CONSTRAINT "EventType_calendarId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_MachineryToShop" DROP CONSTRAINT "_MachineryToShop_A_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_MachineryToShop" DROP CONSTRAINT "_MachineryToShop_B_fkey"; - --- AlterTable -ALTER TABLE "public"."Calendar" DROP CONSTRAINT "Calendar_pkey", -DROP COLUMN "id", -ADD COLUMN "calendarId" TEXT NOT NULL, -ADD COLUMN "userCreatedId" TEXT NOT NULL, -ADD COLUMN "userDeletedId" TEXT, -ADD CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId"); - --- AlterTable -ALTER TABLE "public"."Event" DROP CONSTRAINT "Event_pkey", -DROP COLUMN "id", -DROP COLUMN "recurring", -ADD COLUMN "eventId" TEXT NOT NULL, -ADD COLUMN "recurringInterval" INTEGER NOT NULL, -ADD COLUMN "userCreatedId" TEXT NOT NULL, -ADD COLUMN "userDeletedId" TEXT, -ADD CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId"); - --- AlterTable -ALTER TABLE "public"."EventType" DROP CONSTRAINT "EventType_pkey", -DROP COLUMN "id", -ADD COLUMN "eventTypeId" TEXT NOT NULL, -ADD COLUMN "userCreatedId" TEXT NOT NULL, -ADD COLUMN "userDeletedId" TEXT, -ADD CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId"); - --- AlterTable -ALTER TABLE "public"."Machinery" DROP CONSTRAINT "Machinery_pkey", -DROP COLUMN "id", -ADD COLUMN "machineryId" TEXT NOT NULL, -ADD CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId"); - --- AlterTable -ALTER TABLE "public"."Shop" DROP CONSTRAINT "Shop_pkey", -DROP COLUMN "id", -ADD COLUMN "shopId" TEXT NOT NULL, -ADD CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId"); - --- CreateTable -CREATE TABLE "public"."_eventAttender" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_eventAttender_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateIndex -CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "public"."EventType"("eventTypeId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("shopId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("machineryId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_calendarId_fkey" FOREIGN KEY ("calendarId") REFERENCES "public"."Calendar"("calendarId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; \ No newline at end of file diff --git a/src/backend/src/prisma/migrations/20250830055112_calendar/migration.sql b/src/backend/src/prisma/migrations/20250830055112_calendar/migration.sql new file mode 100644 index 0000000000..fae11605ff --- /dev/null +++ b/src/backend/src/prisma/migrations/20250830055112_calendar/migration.sql @@ -0,0 +1,180 @@ +-- AlterTable +ALTER TABLE "public"."Availability" ADD COLUMN "eventId" TEXT; + +-- CreateTable +CREATE TABLE "public"."Shop" ( + "shopId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "description" TEXT NOT NULL DEFAULT '', + + CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId") +); + +-- CreateTable +CREATE TABLE "public"."Machinery" ( + "machineryId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "quantity" INTEGER NOT NULL DEFAULT 0, + + CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId") +); + +-- CreateTable +CREATE TABLE "public"."Event" ( + "eventId" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "title" TEXT NOT NULL, + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "eventTypeId" TEXT NOT NULL, + "approved" BOOLEAN, + "approvedByUserId" TEXT, + "meetingTimes" INTEGER[], + "initialDateScheduled" DATE NOT NULL, + "allDay" BOOLEAN NOT NULL DEFAULT false, + "recurringInterval" INTEGER NOT NULL, + "memberId" TEXT, + "location" TEXT, + "zoomLink" TEXT, + "shopId" TEXT, + "machineryId" TEXT, + "workPackageId" TEXT, + "documents" TEXT[], + "description" TEXT, + + CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId") +); + +-- CreateTable +CREATE TABLE "public"."Calendar" ( + "calendarId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "description" TEXT NOT NULL DEFAULT '', + "colorHexCode" TEXT NOT NULL, + + CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId") +); + +-- CreateTable +CREATE TABLE "public"."EventType" ( + "eventTypeId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "calendarId" TEXT NOT NULL, + "meetingTimes" BOOLEAN, + "initialDateScheduled" BOOLEAN, + "allDay" BOOLEAN, + "recurring" BOOLEAN, + "members" BOOLEAN, + "location" BOOLEAN, + "zoomLink" BOOLEAN, + "availabilities" BOOLEAN, + "shop" BOOLEAN, + "machinery" BOOLEAN, + "workPackage" BOOLEAN, + "documents" BOOLEAN, + "description" BOOLEAN, + + CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") +); + +-- CreateTable +CREATE TABLE "public"."_MachineryToShop" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_MachineryToShop_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_eventAttender" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_eventAttender_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE INDEX "_MachineryToShop_B_index" ON "public"."_MachineryToShop"("B"); + +-- CreateIndex +CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); + +-- AddForeignKey +ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "public"."EventType"("eventTypeId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_approvedByUserId_fkey" FOREIGN KEY ("approvedByUserId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("shopId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("machineryId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_workPackageId_fkey" FOREIGN KEY ("workPackageId") REFERENCES "public"."Work_Package"("workPackageId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_calendarId_fkey" FOREIGN KEY ("calendarId") REFERENCES "public"."Calendar"("calendarId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 069d898cbc..cb3c9906d5 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -938,6 +938,7 @@ model Event { machinery Machinery? @relation(fields: [machineryId], references: [machineryId]) workPackageId String? workPackage Work_Package? @relation(fields: [workPackageId], references: [workPackageId]) + documents String[] description String? } From 68a49524993fbf3d1625f0f31ac543cce3123f53 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 30 Aug 2025 10:49:07 -0400 Subject: [PATCH 008/477] remove clutter --- src/backend/src/prisma/schema.prisma | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index cb3c9906d5..c00373cfc8 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -890,7 +890,7 @@ model Shop { userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") machinery Machinery[] - description String @default("") + description String events Event[] } @@ -951,7 +951,7 @@ model Calendar { userCreated User @relation(name: "calendarCreator", fields: [userCreatedId], references: [userId]) userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "calendarDeleter") - description String @default("") + description String colorHexCode String eventTypes EventType[] } From e2df20c380b3e58d97f9573271cc6296737b833a Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 30 Aug 2025 11:13:44 -0400 Subject: [PATCH 009/477] revert --- src/backend/src/prisma/schema.prisma | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index c00373cfc8..f98ae61faa 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -890,7 +890,7 @@ model Shop { userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") machinery Machinery[] - description String + description String @default("") events Event[] } @@ -938,7 +938,7 @@ model Event { machinery Machinery? @relation(fields: [machineryId], references: [machineryId]) workPackageId String? workPackage Work_Package? @relation(fields: [workPackageId], references: [workPackageId]) - documents String[] + documentIds String[] description String? } @@ -951,7 +951,7 @@ model Calendar { userCreated User @relation(name: "calendarCreator", fields: [userCreatedId], references: [userId]) userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "calendarDeleter") - description String + description String @default("") colorHexCode String eventTypes EventType[] } From bd20373e80d05ce02970334953159a10e28271c0 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 30 Aug 2025 13:01:58 -0400 Subject: [PATCH 010/477] new stuff --- .../migration.sql | 36 +++++++++---------- src/backend/src/prisma/schema.prisma | 34 +++++++++++------- 2 files changed, 37 insertions(+), 33 deletions(-) rename src/backend/src/prisma/migrations/{20250830055112_calendar => 20250830165943_calendar}/migration.sql (91%) diff --git a/src/backend/src/prisma/migrations/20250830055112_calendar/migration.sql b/src/backend/src/prisma/migrations/20250830165943_calendar/migration.sql similarity index 91% rename from src/backend/src/prisma/migrations/20250830055112_calendar/migration.sql rename to src/backend/src/prisma/migrations/20250830165943_calendar/migration.sql index fae11605ff..c53d50411d 100644 --- a/src/backend/src/prisma/migrations/20250830055112_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250830165943_calendar/migration.sql @@ -22,11 +22,19 @@ CREATE TABLE "public"."Machinery" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, - "quantity" INTEGER NOT NULL DEFAULT 0, CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId") ); +-- CreateTable +CREATE TABLE "public"."ShopMachinery" ( + "shopId" TEXT NOT NULL, + "machineryId" TEXT NOT NULL, + "quantity" INTEGER NOT NULL DEFAULT 0, + + CONSTRAINT "ShopMachinery_pkey" PRIMARY KEY ("shopId","machineryId") +); + -- CreateTable CREATE TABLE "public"."Event" ( "eventId" TEXT NOT NULL, @@ -42,13 +50,12 @@ CREATE TABLE "public"."Event" ( "initialDateScheduled" DATE NOT NULL, "allDay" BOOLEAN NOT NULL DEFAULT false, "recurringInterval" INTEGER NOT NULL, - "memberId" TEXT, "location" TEXT, "zoomLink" TEXT, "shopId" TEXT, "machineryId" TEXT, "workPackageId" TEXT, - "documents" TEXT[], + "documentIds" TEXT[], "description" TEXT, CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId") @@ -94,14 +101,6 @@ CREATE TABLE "public"."EventType" ( CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") ); --- CreateTable -CREATE TABLE "public"."_MachineryToShop" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_MachineryToShop_AB_pkey" PRIMARY KEY ("A","B") -); - -- CreateTable CREATE TABLE "public"."_eventAttender" ( "A" TEXT NOT NULL, @@ -110,9 +109,6 @@ CREATE TABLE "public"."_eventAttender" ( CONSTRAINT "_eventAttender_AB_pkey" PRIMARY KEY ("A","B") ); --- CreateIndex -CREATE INDEX "_MachineryToShop_B_index" ON "public"."_MachineryToShop"("B"); - -- CreateIndex CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); @@ -128,6 +124,12 @@ ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" F -- AddForeignKey ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "public"."ShopMachinery" ADD CONSTRAINT "ShopMachinery_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("shopId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."ShopMachinery" ADD CONSTRAINT "ShopMachinery_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("machineryId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; @@ -167,12 +169,6 @@ ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_calendarId_fkey" FORE -- AddForeignKey ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; --- AddForeignKey -ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_MachineryToShop" ADD CONSTRAINT "_MachineryToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; - -- AddForeignKey ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index f98ae61faa..7fa806b7aa 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -881,33 +881,42 @@ model Manufacturer { } model Shop { - shopId String @id @default(uuid()) + shopId String @id @default(uuid()) name String - dateCreated DateTime @default(now()) + dateCreated DateTime @default(now()) dateDeleted DateTime? userCreatedId String - userCreated User @relation(name: "shopCreator", fields: [userCreatedId], references: [userId]) + userCreated User @relation(name: "shopCreator", fields: [userCreatedId], references: [userId]) userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") - machinery Machinery[] - description String @default("") + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") + machinery ShopMachinery[] + description String @default("") events Event[] } model Machinery { - machineryId String @id @default(uuid()) + machineryId String @id @default(uuid()) name String - dateCreated DateTime @default(now()) + dateCreated DateTime @default(now()) dateDeleted DateTime? userCreatedId String - userCreated User @relation(name: "machineryCreator", fields: [userCreatedId], references: [userId]) + userCreated User @relation(name: "machineryCreator", fields: [userCreatedId], references: [userId]) userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "machineryDeleter") - quantity Int @default(0) - shops Shop[] + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "machineryDeleter") + shops ShopMachinery[] events Event[] } +model ShopMachinery { + shopId String + machineryId String + quantity Int @default(0) + shop Shop @relation(fields: [shopId], references: [shopId]) + machinery Machinery @relation(fields: [machineryId], references: [machineryId]) + + @@id([shopId, machineryId]) +} + model Event { eventId String @id @default(uuid()) dateCreated DateTime @default(now()) @@ -927,7 +936,6 @@ model Event { initialDateScheduled DateTime @db.Date allDay Boolean @default(false) recurringInterval Int // the number of days between each meeting (0 = no recurring) - memberId String? members User[] @relation(name: "eventAttender") location String? zoomLink String? From 46db5286fe6fd286ae7ba6ff05ec654923c87493 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 30 Aug 2025 13:54:55 -0400 Subject: [PATCH 011/477] update to be more in line with request --- .../migration.sql | 8 +++++--- src/backend/src/prisma/schema.prisma | 15 ++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) rename src/backend/src/prisma/migrations/{20250830165943_calendar => 20250830175323_calendar}/migration.sql (97%) diff --git a/src/backend/src/prisma/migrations/20250830165943_calendar/migration.sql b/src/backend/src/prisma/migrations/20250830175323_calendar/migration.sql similarity index 97% rename from src/backend/src/prisma/migrations/20250830165943_calendar/migration.sql rename to src/backend/src/prisma/migrations/20250830175323_calendar/migration.sql index c53d50411d..a30d623b24 100644 --- a/src/backend/src/prisma/migrations/20250830165943_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250830175323_calendar/migration.sql @@ -28,11 +28,10 @@ CREATE TABLE "public"."Machinery" ( -- CreateTable CREATE TABLE "public"."ShopMachinery" ( + "shopMachineryId" TEXT NOT NULL, "shopId" TEXT NOT NULL, "machineryId" TEXT NOT NULL, - "quantity" INTEGER NOT NULL DEFAULT 0, - - CONSTRAINT "ShopMachinery_pkey" PRIMARY KEY ("shopId","machineryId") + "quantity" INTEGER NOT NULL DEFAULT 0 ); -- CreateTable @@ -109,6 +108,9 @@ CREATE TABLE "public"."_eventAttender" ( CONSTRAINT "_eventAttender_AB_pkey" PRIMARY KEY ("A","B") ); +-- CreateIndex +CREATE UNIQUE INDEX "ShopMachinery_shopId_machineryId_key" ON "public"."ShopMachinery"("shopId", "machineryId"); + -- CreateIndex CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 7fa806b7aa..31d8cb42b7 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -908,13 +908,14 @@ model Machinery { } model ShopMachinery { - shopId String - machineryId String - quantity Int @default(0) - shop Shop @relation(fields: [shopId], references: [shopId]) - machinery Machinery @relation(fields: [machineryId], references: [machineryId]) - - @@id([shopId, machineryId]) + shopMachineryId String + shopId String + machineryId String + quantity Int @default(0) + shop Shop @relation(fields: [shopId], references: [shopId]) + machinery Machinery @relation(fields: [machineryId], references: [machineryId]) + + @@unique([shopId, machineryId], name: "uniqueShopMachinery") } model Event { From 9bd7aa0f728c010a18412e546a8f5a6f23cf1556 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 30 Aug 2025 14:01:26 -0400 Subject: [PATCH 012/477] forgot the @id --- .../migration.sql | 4 +++- src/backend/src/prisma/schema.prisma | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) rename src/backend/src/prisma/migrations/{20250830175323_calendar => 20250830180036_calendar}/migration.sql (98%) diff --git a/src/backend/src/prisma/migrations/20250830175323_calendar/migration.sql b/src/backend/src/prisma/migrations/20250830180036_calendar/migration.sql similarity index 98% rename from src/backend/src/prisma/migrations/20250830175323_calendar/migration.sql rename to src/backend/src/prisma/migrations/20250830180036_calendar/migration.sql index a30d623b24..92a582d3db 100644 --- a/src/backend/src/prisma/migrations/20250830175323_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250830180036_calendar/migration.sql @@ -31,7 +31,9 @@ CREATE TABLE "public"."ShopMachinery" ( "shopMachineryId" TEXT NOT NULL, "shopId" TEXT NOT NULL, "machineryId" TEXT NOT NULL, - "quantity" INTEGER NOT NULL DEFAULT 0 + "quantity" INTEGER NOT NULL DEFAULT 0, + + CONSTRAINT "ShopMachinery_pkey" PRIMARY KEY ("shopMachineryId") ); -- CreateTable diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 31d8cb42b7..fca44be73a 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -908,7 +908,7 @@ model Machinery { } model ShopMachinery { - shopMachineryId String + shopMachineryId String @id @default(uuid()) shopId String machineryId String quantity Int @default(0) From 4bd4669948dd7cc095e7f37948ada0ca2f59eceb Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 31 Aug 2025 10:23:50 -0400 Subject: [PATCH 013/477] defaults removed --- .../migration.sql | 4 ++-- src/backend/src/prisma/schema.prisma | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/backend/src/prisma/migrations/{20250830180036_calendar => 20250831142319_calendar}/migration.sql (98%) diff --git a/src/backend/src/prisma/migrations/20250830180036_calendar/migration.sql b/src/backend/src/prisma/migrations/20250831142319_calendar/migration.sql similarity index 98% rename from src/backend/src/prisma/migrations/20250830180036_calendar/migration.sql rename to src/backend/src/prisma/migrations/20250831142319_calendar/migration.sql index 92a582d3db..71771cd04f 100644 --- a/src/backend/src/prisma/migrations/20250830180036_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250831142319_calendar/migration.sql @@ -9,7 +9,7 @@ CREATE TABLE "public"."Shop" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, - "description" TEXT NOT NULL DEFAULT '', + "description" TEXT NOT NULL, CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId") ); @@ -70,7 +70,7 @@ CREATE TABLE "public"."Calendar" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, - "description" TEXT NOT NULL DEFAULT '', + "description" TEXT NOT NULL, "colorHexCode" TEXT NOT NULL, CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId") diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index fca44be73a..6c2a04a400 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -890,7 +890,7 @@ model Shop { userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") machinery ShopMachinery[] - description String @default("") + description String events Event[] } @@ -960,7 +960,7 @@ model Calendar { userCreated User @relation(name: "calendarCreator", fields: [userCreatedId], references: [userId]) userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "calendarDeleter") - description String @default("") + description String colorHexCode String eventTypes EventType[] } From 55ad0c0fe089b76bf99bbd15e2de9043b7211182 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 31 Aug 2025 12:03:23 -0400 Subject: [PATCH 014/477] many to many --- src/backend/src/prisma/schema.prisma | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 6c2a04a400..509a1ad7eb 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -941,12 +941,9 @@ model Event { location String? zoomLink String? availabilities Availability[] - shop Shop? @relation(fields: [shopId], references: [shopId]) - shopId String? - machineryId String? - machinery Machinery? @relation(fields: [machineryId], references: [machineryId]) - workPackageId String? - workPackage Work_Package? @relation(fields: [workPackageId], references: [workPackageId]) + shop Shop[] + machinery Machinery[] + workPackage Work_Package[] documentIds String[] description String? } From c21eae759972724c8e32c0e91c2ec1f0e050d676 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 31 Aug 2025 12:04:09 -0400 Subject: [PATCH 015/477] misused comment --- src/backend/src/prisma/schema.prisma | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 509a1ad7eb..1245ac1d1d 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -973,7 +973,6 @@ model EventType { userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") calendarId String calendar Calendar @relation(fields: [calendarId], references: [calendarId]) - // Meeting times are an integer between 0 and 11 from 10am - 10pm for the date scheduled at hour intervals meetingTimes Boolean? initialDateScheduled Boolean? allDay Boolean? From 9ac86f97436d63afe2664ed7a0352161b3b6329b Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 31 Aug 2025 12:04:59 -0400 Subject: [PATCH 016/477] many to many part 2 --- src/backend/src/prisma/schema.prisma | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 1245ac1d1d..7dae65b381 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -941,9 +941,9 @@ model Event { location String? zoomLink String? availabilities Availability[] - shop Shop[] + shops Shop[] machinery Machinery[] - workPackage Work_Package[] + workPackages Work_Package[] documentIds String[] description String? } @@ -963,16 +963,15 @@ model Calendar { } model EventType { - eventTypeId String @id @default(uuid()) + eventTypeId String @id @default(uuid()) name String - dateCreated DateTime @default(now()) + dateCreated DateTime @default(now()) dateDeleted DateTime? userCreatedId String - userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) + userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") - calendarId String - calendar Calendar @relation(fields: [calendarId], references: [calendarId]) + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") + calendars Calendar[] meetingTimes Boolean? initialDateScheduled Boolean? allDay Boolean? From 072ed811061e9ddd1f9fdd122d0c358f1814750f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 31 Aug 2025 12:05:53 -0400 Subject: [PATCH 017/477] not needed --- src/backend/src/prisma/schema.prisma | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 7dae65b381..07bdde8056 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -972,7 +972,6 @@ model EventType { userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") calendars Calendar[] - meetingTimes Boolean? initialDateScheduled Boolean? allDay Boolean? recurring Boolean? From c10a31a266a7ac57a2a58f30ef569b9a345a4b27 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 31 Aug 2025 12:16:42 -0400 Subject: [PATCH 018/477] more updates --- src/backend/src/prisma/schema.prisma | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 07bdde8056..9ffa981893 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -882,7 +882,7 @@ model Manufacturer { model Shop { shopId String @id @default(uuid()) - name String + name String @unique dateCreated DateTime @default(now()) dateDeleted DateTime? userCreatedId String @@ -908,14 +908,16 @@ model Machinery { } model ShopMachinery { + description String? shopMachineryId String @id @default(uuid()) shopId String machineryId String - quantity Int @default(0) + quantity Int @default(1) shop Shop @relation(fields: [shopId], references: [shopId]) machinery Machinery @relation(fields: [machineryId], references: [machineryId]) @@unique([shopId, machineryId], name: "uniqueShopMachinery") + @@index([machineryId]) } model Event { From 3a3a1063bea8ea1fdd2431b7e68d34b3ba8f0420 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 31 Aug 2025 13:57:07 -0400 Subject: [PATCH 019/477] new representations for scheduling --- .../migration.sql | 124 +++++++++++++++--- src/backend/src/prisma/schema.prisma | 22 +++- 2 files changed, 124 insertions(+), 22 deletions(-) rename src/backend/src/prisma/migrations/{20250831142319_calendar => 20250831175618_calendar}/migration.sql (62%) diff --git a/src/backend/src/prisma/migrations/20250831142319_calendar/migration.sql b/src/backend/src/prisma/migrations/20250831175618_calendar/migration.sql similarity index 62% rename from src/backend/src/prisma/migrations/20250831142319_calendar/migration.sql rename to src/backend/src/prisma/migrations/20250831175618_calendar/migration.sql index 71771cd04f..a428e09f47 100644 --- a/src/backend/src/prisma/migrations/20250831142319_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250831175618_calendar/migration.sql @@ -1,3 +1,6 @@ +-- CreateEnum +CREATE TYPE "public"."DayOfWeek" AS ENUM ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'); + -- AlterTable ALTER TABLE "public"."Availability" ADD COLUMN "eventId" TEXT; @@ -28,14 +31,24 @@ CREATE TABLE "public"."Machinery" ( -- CreateTable CREATE TABLE "public"."ShopMachinery" ( + "description" TEXT, "shopMachineryId" TEXT NOT NULL, "shopId" TEXT NOT NULL, "machineryId" TEXT NOT NULL, - "quantity" INTEGER NOT NULL DEFAULT 0, + "quantity" INTEGER NOT NULL DEFAULT 1, CONSTRAINT "ShopMachinery_pkey" PRIMARY KEY ("shopMachineryId") ); +-- CreateTable +CREATE TABLE "public"."ScheduleSlot" ( + "id" TEXT NOT NULL, + "day" "public"."DayOfWeek" NOT NULL, + "time" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "ScheduleSlot_pkey" PRIMARY KEY ("id") +); + -- CreateTable CREATE TABLE "public"."Event" ( "eventId" TEXT NOT NULL, @@ -47,15 +60,11 @@ CREATE TABLE "public"."Event" ( "eventTypeId" TEXT NOT NULL, "approved" BOOLEAN, "approvedByUserId" TEXT, - "meetingTimes" INTEGER[], "initialDateScheduled" DATE NOT NULL, "allDay" BOOLEAN NOT NULL DEFAULT false, - "recurringInterval" INTEGER NOT NULL, + "recurrenceNumber" INTEGER NOT NULL, "location" TEXT, "zoomLink" TEXT, - "shopId" TEXT, - "machineryId" TEXT, - "workPackageId" TEXT, "documentIds" TEXT[], "description" TEXT, @@ -84,8 +93,6 @@ CREATE TABLE "public"."EventType" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, - "calendarId" TEXT NOT NULL, - "meetingTimes" BOOLEAN, "initialDateScheduled" BOOLEAN, "allDay" BOOLEAN, "recurring" BOOLEAN, @@ -102,6 +109,14 @@ CREATE TABLE "public"."EventType" ( CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") ); +-- CreateTable +CREATE TABLE "public"."_EventToScheduleSlot" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToScheduleSlot_AB_pkey" PRIMARY KEY ("A","B") +); + -- CreateTable CREATE TABLE "public"."_eventAttender" ( "A" TEXT NOT NULL, @@ -110,12 +125,65 @@ CREATE TABLE "public"."_eventAttender" ( CONSTRAINT "_eventAttender_AB_pkey" PRIMARY KEY ("A","B") ); +-- CreateTable +CREATE TABLE "public"."_EventToShop" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToShop_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_EventToMachinery" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToMachinery_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_EventToWork_Package" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToWork_Package_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_CalendarToEventType" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_CalendarToEventType_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Shop_name_key" ON "public"."Shop"("name"); + +-- CreateIndex +CREATE INDEX "ShopMachinery_machineryId_idx" ON "public"."ShopMachinery"("machineryId"); + -- CreateIndex CREATE UNIQUE INDEX "ShopMachinery_shopId_machineryId_key" ON "public"."ShopMachinery"("shopId", "machineryId"); +-- CreateIndex +CREATE INDEX "_EventToScheduleSlot_B_index" ON "public"."_EventToScheduleSlot"("B"); + -- CreateIndex CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); +-- CreateIndex +CREATE INDEX "_EventToShop_B_index" ON "public"."_EventToShop"("B"); + +-- CreateIndex +CREATE INDEX "_EventToMachinery_B_index" ON "public"."_EventToMachinery"("B"); + +-- CreateIndex +CREATE INDEX "_EventToWork_Package_B_index" ON "public"."_EventToWork_Package"("B"); + +-- CreateIndex +CREATE INDEX "_CalendarToEventType_B_index" ON "public"."_CalendarToEventType"("B"); + -- AddForeignKey ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; @@ -146,15 +214,6 @@ ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY -- AddForeignKey ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_approvedByUserId_fkey" FOREIGN KEY ("approvedByUserId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("shopId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("machineryId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_workPackageId_fkey" FOREIGN KEY ("workPackageId") REFERENCES "public"."Work_Package"("workPackageId") ON DELETE SET NULL ON UPDATE CASCADE; - -- AddForeignKey ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; @@ -168,13 +227,40 @@ ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userCreatedId_fkey" F ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_calendarId_fkey" FOREIGN KEY ("calendarId") REFERENCES "public"."Calendar"("calendarId") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; +ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."ScheduleSlot"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToShop" ADD CONSTRAINT "_EventToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToShop" ADD CONSTRAINT "_EventToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Work_Package"("workPackageId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_CalendarToEventType" ADD CONSTRAINT "_CalendarToEventType_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Calendar"("calendarId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_CalendarToEventType" ADD CONSTRAINT "_CalendarToEventType_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."EventType"("eventTypeId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 9ffa981893..ab0c73137b 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -920,6 +920,23 @@ model ShopMachinery { @@index([machineryId]) } +enum DayOfWeek { + MONDAY + TUESDAY + WEDNESDAY + THURSDAY + FRIDAY + SATURDAY + SUNDAY +} + +model ScheduleSlot { + id String @id @default(uuid()) + day DayOfWeek + time DateTime // time of day (just use a DateTime, ignore the date portion) + ScheduledEvents Event[] +} + model Event { eventId String @id @default(uuid()) dateCreated DateTime @default(now()) @@ -934,11 +951,10 @@ model Event { approved Boolean? approvedByUserId String? approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") - // Meeting times are an integer between 0 and 11 from 10am - 10pm for the date scheduled at hour intervals - meetingTimes Int[] initialDateScheduled DateTime @db.Date allDay Boolean @default(false) - recurringInterval Int // the number of days between each meeting (0 = no recurring) + recurringInterval ScheduleSlot[] + recurrenceNumber Int members User[] @relation(name: "eventAttender") location String? zoomLink String? From f1ca71743aa99e5e739b06823478fe65d86826fe Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 2 Sep 2025 10:27:04 -0400 Subject: [PATCH 020/477] schedule refactor --- src/backend/src/prisma/schema.prisma | 61 ++++++++++++++-------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index ab0c73137b..d9596e1471 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -931,39 +931,40 @@ enum DayOfWeek { } model ScheduleSlot { - id String @id @default(uuid()) - day DayOfWeek - time DateTime // time of day (just use a DateTime, ignore the date portion) - ScheduledEvents Event[] + id String @id @default(uuid()) + day DayOfWeek + startTime DateTime // time of day (just use a DateTime, ignore the date portion) + endTime DateTime // time of day (just use a DateTime, ignore the date portion) + recurrenceNumber Int + initialDateScheduled DateTime @db.Date + allDay Boolean @default(false) + ScheduledEvents Event[] } model Event { - eventId String @id @default(uuid()) - dateCreated DateTime @default(now()) - dateDeleted DateTime? - title String - userCreatedId String - userCreated User @relation(name: "eventCreator", fields: [userCreatedId], references: [userId]) - userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventDeleter") - eventTypeId String - eventType EventType @relation(fields: [eventTypeId], references: [eventTypeId]) - approved Boolean? - approvedByUserId String? - approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") - initialDateScheduled DateTime @db.Date - allDay Boolean @default(false) - recurringInterval ScheduleSlot[] - recurrenceNumber Int - members User[] @relation(name: "eventAttender") - location String? - zoomLink String? - availabilities Availability[] - shops Shop[] - machinery Machinery[] - workPackages Work_Package[] - documentIds String[] - description String? + eventId String @id @default(uuid()) + dateCreated DateTime @default(now()) + dateDeleted DateTime? + title String + userCreatedId String + userCreated User @relation(name: "eventCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventDeleter") + eventTypeId String + eventType EventType @relation(fields: [eventTypeId], references: [eventTypeId]) + approved Boolean? + approvedByUserId String? + approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") + scheduledTimes ScheduleSlot[] + members User[] @relation(name: "eventAttender") + location String? + zoomLink String? + availabilities Availability[] + shops Shop[] + machinery Machinery[] + workPackages Work_Package[] + documentIds String[] + description String? } model Calendar { From 86d205cd4a277bf5c5fdbffa4642196164cb77c7 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 3 Sep 2025 20:29:47 -0400 Subject: [PATCH 021/477] update --- .../migration.sql | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) rename src/backend/src/prisma/migrations/{20250831175618_calendar => 20250904002941_calendar}/migration.sql (99%) diff --git a/src/backend/src/prisma/migrations/20250831175618_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904002941_calendar/migration.sql similarity index 99% rename from src/backend/src/prisma/migrations/20250831175618_calendar/migration.sql rename to src/backend/src/prisma/migrations/20250904002941_calendar/migration.sql index a428e09f47..51a1775352 100644 --- a/src/backend/src/prisma/migrations/20250831175618_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904002941_calendar/migration.sql @@ -44,7 +44,11 @@ CREATE TABLE "public"."ShopMachinery" ( CREATE TABLE "public"."ScheduleSlot" ( "id" TEXT NOT NULL, "day" "public"."DayOfWeek" NOT NULL, - "time" TIMESTAMP(3) NOT NULL, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, + "recurrenceNumber" INTEGER NOT NULL, + "initialDateScheduled" DATE NOT NULL, + "allDay" BOOLEAN NOT NULL DEFAULT false, CONSTRAINT "ScheduleSlot_pkey" PRIMARY KEY ("id") ); @@ -60,9 +64,6 @@ CREATE TABLE "public"."Event" ( "eventTypeId" TEXT NOT NULL, "approved" BOOLEAN, "approvedByUserId" TEXT, - "initialDateScheduled" DATE NOT NULL, - "allDay" BOOLEAN NOT NULL DEFAULT false, - "recurrenceNumber" INTEGER NOT NULL, "location" TEXT, "zoomLink" TEXT, "documentIds" TEXT[], From d1738b42b7686acc98177e419fe31bc5e4d392f8 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 4 Sep 2025 17:39:49 -0400 Subject: [PATCH 022/477] small fixes --- src/backend/src/prisma/schema.prisma | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index d9596e1471..8f3cb5c732 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -931,13 +931,13 @@ enum DayOfWeek { } model ScheduleSlot { - id String @id @default(uuid()) - day DayOfWeek - startTime DateTime // time of day (just use a DateTime, ignore the date portion) - endTime DateTime // time of day (just use a DateTime, ignore the date portion) + id String @id @default(uuid()) + days DayOfWeek[] + startTime DateTime? // time of day (just use a DateTime, ignore the date portion) + endTime DateTime? // time of day (just use a DateTime, ignore the date portion) recurrenceNumber Int - initialDateScheduled DateTime @db.Date - allDay Boolean @default(false) + initialDateScheduled DateTime @db.Date + allDay Boolean @default(false) ScheduledEvents Event[] } From ebe2f55eb6dc9101d05d361619d1f991c140fda8 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 4 Sep 2025 17:43:24 -0400 Subject: [PATCH 023/477] migration --- .../migration.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/backend/src/prisma/migrations/{20250904002941_calendar => 20250904214316_calendar}/migration.sql (98%) diff --git a/src/backend/src/prisma/migrations/20250904002941_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql similarity index 98% rename from src/backend/src/prisma/migrations/20250904002941_calendar/migration.sql rename to src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index 51a1775352..9c6c8f6c37 100644 --- a/src/backend/src/prisma/migrations/20250904002941_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -43,9 +43,9 @@ CREATE TABLE "public"."ShopMachinery" ( -- CreateTable CREATE TABLE "public"."ScheduleSlot" ( "id" TEXT NOT NULL, - "day" "public"."DayOfWeek" NOT NULL, - "startTime" TIMESTAMP(3) NOT NULL, - "endTime" TIMESTAMP(3) NOT NULL, + "days" "public"."DayOfWeek"[], + "startTime" TIMESTAMP(3), + "endTime" TIMESTAMP(3), "recurrenceNumber" INTEGER NOT NULL, "initialDateScheduled" DATE NOT NULL, "allDay" BOOLEAN NOT NULL DEFAULT false, From 431e73f395c24dad1951f44c7a49593d14abd77d Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 9 Sep 2025 19:16:10 -0400 Subject: [PATCH 024/477] shared types --- src/shared/src/types/calendar-types.ts | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/shared/src/types/calendar-types.ts diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts new file mode 100644 index 0000000000..763c0cd1bf --- /dev/null +++ b/src/shared/src/types/calendar-types.ts @@ -0,0 +1,64 @@ +import { WorkPackage } from './project-types'; +import { Availability, User } from './user-types'; + +export interface Calendar { + name: string; + description: string; + color: string; +} + +export enum DayOfWeek { + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY, + SUNDAY +} + +export interface ScheduleSlot { + days: DayOfWeek[]; + startTime?: Date; + endTime?: Date; + recurrenceNumber: number; + initialDateScheduled: Date; + allDay: Boolean; +} + +export interface EventType { + name: string; + events: Event[]; +} + +export interface Shop { + name: string; + description: string; +} + +export interface ShopMachinery { + shop: Shop; + quantity: number; + description?: string; +} + +export interface Machinery { + name: string; + shops: ShopMachinery[]; +} + +export interface Event { + name: string; + approved: boolean; + approvedBy?: User; + scheduledTimes?: ScheduleSlot[]; + people?: User[]; + location?: string; + zoomLink?: string; + availability?: Availability[]; + shop?: Shop[]; + machinery?: Machinery[]; + workPackage?: WorkPackage[]; + documentIds?: string[]; + description?: string; +} From 46f3fb1440a68d1dee202657edc8a71b0545f240 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Fri, 12 Sep 2025 19:37:36 -0400 Subject: [PATCH 025/477] #3565 setup the endpoint for createMachinery --- .../src/controllers/machinery.controllers.ts | 15 +++++ src/backend/src/prisma/seed.ts | 29 +++++++++ src/backend/src/routes/machinery.routes.ts | 17 +++++ .../src/services/machinery.services.ts | 49 +++++++++++++++ src/backend/tests/test-utils.ts | 3 + src/backend/tests/unit/machinery.test.ts | 62 +++++++++++++++++++ 6 files changed, 175 insertions(+) create mode 100644 src/backend/src/controllers/machinery.controllers.ts create mode 100644 src/backend/src/routes/machinery.routes.ts create mode 100644 src/backend/src/services/machinery.services.ts create mode 100644 src/backend/tests/unit/machinery.test.ts diff --git a/src/backend/src/controllers/machinery.controllers.ts b/src/backend/src/controllers/machinery.controllers.ts new file mode 100644 index 0000000000..4aa1c35c34 --- /dev/null +++ b/src/backend/src/controllers/machinery.controllers.ts @@ -0,0 +1,15 @@ +import { NextFunction, Request, Response } from 'express'; +import MachineryService from '../services/machinery.services'; + +export default class MachineryController { + static async createMachinery(req: Request, res: Response, next: NextFunction) { + try { + const { name, shopId, quantity } = req.body; + + const machinery = await MachineryService.createMachinery(req.currentUser, name, shopId, quantity, req.organization); + res.status(200).json(machinery); + } catch (error: unknown) { + next(error); + } + } +} diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index a002745e4a..5273b48aca 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -50,6 +50,7 @@ import AnnouncementService from '../services/announcement.services'; import OnboardingServices from '../services/onboarding.services'; import { dbSeedAllParts, dbSeedAllPartTags } from './seed-data/parts.seed'; import FinanceServices from '../services/finance.services'; +import MachineryService from '../services/machinery.services'; const prisma = new PrismaClient(); @@ -3059,6 +3060,34 @@ const performSeed: () => Promise = async () => { new Date(7, 5, 25), thomasEmrax.userId ); + + // Create temporary shops (placeholder until we have createShop service) + const machineShop = await prisma.shop.create({ + data: { + name: 'Precision Manufacturing Lab', + description: 'CNC machining and precision manufacturing facility', + userCreatedId: thomasEmrax.userId + } + }); + + const electronicsShop = await prisma.shop.create({ + data: { + name: 'Electronics Design Center', + description: 'Electronics testing and circuit design lab', + userCreatedId: thomasEmrax.userId + } + }); + + // Create machineries and assign to machineShop + await MachineryService.createMachinery(thomasEmrax, 'Iron Man Mark 42 CNC Mill', machineShop.shopId, 2, ner); + await MachineryService.createMachinery(thomasEmrax, 'Captain America Shield Press', machineShop.shopId, 1, ner); + await MachineryService.createMachinery(thomasEmrax, 'Thor Hammer Forge', machineShop.shopId, 1, ner); + + //Create machineries and assign to electronicsShop + await MachineryService.createMachinery(thomasEmrax, 'Arc Reactor Oscilloscope', electronicsShop.shopId, 4, ner); + await MachineryService.createMachinery(thomasEmrax, 'Vibranium Power Supply', electronicsShop.shopId, 6, ner); + await MachineryService.createMachinery(thomasEmrax, 'Stark Industries Multimeter', electronicsShop.shopId, 2, ner); + await MachineryService.createMachinery(thomasEmrax, 'Wakanda Tech Oscilloscope', electronicsShop.shopId, 3, ner); }; performSeed() diff --git a/src/backend/src/routes/machinery.routes.ts b/src/backend/src/routes/machinery.routes.ts new file mode 100644 index 0000000000..252c706377 --- /dev/null +++ b/src/backend/src/routes/machinery.routes.ts @@ -0,0 +1,17 @@ +import express from 'express'; +import { body } from 'express-validator'; +import { nonEmptyString, intMinZero, validateInputs } from '../utils/validation.utils'; +import MachineryController from '../controllers/machinery.controllers'; + +const machineryRouter = express.Router(); + +machineryRouter.post( + '/machinery/create', + nonEmptyString(body('name')), + nonEmptyString(body('shopId')), + intMinZero(body('quantity')), + validateInputs, + MachineryController.createMachinery +); + +export default machineryRouter; diff --git a/src/backend/src/services/machinery.services.ts b/src/backend/src/services/machinery.services.ts new file mode 100644 index 0000000000..e4afe8fefd --- /dev/null +++ b/src/backend/src/services/machinery.services.ts @@ -0,0 +1,49 @@ +import { Organization, User } from '@prisma/client'; +import { isAdmin } from 'shared'; +import prisma from '../prisma/prisma'; +import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; +import { userHasPermission } from '../utils/users.utils'; + +export default class MachineryService { + /** + * Creates a new machinery and associates it with a shop. + * + * @param submitter The user submitting the request, who must be an admin. + * @param name The name of the machinery. + * @param shopId The ID of the shop to associate the machinery with. + * @param quantity The quantity of machinery to add to the shop. + * @param organization The organization for which the machinery is being created. + * + * @returns The created machinery object with associated shop machinery. + * + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + */ + static async createMachinery(submitter: User, name: string, shopId: string, quantity: number, organization: Organization) { + // Check if user is admin + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('create machinery'); + } + + const newMachinery = await prisma.machinery.create({ + data: { + name, + userCreatedId: submitter.userId, + shops: { + create: { + shopId, + quantity + } + } + }, + include: { + shops: { + include: { + shop: true + } + } + } + }); + + return newMachinery; + } +} diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index 68e35ff3db..93be4fc79b 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -166,6 +166,9 @@ export const resetUsers = async () => { await prisma.account_Code.deleteMany(); await prisma.refund_Source.deleteMany(); await prisma.index_Code.deleteMany(); + await prisma.shopMachinery.deleteMany(); + await prisma.machinery.deleteMany(); + await prisma.shop.deleteMany(); await prisma.organization.deleteMany(); await prisma.user.deleteMany(); }; diff --git a/src/backend/tests/unit/machinery.test.ts b/src/backend/tests/unit/machinery.test.ts new file mode 100644 index 0000000000..7e6821fbe9 --- /dev/null +++ b/src/backend/tests/unit/machinery.test.ts @@ -0,0 +1,62 @@ +import { Organization } from '@prisma/client'; +import MachineryService from '../../src/services/machinery.services'; +import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; +import { batmanAppAdmin, wonderwomanGuest, supermanAdmin } from '../test-data/users.test-data'; +import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; +import prisma from '../../src/prisma/prisma'; + +describe('Machinery Tests', () => { + let orgId: string; + let organization: Organization; + let shopId: string; + + beforeEach(async () => { + organization = await createTestOrganization(); + orgId = organization.organizationId; + + // Create a test shop for shopId, assuming prisma create shop works + const shopName = 'Precision Manufacturing Lab'; + const shop = await prisma.shop.create({ + data: { + name: shopName, + description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', + userCreatedId: (await createTestUser(batmanAppAdmin, orgId)).userId + } + }); + ({ shopId } = shop); + }); + + afterEach(async () => { + await resetUsers(); + }); + + describe('Create machinery', () => { + it('Fails if user is not an admin', async () => { + await expect( + async () => + await MachineryService.createMachinery( + await createTestUser(wonderwomanGuest, orgId), + 'Captain America Shield Press', + shopId, + 1, + organization + ) + ).rejects.toThrow(new AccessDeniedAdminOnlyException('create machinery')); + }); + + it('Succeeds and creates machinery', async () => { + const result = await MachineryService.createMachinery( + await createTestUser(supermanAdmin, orgId), + 'Iron Man Mark 42 CNC Mill', + shopId, + 2, + organization + ); + + expect(result.name).toEqual('Iron Man Mark 42 CNC Mill'); + expect(result.shops).toHaveLength(1); + expect(result.shops[0].quantity).toBe(2); + expect(result.shops[0].shopId).toBe(shopId); + }); + }); +}); From 5ca1868239adff1f8e19c0f447a825afb66637f8 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 14 Sep 2025 14:55:24 -0400 Subject: [PATCH 026/477] #3565 Added ShopMachinery model to the Machinery model when creating and other testing tweaks --- src/backend/index.ts | 2 ++ src/backend/src/prisma/seed.ts | 25 +++---------------- src/backend/src/routes/machinery.routes.ts | 6 ++--- .../src/services/machinery.services.ts | 16 ++++++------ src/backend/tests/unit/machinery.test.ts | 2 ++ 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/backend/index.ts b/src/backend/index.ts index ffe251ec65..27e4ecb5b4 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -25,6 +25,7 @@ import statisticsRouter from './src/routes/statistics.routes'; import retrospectiveRouter from './src/routes/retrospective.routes'; import partsRouter from './src/routes/parts.routes'; import financeRouter from './src/routes/finance.routes'; +import machineryRouter from './src/routes/machinery.routes'; const app = express(); @@ -87,6 +88,7 @@ app.use('/statistics', statisticsRouter); app.use('/retrospective', retrospectiveRouter); app.use('/parts', partsRouter); app.use('/finance', financeRouter); +app.use('/machinery', machineryRouter); app.use('/', (_req, res) => { res.status(200).json('Welcome to FinishLine'); }); diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 5273b48aca..9cd170f181 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3061,33 +3061,16 @@ const performSeed: () => Promise = async () => { thomasEmrax.userId ); - // Create temporary shops (placeholder until we have createShop service) - const machineShop = await prisma.shop.create({ + // Create machineries and assign to shops + const advancedShop = await prisma.shop.create({ data: { - name: 'Precision Manufacturing Lab', + name: 'Advanced CNC Manufacturing Center', description: 'CNC machining and precision manufacturing facility', userCreatedId: thomasEmrax.userId } }); - const electronicsShop = await prisma.shop.create({ - data: { - name: 'Electronics Design Center', - description: 'Electronics testing and circuit design lab', - userCreatedId: thomasEmrax.userId - } - }); - - // Create machineries and assign to machineShop - await MachineryService.createMachinery(thomasEmrax, 'Iron Man Mark 42 CNC Mill', machineShop.shopId, 2, ner); - await MachineryService.createMachinery(thomasEmrax, 'Captain America Shield Press', machineShop.shopId, 1, ner); - await MachineryService.createMachinery(thomasEmrax, 'Thor Hammer Forge', machineShop.shopId, 1, ner); - - //Create machineries and assign to electronicsShop - await MachineryService.createMachinery(thomasEmrax, 'Arc Reactor Oscilloscope', electronicsShop.shopId, 4, ner); - await MachineryService.createMachinery(thomasEmrax, 'Vibranium Power Supply', electronicsShop.shopId, 6, ner); - await MachineryService.createMachinery(thomasEmrax, 'Stark Industries Multimeter', electronicsShop.shopId, 2, ner); - await MachineryService.createMachinery(thomasEmrax, 'Wakanda Tech Oscilloscope', electronicsShop.shopId, 3, ner); + await MachineryService.createMachinery(thomasEmrax, 'Iron Man Mark 42 CNC Mill', advancedShop.shopId, 1, ner); }; performSeed() diff --git a/src/backend/src/routes/machinery.routes.ts b/src/backend/src/routes/machinery.routes.ts index 252c706377..2f82f20765 100644 --- a/src/backend/src/routes/machinery.routes.ts +++ b/src/backend/src/routes/machinery.routes.ts @@ -1,15 +1,15 @@ import express from 'express'; import { body } from 'express-validator'; -import { nonEmptyString, intMinZero, validateInputs } from '../utils/validation.utils'; +import { nonEmptyString, validateInputs } from '../utils/validation.utils'; import MachineryController from '../controllers/machinery.controllers'; const machineryRouter = express.Router(); machineryRouter.post( - '/machinery/create', + '/create', nonEmptyString(body('name')), nonEmptyString(body('shopId')), - intMinZero(body('quantity')), + body('quantity').isInt({ min: 1 }), validateInputs, MachineryController.createMachinery ); diff --git a/src/backend/src/services/machinery.services.ts b/src/backend/src/services/machinery.services.ts index e4afe8fefd..8774f303ee 100644 --- a/src/backend/src/services/machinery.services.ts +++ b/src/backend/src/services/machinery.services.ts @@ -6,12 +6,11 @@ import { userHasPermission } from '../utils/users.utils'; export default class MachineryService { /** - * Creates a new machinery and associates it with a shop. + * Creates a new machinery and associates it with shops. * * @param submitter The user submitting the request, who must be an admin. * @param name The name of the machinery. - * @param shopId The ID of the shop to associate the machinery with. - * @param quantity The quantity of machinery to add to the shop. + * @param shopMachineryData Array of shop machinery data containing shopId, quantity, and optional description. * @param organization The organization for which the machinery is being created. * * @returns The created machinery object with associated shop machinery. @@ -29,10 +28,13 @@ export default class MachineryService { name, userCreatedId: submitter.userId, shops: { - create: { - shopId, - quantity - } + create: [ + { + shopId, + quantity, + description: null + } + ] } }, include: { diff --git a/src/backend/tests/unit/machinery.test.ts b/src/backend/tests/unit/machinery.test.ts index 7e6821fbe9..4dd3a2b19c 100644 --- a/src/backend/tests/unit/machinery.test.ts +++ b/src/backend/tests/unit/machinery.test.ts @@ -57,6 +57,8 @@ describe('Machinery Tests', () => { expect(result.shops).toHaveLength(1); expect(result.shops[0].quantity).toBe(2); expect(result.shops[0].shopId).toBe(shopId); + expect(result.shops[0].description).toBe('Main production unit'); }); }); }); +//16d5afbe-95f0-4214-8a31-100e5e7e408d From 2a6f6e2f2e224d9eb5c32e8d123b75c31807c10f Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 14 Sep 2025 15:03:26 -0400 Subject: [PATCH 027/477] #3565 adjusted description input and tests --- src/backend/src/services/machinery.services.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backend/src/services/machinery.services.ts b/src/backend/src/services/machinery.services.ts index 8774f303ee..e8a49c2269 100644 --- a/src/backend/src/services/machinery.services.ts +++ b/src/backend/src/services/machinery.services.ts @@ -12,12 +12,20 @@ export default class MachineryService { * @param name The name of the machinery. * @param shopMachineryData Array of shop machinery data containing shopId, quantity, and optional description. * @param organization The organization for which the machinery is being created. + * @param description The description of the machinery (optional). * * @returns The created machinery object with associated shop machinery. * * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. */ - static async createMachinery(submitter: User, name: string, shopId: string, quantity: number, organization: Organization) { + static async createMachinery( + submitter: User, + name: string, + shopId: string, + quantity: number, + organization: Organization, + description?: string + ) { // Check if user is admin if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create machinery'); @@ -32,7 +40,7 @@ export default class MachineryService { { shopId, quantity, - description: null + description } ] } From 61fe748336075be0beab5f9adef158136bf4cb0b Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 14 Sep 2025 15:07:02 -0400 Subject: [PATCH 028/477] #3565 fix test hopefully --- src/backend/tests/unit/machinery.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/tests/unit/machinery.test.ts b/src/backend/tests/unit/machinery.test.ts index 4dd3a2b19c..acf0a2051d 100644 --- a/src/backend/tests/unit/machinery.test.ts +++ b/src/backend/tests/unit/machinery.test.ts @@ -57,7 +57,7 @@ describe('Machinery Tests', () => { expect(result.shops).toHaveLength(1); expect(result.shops[0].quantity).toBe(2); expect(result.shops[0].shopId).toBe(shopId); - expect(result.shops[0].description).toBe('Main production unit'); + expect(result.shops[0].description).toBe(''); }); }); }); From 130641b58b96f6a96cf2781e4d899fd3838dc30b Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 14 Sep 2025 15:10:28 -0400 Subject: [PATCH 029/477] #3565 fix test final --- src/backend/tests/unit/machinery.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/tests/unit/machinery.test.ts b/src/backend/tests/unit/machinery.test.ts index acf0a2051d..2948fcdca2 100644 --- a/src/backend/tests/unit/machinery.test.ts +++ b/src/backend/tests/unit/machinery.test.ts @@ -57,7 +57,7 @@ describe('Machinery Tests', () => { expect(result.shops).toHaveLength(1); expect(result.shops[0].quantity).toBe(2); expect(result.shops[0].shopId).toBe(shopId); - expect(result.shops[0].description).toBe(''); + expect(result.shops[0].description).toBe(null); }); }); }); From 91457335c2c0cca6bae228d299e2eb2ade036970 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 15 Sep 2025 08:42:00 -0400 Subject: [PATCH 030/477] #3565 updated the general path to calender routes for all related calendar endpoints --- src/backend/index.ts | 4 ++-- .../routes/{machinery.routes.ts => calendar.routes.ts} | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/backend/src/routes/{machinery.routes.ts => calendar.routes.ts} (76%) diff --git a/src/backend/index.ts b/src/backend/index.ts index 27e4ecb5b4..f958e82b98 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -25,7 +25,7 @@ import statisticsRouter from './src/routes/statistics.routes'; import retrospectiveRouter from './src/routes/retrospective.routes'; import partsRouter from './src/routes/parts.routes'; import financeRouter from './src/routes/finance.routes'; -import machineryRouter from './src/routes/machinery.routes'; +import calendarRouter from './src/routes/calendar.routes'; const app = express(); @@ -88,7 +88,7 @@ app.use('/statistics', statisticsRouter); app.use('/retrospective', retrospectiveRouter); app.use('/parts', partsRouter); app.use('/finance', financeRouter); -app.use('/machinery', machineryRouter); +app.use('/calendar', calendarRouter); app.use('/', (_req, res) => { res.status(200).json('Welcome to FinishLine'); }); diff --git a/src/backend/src/routes/machinery.routes.ts b/src/backend/src/routes/calendar.routes.ts similarity index 76% rename from src/backend/src/routes/machinery.routes.ts rename to src/backend/src/routes/calendar.routes.ts index 2f82f20765..d233b0efea 100644 --- a/src/backend/src/routes/machinery.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -3,10 +3,10 @@ import { body } from 'express-validator'; import { nonEmptyString, validateInputs } from '../utils/validation.utils'; import MachineryController from '../controllers/machinery.controllers'; -const machineryRouter = express.Router(); +const calendarRouter = express.Router(); -machineryRouter.post( - '/create', +calendarRouter.post( + '/machinery/create', nonEmptyString(body('name')), nonEmptyString(body('shopId')), body('quantity').isInt({ min: 1 }), @@ -14,4 +14,4 @@ machineryRouter.post( MachineryController.createMachinery ); -export default machineryRouter; +export default calendarRouter; From a18c13236f82610421a625e346235ad664dbae28 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Sep 2025 11:14:32 -0400 Subject: [PATCH 031/477] shared type update --- src/shared/src/types/calendar-types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 763c0cd1bf..6975485267 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -28,7 +28,6 @@ export interface ScheduleSlot { export interface EventType { name: string; - events: Event[]; } export interface Shop { @@ -50,6 +49,7 @@ export interface Machinery { export interface Event { name: string; approved: boolean; + eventTypeId: string; approvedBy?: User; scheduledTimes?: ScheduleSlot[]; people?: User[]; From ddce5b9fa698716165bd29e3536622916fc6ac95 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Sep 2025 11:30:17 -0400 Subject: [PATCH 032/477] update 2 --- src/shared/src/types/calendar-types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 6975485267..b13ee3b234 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -28,6 +28,7 @@ export interface ScheduleSlot { export interface EventType { name: string; + calendarId: string; } export interface Shop { From d197d658b9ec4a927ad45fd85cf5e3433ab2699e Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Sep 2025 11:35:37 -0400 Subject: [PATCH 033/477] update 3 --- src/shared/src/types/calendar-types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index b13ee3b234..4ca68ccfc9 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -5,6 +5,7 @@ export interface Calendar { name: string; description: string; color: string; + eventTypes: EventType[]; } export enum DayOfWeek { @@ -28,7 +29,6 @@ export interface ScheduleSlot { export interface EventType { name: string; - calendarId: string; } export interface Shop { From f4ae6a7f66a658e65c5f4fb1657f6fd2ecf52410 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 15 Sep 2025 12:35:40 -0400 Subject: [PATCH 034/477] end point finished --- src/backend/index.ts | 2 + .../src/controllers/shop.controllers.ts | 18 + src/backend/src/prisma/seed.ts | 19 + src/backend/src/routes/shop.routes.ts | 15 + src/backend/src/services/shop.services.ts | 29 + src/backend/tests/test-utils.ts | 4 + src/backend/tests/unit/shop.test.ts | 50 + yarn.lock | 2272 ++++++++++++----- 8 files changed, 1792 insertions(+), 617 deletions(-) create mode 100644 src/backend/src/controllers/shop.controllers.ts create mode 100644 src/backend/src/routes/shop.routes.ts create mode 100644 src/backend/src/services/shop.services.ts create mode 100644 src/backend/tests/unit/shop.test.ts diff --git a/src/backend/index.ts b/src/backend/index.ts index ffe251ec65..10b4e921ff 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -25,6 +25,7 @@ import statisticsRouter from './src/routes/statistics.routes'; import retrospectiveRouter from './src/routes/retrospective.routes'; import partsRouter from './src/routes/parts.routes'; import financeRouter from './src/routes/finance.routes'; +import shopRouter from './src/routes/shop.routes'; const app = express(); @@ -87,6 +88,7 @@ app.use('/statistics', statisticsRouter); app.use('/retrospective', retrospectiveRouter); app.use('/parts', partsRouter); app.use('/finance', financeRouter); +app.use('/shops', shopRouter); app.use('/', (_req, res) => { res.status(200).json('Welcome to FinishLine'); }); diff --git a/src/backend/src/controllers/shop.controllers.ts b/src/backend/src/controllers/shop.controllers.ts new file mode 100644 index 0000000000..08abff0f1d --- /dev/null +++ b/src/backend/src/controllers/shop.controllers.ts @@ -0,0 +1,18 @@ +import { NextFunction, Request, Response } from 'express'; +import ShopService from '../services/shop.services'; + +export default class ShopController { + static async createShop(req: Request, res: Response, next: NextFunction) { + try{ + const {name, description} = req.body; + const shop = await ShopService.createShop( + (req as any).currentUser, + name, + description, + (req as any).organization); + res.status(201).json(shop); + } catch(error) { + next(error); + } + } +} \ No newline at end of file diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index a002745e4a..c36d512b6b 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -50,6 +50,7 @@ import AnnouncementService from '../services/announcement.services'; import OnboardingServices from '../services/onboarding.services'; import { dbSeedAllParts, dbSeedAllPartTags } from './seed-data/parts.seed'; import FinanceServices from '../services/finance.services'; +import ShopServices from '../services/shop.services'; const prisma = new PrismaClient(); @@ -3059,8 +3060,25 @@ const performSeed: () => Promise = async () => { new Date(7, 5, 25), thomasEmrax.userId ); + + await ShopServices.createShop( + thomasEmrax, + 'Precision Manufacturing Lab', + 'CNC machining and precision manufacturing facility', + ner + ); + + await ShopServices.createShop( + thomasEmrax, + 'Electronics Design Center', + 'Electronics testing and circuit design lab', + ner + ); + }; + + performSeed() .catch((e) => { console.error(e); @@ -3069,3 +3087,4 @@ performSeed() .finally(async () => { await prisma.$disconnect(); }); + diff --git a/src/backend/src/routes/shop.routes.ts b/src/backend/src/routes/shop.routes.ts new file mode 100644 index 0000000000..ae70de6c97 --- /dev/null +++ b/src/backend/src/routes/shop.routes.ts @@ -0,0 +1,15 @@ +import express from 'express'; +import { body } from 'express-validator'; +import { nonEmptyString, validateInputs } from '../utils/validation.utils'; +import ShopController from '../controllers/shop.controllers'; + +const shopRouter = express.Router(); +shopRouter.post( + '/shop/create', + nonEmptyString(body('name')), + nonEmptyString(body('description')), + validateInputs, + ShopController.createShop +); + +export default shopRouter; diff --git a/src/backend/src/services/shop.services.ts b/src/backend/src/services/shop.services.ts new file mode 100644 index 0000000000..f8e3f38628 --- /dev/null +++ b/src/backend/src/services/shop.services.ts @@ -0,0 +1,29 @@ +import { Organization, User } from '@prisma/client'; +import { isAdmin } from 'shared'; +import prisma from '../prisma/prisma'; +import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; +import { userHasPermission } from '../utils/users.utils'; + +export default class ShopServices { + /** + * Creates a new shop + * requires the submiter to be Admin + */ + static async createShop(submitter: User, name: string, description: string, organization: Organization) { + const permission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); + if (!permission) throw new AccessDeniedAdminOnlyException('Only admins can create a shop'); + + const shop = await prisma.shop.create({ + data: { + name, + description, + userCreatedId: submitter.userId, + + }, + }); + return shop; + + + + } +} \ No newline at end of file diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index 68e35ff3db..ef59ede25d 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -168,6 +168,10 @@ export const resetUsers = async () => { await prisma.index_Code.deleteMany(); await prisma.organization.deleteMany(); await prisma.user.deleteMany(); + await prisma.shopMachinery.deleteMany(); + await prisma.machinery.deleteMany(); + await prisma.shop.deleteMany(); + }; export const createFinanceTeamAndLead = async (organization?: Organization) => { diff --git a/src/backend/tests/unit/shop.test.ts b/src/backend/tests/unit/shop.test.ts new file mode 100644 index 0000000000..ac13f7c4ff --- /dev/null +++ b/src/backend/tests/unit/shop.test.ts @@ -0,0 +1,50 @@ +import { Organization } from '@prisma/client'; +import ShopServices from '../../src/services/shop.services'; +import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; +import { batmanAppAdmin, wonderwomanGuest, supermanAdmin } from '../test-data/users.test-data'; +import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; + +describe('Shop Tests', () => { + let organization: Organization; + let orgId: string; + + beforeEach(async () => { + organization = await createTestOrganization(); + orgId = organization.organizationId; + }); + + afterEach(async () => { + await resetUsers(); + }); + + describe('create shop', () => { + it('fails if user is not an admin', async () => { + await expect( + ShopServices.createShop( + await createTestUser(wonderwomanGuest, orgId), + 'Non-Admin Shop', + 'desc', + organization + ) + ).rejects.toThrow(new AccessDeniedAdminOnlyException('create shop')); + }); + + it('succeeds for admin', async () => { + const admin = await createTestUser(supermanAdmin, orgId); + const result = await ShopServices.createShop(admin, 'Demo Shop', 'A seeded demo shop', organization); + + expect(result.name).toBe('Demo Shop'); + expect(result.description).toBe('A seeded demo shop'); + expect(result.userCreatedId).toBe(admin.userId); + }); + + it('fails on duplicate name', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); + await ShopServices.createShop(admin, 'UniqueName', 'first', organization); + + await expect( + ShopServices.createShop(admin, 'UniqueName', 'second attempt', organization) + ).rejects.toBeTruthy(); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index c82e2a9721..1c0eddac84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6,9 +6,9 @@ __metadata: cacheKey: 8 "@adobe/css-tools@npm:^4.4.0": - version: 4.4.3 - resolution: "@adobe/css-tools@npm:4.4.3" - checksum: 8c773f624d7327cdc58e92ab9077500f4578b24eee9f504e7925a775df6885cd534399c40c1a2919e38cbd57c0023d5bf9e32f8b89ed783733f706366b0f61e6 + version: 4.4.4 + resolution: "@adobe/css-tools@npm:4.4.4" + checksum: 452b82cd9f42aacc57eeaf0b11e36c6864eb482e8a347054cb986503d221d1f7c1418710d2007858d8919afdbd31357149c2c16bd080ded15506f13608d16cf2 languageName: node linkType: hard @@ -19,16 +19,6 @@ __metadata: languageName: node linkType: hard -"@ampproject/remapping@npm:^2.2.0": - version: 2.3.0 - resolution: "@ampproject/remapping@npm:2.3.0" - dependencies: - "@jridgewell/gen-mapping": ^0.3.5 - "@jridgewell/trace-mapping": ^0.3.24 - checksum: d3ad7b89d973df059c4e8e6d7c972cbeb1bb2f18f002a3bd04ae0707da214cb06cc06929b65aa2313b9347463df2914772298bae8b1d7973f246bb3f2ab3e8f0 - languageName: node - linkType: hard - "@apideck/better-ajv-errors@npm:^0.3.1": version: 0.3.6 resolution: "@apideck/better-ajv-errors@npm:0.3.6" @@ -42,6 +32,490 @@ __metadata: languageName: node linkType: hard +"@aws-crypto/sha256-browser@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/sha256-browser@npm:5.2.0" + dependencies: + "@aws-crypto/sha256-js": ^5.2.0 + "@aws-crypto/supports-web-crypto": ^5.2.0 + "@aws-crypto/util": ^5.2.0 + "@aws-sdk/types": ^3.222.0 + "@aws-sdk/util-locate-window": ^3.0.0 + "@smithy/util-utf8": ^2.0.0 + tslib: ^2.6.2 + checksum: 773f12f2026d82a6bb4a23a8f491894a6d32525bd9b8bfbc12896526cf11882a7607a671c478c45f9cd7d6ba1caaed48a62b67c6f725244bd83a1275108f46c7 + languageName: node + linkType: hard + +"@aws-crypto/sha256-js@npm:5.2.0, @aws-crypto/sha256-js@npm:^5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/sha256-js@npm:5.2.0" + dependencies: + "@aws-crypto/util": ^5.2.0 + "@aws-sdk/types": ^3.222.0 + tslib: ^2.6.2 + checksum: 007fbe0436d714d0d0d282e2b61c90e45adcb9ad75eac9ac7ba03d32b56624afd09b2a9ceb4d659661cf17c51d74d1900ab6b00eacafc002da1101664955ca53 + languageName: node + linkType: hard + +"@aws-crypto/supports-web-crypto@npm:^5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/supports-web-crypto@npm:5.2.0" + dependencies: + tslib: ^2.6.2 + checksum: 6ffc21de48b2b2c3e918193101d7e8fe949d47b37688892e1c39eaedaa938be80c0f404fe1c874c30cce16781026777a53bf47d5d90143ca91d0feb7c4a6f830 + languageName: node + linkType: hard + +"@aws-crypto/util@npm:^5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/util@npm:5.2.0" + dependencies: + "@aws-sdk/types": ^3.222.0 + "@smithy/util-utf8": ^2.0.0 + tslib: ^2.6.2 + checksum: f0f81d9d2771c59946cfec48b86cb23d39f78a966c4a1f89d4753abdc3cb38de06f907d1e6450059b121d48ac65d612ab88bdb70014553a077fc3dabddfbf8d6 + languageName: node + linkType: hard + +"@aws-sdk/client-ses@npm:^3.731.1": + version: 3.888.0 + resolution: "@aws-sdk/client-ses@npm:3.888.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.888.0 + "@aws-sdk/credential-provider-node": 3.888.0 + "@aws-sdk/middleware-host-header": 3.887.0 + "@aws-sdk/middleware-logger": 3.887.0 + "@aws-sdk/middleware-recursion-detection": 3.887.0 + "@aws-sdk/middleware-user-agent": 3.888.0 + "@aws-sdk/region-config-resolver": 3.887.0 + "@aws-sdk/types": 3.887.0 + "@aws-sdk/util-endpoints": 3.887.0 + "@aws-sdk/util-user-agent-browser": 3.887.0 + "@aws-sdk/util-user-agent-node": 3.888.0 + "@smithy/config-resolver": ^4.2.1 + "@smithy/core": ^3.11.0 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/hash-node": ^4.1.1 + "@smithy/invalid-dependency": ^4.1.1 + "@smithy/middleware-content-length": ^4.1.1 + "@smithy/middleware-endpoint": ^4.2.1 + "@smithy/middleware-retry": ^4.2.1 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/middleware-stack": ^4.1.1 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-body-length-node": ^4.1.0 + "@smithy/util-defaults-mode-browser": ^4.1.1 + "@smithy/util-defaults-mode-node": ^4.1.1 + "@smithy/util-endpoints": ^3.1.1 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-retry": ^4.1.1 + "@smithy/util-utf8": ^4.1.0 + "@smithy/util-waiter": ^4.1.1 + tslib: ^2.6.2 + checksum: 818bd91245081edb2e16d3e8c05f0c9a74868dd46b9f3fa1b4d57496636961a3a09ce7837471abaebe0e2697c7732366d5af3b8d9b9ece65c4d3c0a7e1419619 + languageName: node + linkType: hard + +"@aws-sdk/client-sso@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/client-sso@npm:3.888.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.888.0 + "@aws-sdk/middleware-host-header": 3.887.0 + "@aws-sdk/middleware-logger": 3.887.0 + "@aws-sdk/middleware-recursion-detection": 3.887.0 + "@aws-sdk/middleware-user-agent": 3.888.0 + "@aws-sdk/region-config-resolver": 3.887.0 + "@aws-sdk/types": 3.887.0 + "@aws-sdk/util-endpoints": 3.887.0 + "@aws-sdk/util-user-agent-browser": 3.887.0 + "@aws-sdk/util-user-agent-node": 3.888.0 + "@smithy/config-resolver": ^4.2.1 + "@smithy/core": ^3.11.0 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/hash-node": ^4.1.1 + "@smithy/invalid-dependency": ^4.1.1 + "@smithy/middleware-content-length": ^4.1.1 + "@smithy/middleware-endpoint": ^4.2.1 + "@smithy/middleware-retry": ^4.2.1 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/middleware-stack": ^4.1.1 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-body-length-node": ^4.1.0 + "@smithy/util-defaults-mode-browser": ^4.1.1 + "@smithy/util-defaults-mode-node": ^4.1.1 + "@smithy/util-endpoints": ^3.1.1 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-retry": ^4.1.1 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: 0aa68ee0144cf56c31034c520c39fd8c53b73083bd6ce1ad0ac32ecbefd497e280b5638a00b8078c26e4687b4a083161468b94f4d79d0e51132c98044d2628ab + languageName: node + linkType: hard + +"@aws-sdk/core@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/core@npm:3.888.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@aws-sdk/xml-builder": 3.887.0 + "@smithy/core": ^3.11.0 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/property-provider": ^4.0.5 + "@smithy/protocol-http": ^5.2.1 + "@smithy/signature-v4": ^5.1.3 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-utf8": ^4.1.0 + fast-xml-parser: 5.2.5 + tslib: ^2.6.2 + checksum: baf26845beaf66f796130337365e2992751e37fd632ea75ad0bfc8f955aea704c69112fc107a0c13a5af7e932707c3a40fc490c9634cdda4acf6050f5ca63deb + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-env@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 4c5012bcb95966db2a72ad7700fc3b5bbb4f7e4dea43f215b972b2d868ed40c8b7c7d1cec4fe53b0bda9b5f6c142480716561707609022f0fd91f033c2450a9c + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-http@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/property-provider": ^4.0.5 + "@smithy/protocol-http": ^5.2.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/util-stream": ^4.3.1 + tslib: ^2.6.2 + checksum: cd83cae0e01c65bc91ff922670d5c1933463726bbb44a68c6ee726f6b0799dc8d596ca7ef15e1abfb7fb9c88322f337e2bd303f65d66dfd5859055be35061d86 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-ini@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/credential-provider-env": 3.888.0 + "@aws-sdk/credential-provider-http": 3.888.0 + "@aws-sdk/credential-provider-process": 3.888.0 + "@aws-sdk/credential-provider-sso": 3.888.0 + "@aws-sdk/credential-provider-web-identity": 3.888.0 + "@aws-sdk/nested-clients": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/credential-provider-imds": ^4.0.7 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: aa551d529f378ef9558a16ea01e043f742646f38347469e2b1cbe3e2e094ca30cd272911750c62dd56908c9ff704c459014f6fbf3a25fd61e8f0e7e61f3a41bb + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-node@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.888.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.888.0 + "@aws-sdk/credential-provider-http": 3.888.0 + "@aws-sdk/credential-provider-ini": 3.888.0 + "@aws-sdk/credential-provider-process": 3.888.0 + "@aws-sdk/credential-provider-sso": 3.888.0 + "@aws-sdk/credential-provider-web-identity": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/credential-provider-imds": ^4.0.7 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: cac63c05516ebf645068f8f68f1932db4691b1368ceced7260cd6ad6b10e4bf6be30962c150e3db69aab86e31609576610b85e62293fc4b4c71b4c96991e9ada + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-process@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 51290738eb782230758767994c677bec5a7da72756b7a780e5eaff04ed2812d7612e74df90892eac89c1f06ad164f2c657da0d999a786158e7e4af972a9dc7e0 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-sso@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.888.0" + dependencies: + "@aws-sdk/client-sso": 3.888.0 + "@aws-sdk/core": 3.888.0 + "@aws-sdk/token-providers": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 69e040bd12cea21134669ce8635741a754c940e5c9b053bf208d498b7878ca35ed047405eddf8264c8e44f09258166c8701b75776aa9002f8fc28e6b9a498580 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-web-identity@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/nested-clients": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: f4a6855190f47b00c5150d8e89c588e2beb65232829a4e2cef398aab2fddd775124541cead84c4ae5b59f1cabd4e566127ae23cb909841ce8e34a2d8f4fbc623 + languageName: node + linkType: hard + +"@aws-sdk/middleware-host-header@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: f07a901c5165d8eaf831bc0968f12c77c2b74cde53c7a6f61caadc87578172be162e4e0df6fdf7df0a182d282716603f01b4d818b2f2ba2856ad0ecb82de7816 + languageName: node + linkType: hard + +"@aws-sdk/middleware-logger@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/middleware-logger@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 6f4a95ed164378d6104207ec6b0da8d61452a74a67c95156e42be33d00f29daa53badc7a0461f269223eaeb0d5eff520d8fc4e25cc615657c0d5a897dbd7546f + languageName: node + linkType: hard + +"@aws-sdk/middleware-recursion-detection@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@aws/lambda-invoke-store": ^0.0.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: c8cdef1bcbe1228b918c6fa8fd7f149fb46c0004ee661b04138d95f167eeae9abfac68ca5597b70fa501efc292024ce7369161459cdcb2f6615587c428c6baac + languageName: node + linkType: hard + +"@aws-sdk/middleware-user-agent@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@aws-sdk/util-endpoints": 3.887.0 + "@smithy/core": ^3.11.0 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 17eeaa35c7a9b4e0505e7d5feb705c41dbdcdf4809ef39562fa8bd6e964ef5b9d3669eb6f307e535ce3f7a00c466b4080948a822ee9d7e14fa2c4257dc0c5eb3 + languageName: node + linkType: hard + +"@aws-sdk/nested-clients@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/nested-clients@npm:3.888.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.888.0 + "@aws-sdk/middleware-host-header": 3.887.0 + "@aws-sdk/middleware-logger": 3.887.0 + "@aws-sdk/middleware-recursion-detection": 3.887.0 + "@aws-sdk/middleware-user-agent": 3.888.0 + "@aws-sdk/region-config-resolver": 3.887.0 + "@aws-sdk/types": 3.887.0 + "@aws-sdk/util-endpoints": 3.887.0 + "@aws-sdk/util-user-agent-browser": 3.887.0 + "@aws-sdk/util-user-agent-node": 3.888.0 + "@smithy/config-resolver": ^4.2.1 + "@smithy/core": ^3.11.0 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/hash-node": ^4.1.1 + "@smithy/invalid-dependency": ^4.1.1 + "@smithy/middleware-content-length": ^4.1.1 + "@smithy/middleware-endpoint": ^4.2.1 + "@smithy/middleware-retry": ^4.2.1 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/middleware-stack": ^4.1.1 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-body-length-node": ^4.1.0 + "@smithy/util-defaults-mode-browser": ^4.1.1 + "@smithy/util-defaults-mode-node": ^4.1.1 + "@smithy/util-endpoints": ^3.1.1 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-retry": ^4.1.1 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: 699aaea06f8d0fe720470003ec70ede15e8781d50dbf28ed827ed7dd85318b3684995996859c1c5e0350ba9829f39f6721f1229b2c0e06f2a0e4cf77fee89f4b + languageName: node + linkType: hard + +"@aws-sdk/region-config-resolver@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-config-provider": ^4.0.0 + "@smithy/util-middleware": ^4.1.1 + tslib: ^2.6.2 + checksum: aced1bf4e3dce92fa76337a774551cf88e72a25e44f7582a9897ce52e73d309791fab22ba4900f364715afc73190c9e5a1d8934077aa04a63d8ef9cd9bf3f4ad + languageName: node + linkType: hard + +"@aws-sdk/token-providers@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/token-providers@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/nested-clients": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 8e2e6ac2fc480f6d1b38a3563f274d2096bc7aad1ea46e875ce08955c7bb37b8c3f2ce7c457f414af94b5d7053499589909f15ceb5de8c28bd9a596c24b6fa6c + languageName: node + linkType: hard + +"@aws-sdk/types@npm:3.887.0, @aws-sdk/types@npm:^3.222.0": + version: 3.887.0 + resolution: "@aws-sdk/types@npm:3.887.0" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 141d3fcd3bf5b95e13df81b8cf1554f2cc2f4783922265ea344ab60105ea4453a9b4fae7df5da8652f9ede9e83fba8b06bc1c95566329d0541810d711ff1dad9 + languageName: node + linkType: hard + +"@aws-sdk/util-endpoints@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/util-endpoints@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-endpoints": ^3.1.1 + tslib: ^2.6.2 + checksum: aced26165e63871ac44e0cd9393729cb437d8b2f277c34cc45d51c9964e43c5bea4762c948ee04e9a93c5d98b037923de23d0b69973f256480f533285d0db45d + languageName: node + linkType: hard + +"@aws-sdk/util-locate-window@npm:^3.0.0": + version: 3.873.0 + resolution: "@aws-sdk/util-locate-window@npm:3.873.0" + dependencies: + tslib: ^2.6.2 + checksum: ff98e8fa00504ae62bf25605e708ac77693b11b628e0234b0a5bd03e6021e0ca12677ea494b1463c2ef70b483b5b30b2a08dfe5806788a570b3d7becae15591e + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-browser@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/types": ^4.5.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 18c5f77fd5e60129c7944c7f2d8b5b6c61783c12d59492193b25dcb6631d1c48896d5ffdec4ffd579ed75ae781c8fb91747e25cf4e7927b6f37b41b059e3035c + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-node@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.888.0" + dependencies: + "@aws-sdk/middleware-user-agent": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: f2e273f44e078aeeaad678a592a69c315e0307a557f48759cba5d78f2ae501faed18c2497ea27e35796a11642ea6f9eeff2629947db07621b3a553e7fc81884c + languageName: node + linkType: hard + +"@aws-sdk/xml-builder@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/xml-builder@npm:3.887.0" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: c2937d705a6ba6e3635279532eb984548117086520e9569df97ce400c6d7b9d1a74b47e720089857e2e5bd2a68f2b8273e746a79938ece0b875cca5b7ddbd844 + languageName: node + linkType: hard + +"@aws/lambda-invoke-store@npm:^0.0.1": + version: 0.0.1 + resolution: "@aws/lambda-invoke-store@npm:0.0.1" + checksum: af732ba2cd343daa49d4933827b4bdc80449641fbdf465ad4a97a818adf6f355454942a2b59a6a297c261c1b3fff11ea69c93b9564ed5e33fcdcf30f993c722d + languageName: node + linkType: hard + "@babel/code-frame@npm:7.12.11": version: 7.12.11 resolution: "@babel/code-frame@npm:7.12.11" @@ -63,38 +537,38 @@ __metadata: linkType: hard "@babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7, @babel/compat-data@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/compat-data@npm:7.28.0" - checksum: 37a40d4ea10a32783bc24c4ad374200f5db864c8dfa42f82e76f02b8e84e4c65e6a017fc014d165b08833f89333dff4cb635fce30f03c333ea3525ea7e20f0a2 + version: 7.28.4 + resolution: "@babel/compat-data@npm:7.28.4" + checksum: 9f6f5289bbe5a29e3f9c737577a797205a91f19371b50af8942257d9cb590d44eb950154e4f2a3d5de4105f97a49d6fbc8daebe0db1e6eee04f5a4bf73536bfc languageName: node linkType: hard "@babel/core@npm:^7.1.0, @babel/core@npm:^7.11.1, @babel/core@npm:^7.12.3, @babel/core@npm:^7.16.0, @babel/core@npm:^7.20.5, @babel/core@npm:^7.28.0, @babel/core@npm:^7.7.2, @babel/core@npm:^7.8.0": - version: 7.28.0 - resolution: "@babel/core@npm:7.28.0" + version: 7.28.4 + resolution: "@babel/core@npm:7.28.4" dependencies: - "@ampproject/remapping": ^2.2.0 "@babel/code-frame": ^7.27.1 - "@babel/generator": ^7.28.0 + "@babel/generator": ^7.28.3 "@babel/helper-compilation-targets": ^7.27.2 - "@babel/helper-module-transforms": ^7.27.3 - "@babel/helpers": ^7.27.6 - "@babel/parser": ^7.28.0 + "@babel/helper-module-transforms": ^7.28.3 + "@babel/helpers": ^7.28.4 + "@babel/parser": ^7.28.4 "@babel/template": ^7.27.2 - "@babel/traverse": ^7.28.0 - "@babel/types": ^7.28.0 + "@babel/traverse": ^7.28.4 + "@babel/types": ^7.28.4 + "@jridgewell/remapping": ^2.3.5 convert-source-map: ^2.0.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.3 semver: ^6.3.1 - checksum: 86da9e26c96e22d96deca0509969d273476f61c30464f262dec5e5a163422e07d5ab690ed54619d10fcab784abd10567022ce3d90f175b40279874f5288215e3 + checksum: f55b90b2c61a6461f5c0ccab74d32af9c67448c43c629529ba7ec3c61d87fa8c408cc9305bfb1f5b09e671d25436d44eaf75c48dee5dc0a5c5e21c01290f5134 languageName: node linkType: hard "@babel/eslint-parser@npm:^7.16.3": - version: 7.28.0 - resolution: "@babel/eslint-parser@npm:7.28.0" + version: 7.28.4 + resolution: "@babel/eslint-parser@npm:7.28.4" dependencies: "@nicolo-ribaudo/eslint-scope-5-internals": 5.1.1-v1 eslint-visitor-keys: ^2.1.0 @@ -102,20 +576,20 @@ __metadata: peerDependencies: "@babel/core": ^7.11.0 eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - checksum: ccfc4b9b9fdca2b8df95da3827b70231e9588a71447ff7b2de76c4f36710e4e0a7dc5e2e98623f398a737c2429c46500cb11d4ccdfeb98271e067d0bf0eec9b5 + checksum: 32fb41c8648e169bc8570e25b4657475e165e1a49b8c6610f9bf86f311bbcc8dfa73f004977015688763aa6af17f48c690720bbc7b7b99695557adb267a9a7ff languageName: node linkType: hard -"@babel/generator@npm:^7.28.0, @babel/generator@npm:^7.7.2": - version: 7.28.0 - resolution: "@babel/generator@npm:7.28.0" +"@babel/generator@npm:^7.28.3, @babel/generator@npm:^7.7.2": + version: 7.28.3 + resolution: "@babel/generator@npm:7.28.3" dependencies: - "@babel/parser": ^7.28.0 - "@babel/types": ^7.28.0 + "@babel/parser": ^7.28.3 + "@babel/types": ^7.28.2 "@jridgewell/gen-mapping": ^0.3.12 "@jridgewell/trace-mapping": ^0.3.28 jsesc: ^3.0.2 - checksum: 3fc9ecca7e7a617cf7b7357e11975ddfaba4261f374ab915f5d9f3b1ddc8fd58da9f39492396416eb08cf61972d1aa13c92d4cca206533c553d8651c2740f07f + checksum: e2202bf2b9c8a94f7e7a0a049fda0ee037d055c46922e85afa3bbc53309113f859b8193894f991045d7865226028b8f4f06152ed315ab414451932016dba5e42 languageName: node linkType: hard @@ -141,20 +615,20 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-create-class-features-plugin@npm:7.27.1" +"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.27.1, @babel/helper-create-class-features-plugin@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/helper-create-class-features-plugin@npm:7.28.3" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.1 + "@babel/helper-annotate-as-pure": ^7.27.3 "@babel/helper-member-expression-to-functions": ^7.27.1 "@babel/helper-optimise-call-expression": ^7.27.1 "@babel/helper-replace-supers": ^7.27.1 "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 - "@babel/traverse": ^7.27.1 + "@babel/traverse": ^7.28.3 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 406954b455e5b20924e7d1b41cf932e6e98e95c3a5224c7a70c3ad96a84e8fbde915ceff7ddbf9c7d121397c4e9274f061241648475122cf6fe54e0a95caae15 + checksum: 6d918e5e9c88ad1a262ab7b1a3caede1bbf95f8276c96846d8b0c1af251c85a0c868a9f1bbbaebdeb199e44dfd0e10fbe22935e56bedd1aa41ba4a7162bfa86c languageName: node linkType: hard @@ -213,16 +687,16 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.27.3": - version: 7.27.3 - resolution: "@babel/helper-module-transforms@npm:7.27.3" +"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/helper-module-transforms@npm:7.28.3" dependencies: "@babel/helper-module-imports": ^7.27.1 "@babel/helper-validator-identifier": ^7.27.1 - "@babel/traverse": ^7.27.3 + "@babel/traverse": ^7.28.3 peerDependencies: "@babel/core": ^7.0.0 - checksum: c611d42d3cb7ba23b1a864fcf8d6cde0dc99e876ca1c9a67e4d7919a70706ded4aaa45420de2bf7f7ea171e078e59f0edcfa15a56d74b9485e151b95b93b946e + checksum: 7cf7b79da0fa626d6c84bfc7b35c079a2559caecaa2ff645b0f1db0d741507aa4df6b5b98a3283e8ac4e89094af271d805bf5701e5c4f916e622797b7c8cbb18 languageName: node linkType: hard @@ -300,23 +774,23 @@ __metadata: linkType: hard "@babel/helper-wrap-function@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-wrap-function@npm:7.27.1" + version: 7.28.3 + resolution: "@babel/helper-wrap-function@npm:7.28.3" dependencies: - "@babel/template": ^7.27.1 - "@babel/traverse": ^7.27.1 - "@babel/types": ^7.27.1 - checksum: b0427765766494cb5455a188d4cdef5e6167f2835a8ed76f3c25fa3bbe2ec2a716588fa326c52fab0d184a9537200d76e48656e516580a914129d74528322821 + "@babel/template": ^7.27.2 + "@babel/traverse": ^7.28.3 + "@babel/types": ^7.28.2 + checksum: 0ebdfdc918fdd0c1cf6ff15ba4c664974d0cdf21a017af560d58b00c379df3bf2e55f13a44fe3225668bca169da174f6cb97a96c4e987fb728fdb8f9a39db302 languageName: node linkType: hard -"@babel/helpers@npm:^7.27.6": - version: 7.28.2 - resolution: "@babel/helpers@npm:7.28.2" +"@babel/helpers@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/helpers@npm:7.28.4" dependencies: "@babel/template": ^7.27.2 - "@babel/types": ^7.28.2 - checksum: 7ead856041f73496eeeb4f7f88a741067c8022fc764cbca7fc3e96ae73ce71969f75fd79b40b2c6a60ca4923f9d56f7798fb86ac2538f13b6d4acb54ebb563a7 + "@babel/types": ^7.28.4 + checksum: a8706219e0bd60c18bbb8e010aa122e9b14e7e7e67c21cc101e6f1b5e79dcb9a18d674f655997f85daaf421aa138cf284710bb04371a2255a0a3137f097430b4 languageName: node linkType: hard @@ -332,14 +806,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/parser@npm:7.28.0" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/parser@npm:7.28.4" dependencies: - "@babel/types": ^7.28.0 + "@babel/types": ^7.28.4 bin: parser: ./bin/babel-parser.js - checksum: 718e4ce9b0914701d6f74af610d3e7d52b355ef1dcf34a7dedc5930e96579e387f04f96187e308e601828b900b8e4e66d2fe85023beba2ac46587023c45b01cf + checksum: d95e283fe1153039b396926ef567ca1ab114afb5c732a23bbcbbd0465ac59971aeb6a63f37593ce7671a52d34ec52b23008c999d68241b42d26928c540464063 languageName: node linkType: hard @@ -390,15 +864,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.27.1" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.28.3" dependencies: "@babel/helper-plugin-utils": ^7.27.1 - "@babel/traverse": ^7.27.1 + "@babel/traverse": ^7.28.3 peerDependencies: "@babel/core": ^7.0.0 - checksum: 4d6792ccade2d6b9d5577b0a879ab22d05ac8a1206b1a636b6ffdb53a0c0bacaf0f7947e46de254f228ffd75456f4b95ccd82fdeaefc0b92d88af3c5991863ad + checksum: c810e5d36030df6861ced35f0adbda7b4b41ac3e984422b32bee906564fd49374435f0a7a1a42eb0a9e6a5170c255f0ab31c163d5fc51fa5a816aa0420311029 languageName: node linkType: hard @@ -780,13 +1254,13 @@ __metadata: linkType: hard "@babel/plugin-transform-block-scoping@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/plugin-transform-block-scoping@npm:7.28.0" + version: 7.28.4 + resolution: "@babel/plugin-transform-block-scoping@npm:7.28.4" dependencies: "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 6d740f9a386e5fbdffd9e7c5a8400bff8d54068241a78b8e71aba6f1f46eff0c4297902f5f1543bee1ed076ec88d0dc4ceed19e98a466802c14d3c20f178f712 + checksum: 7f62eae907c0b4f85b9cc024da949697e57d17f2107ca4a240011174762d4c546b856ccbd5ba83ecb4bc9eb50150ea46558d551a5b05d3f25aace88a65fa4e04 languageName: node linkType: hard @@ -802,31 +1276,31 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-class-static-block@npm:7.27.1" +"@babel/plugin-transform-class-static-block@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/plugin-transform-class-static-block@npm:7.28.3" dependencies: - "@babel/helper-create-class-features-plugin": ^7.27.1 + "@babel/helper-create-class-features-plugin": ^7.28.3 "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.12.0 - checksum: 69688fe1641ae0ea025b916b8c2336e8b5643a5ec292e8f546ecd35d9d9d4bb301d738910822a79d867098cf687d550d92cd906ae4cda03c0f69b1ece2149a58 + checksum: 9b2feaacbf29637ab35a3aae1df35a1129adec5400a1767443739557fb0d3bf8278bf0ec90aacf43dec9a7dd91428d01375020b70528713e1bc36a72776a104c languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/plugin-transform-classes@npm:7.28.0" +"@babel/plugin-transform-classes@npm:^7.28.3": + version: 7.28.4 + resolution: "@babel/plugin-transform-classes@npm:7.28.4" dependencies: "@babel/helper-annotate-as-pure": ^7.27.3 "@babel/helper-compilation-targets": ^7.27.2 "@babel/helper-globals": ^7.28.0 "@babel/helper-plugin-utils": ^7.27.1 "@babel/helper-replace-supers": ^7.27.1 - "@babel/traverse": ^7.28.0 + "@babel/traverse": ^7.28.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0b47188046a4f1579123354ee30d08874b4b585d45128a3d492fa1cba7e26c8039d8c44d38d85f4eaa9b5a53064c66f032cfc35526c73c74a865a11edf3a0c28 + checksum: f412e00c86584a9094cc0a2f3dd181b8108a4dced477d609c5406beddd5bf79d05a7ea74db508dc4dcb37172f042d5ef98d3d6311ade61c7ea6fbbbb70f5ec29 languageName: node linkType: hard @@ -1122,17 +1596,17 @@ __metadata: linkType: hard "@babel/plugin-transform-object-rest-spread@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.0" + version: 7.28.4 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.4" dependencies: "@babel/helper-compilation-targets": ^7.27.2 "@babel/helper-plugin-utils": ^7.27.1 "@babel/plugin-transform-destructuring": ^7.28.0 "@babel/plugin-transform-parameters": ^7.27.7 - "@babel/traverse": ^7.28.0 + "@babel/traverse": ^7.28.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7c32c988b4b040d0091d0210b6b946249571858b2f33f3a5105f41c28ee0b8440a9dfb2aa46f3ae0d3014f86ddf16aee9a0cbf4229daf8e013235352b8f31fc9 + checksum: 2063672ba4ac457a64b5c0c982439c7b08b4c70f0e743792b98240db5a05f1c063918d8366c92d4d6b2572e2e3452b300a23980b6668e4f54ff349f60d47ec48 languageName: node linkType: hard @@ -1300,14 +1774,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.28.0": - version: 7.28.1 - resolution: "@babel/plugin-transform-regenerator@npm:7.28.1" +"@babel/plugin-transform-regenerator@npm:^7.28.3": + version: 7.28.4 + resolution: "@babel/plugin-transform-regenerator@npm:7.28.4" dependencies: "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c0bc0123ce2227c5074c7c17d6b72b558f0b38360aa180751c897086912f5e17e18855d361ac29f542343ad30ee128b937398282dc9a12c795fa8227954e48ea + checksum: 2aa99b3a7b254a109e913fabbe1fb320ff40723988fde0e225212b7ef20f523a399a6e45077258b176c29715493b2a853cf7c130811692215adf33e5af99782b languageName: node linkType: hard @@ -1335,8 +1809,8 @@ __metadata: linkType: hard "@babel/plugin-transform-runtime@npm:^7.16.4": - version: 7.28.0 - resolution: "@babel/plugin-transform-runtime@npm:7.28.0" + version: 7.28.3 + resolution: "@babel/plugin-transform-runtime@npm:7.28.3" dependencies: "@babel/helper-module-imports": ^7.27.1 "@babel/helper-plugin-utils": ^7.27.1 @@ -1346,7 +1820,7 @@ __metadata: semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8d324eb312636efe706917a5d44f867538654453c9bf4efd34b0dbd712c6d80e604092b98acbfcb318f42bec707b590c28ae95c659ff359a64a4ccb7621dc400 + checksum: 63d2fc05d5bfcb96f31be54b095d72a89f0a03c8de10f5d742b18b174e2731bcdc27292e8deec66c2e88cebf8298393123d5e767526f6fffbc75cb8144ef66c6 languageName: node linkType: hard @@ -1469,8 +1943,8 @@ __metadata: linkType: hard "@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.16.4": - version: 7.28.0 - resolution: "@babel/preset-env@npm:7.28.0" + version: 7.28.3 + resolution: "@babel/preset-env@npm:7.28.3" dependencies: "@babel/compat-data": ^7.28.0 "@babel/helper-compilation-targets": ^7.27.2 @@ -1480,7 +1954,7 @@ __metadata: "@babel/plugin-bugfix-safari-class-field-initializer-scope": ^7.27.1 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.27.1 "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.27.1 - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.27.1 + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.28.3 "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 "@babel/plugin-syntax-import-assertions": ^7.27.1 "@babel/plugin-syntax-import-attributes": ^7.27.1 @@ -1491,8 +1965,8 @@ __metadata: "@babel/plugin-transform-block-scoped-functions": ^7.27.1 "@babel/plugin-transform-block-scoping": ^7.28.0 "@babel/plugin-transform-class-properties": ^7.27.1 - "@babel/plugin-transform-class-static-block": ^7.27.1 - "@babel/plugin-transform-classes": ^7.28.0 + "@babel/plugin-transform-class-static-block": ^7.28.3 + "@babel/plugin-transform-classes": ^7.28.3 "@babel/plugin-transform-computed-properties": ^7.27.1 "@babel/plugin-transform-destructuring": ^7.28.0 "@babel/plugin-transform-dotall-regex": ^7.27.1 @@ -1524,7 +1998,7 @@ __metadata: "@babel/plugin-transform-private-methods": ^7.27.1 "@babel/plugin-transform-private-property-in-object": ^7.27.1 "@babel/plugin-transform-property-literals": ^7.27.1 - "@babel/plugin-transform-regenerator": ^7.28.0 + "@babel/plugin-transform-regenerator": ^7.28.3 "@babel/plugin-transform-regexp-modifiers": ^7.27.1 "@babel/plugin-transform-reserved-words": ^7.27.1 "@babel/plugin-transform-shorthand-properties": ^7.27.1 @@ -1544,7 +2018,7 @@ __metadata: semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 90399ed6350ac413fb507dc5c9e29e98d10684c4b7c7c6ae7b204bb91a7a9cd3bf8f944167a931a73112c8c820d0d1f42d4c15d7c4a7cf19196bf11c19663513 + checksum: c4e70f69b727d21eedd4de201ac082e951482f2d28a388e401e7937fd6f15bc1a49a63c12f59e87a18d237ac037a5b29d983f3bb82f1196d6444ae5b605ac6e2 languageName: node linkType: hard @@ -1592,10 +2066,10 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.28.2, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.7": - version: 7.28.2 - resolution: "@babel/runtime@npm:7.28.2" - checksum: 8673eb2311752929f5b0167f42cff4cc1d5fadddd0394baca27d06c1618680ffcf95e9f01061f5c4dc3f6a32b6bbf500e7762c02dc22bcd273c2947b9774ddad +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.28.3, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.7": + version: 7.28.4 + resolution: "@babel/runtime@npm:7.28.4" + checksum: 934b0a0460f7d06637d93fcd1a44ac49adc33518d17253b5a0b55ff4cb90a45d8fe78bf034b448911dbec7aff2a90b918697559f78d21c99ff8dbadae9565b55 languageName: node linkType: hard @@ -1610,28 +2084,28 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.7.2": - version: 7.28.0 - resolution: "@babel/traverse@npm:7.28.0" +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.7.2": + version: 7.28.4 + resolution: "@babel/traverse@npm:7.28.4" dependencies: "@babel/code-frame": ^7.27.1 - "@babel/generator": ^7.28.0 + "@babel/generator": ^7.28.3 "@babel/helper-globals": ^7.28.0 - "@babel/parser": ^7.28.0 + "@babel/parser": ^7.28.4 "@babel/template": ^7.27.2 - "@babel/types": ^7.28.0 + "@babel/types": ^7.28.4 debug: ^4.3.1 - checksum: f1b6ed2a37f593ee02db82521f8d54c8540a7ec2735c6c127ba687de306d62ac5a7c6471819783128e0b825c4f7e374206ebbd1daf00d07f05a4528f5b1b4c07 + checksum: d603b8ce4e55ba4fc7b28d3362cc2b1b20bc887e471c8a59fe87b2578c26803c9ef8fcd118081dd8283ea78e0e9a6df9d88c8520033c6aaf81eec30d2a669151 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.0, @babel/types@npm:^7.28.2, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": - version: 7.28.2 - resolution: "@babel/types@npm:7.28.2" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": + version: 7.28.4 + resolution: "@babel/types@npm:7.28.4" dependencies: "@babel/helper-string-parser": ^7.27.1 "@babel/helper-validator-identifier": ^7.27.1 - checksum: 2218f0996d5fbadc4e3428c4c38f4ed403f0e2634e3089beba2c89783268c0c1d796a23e65f9f1ff8547b9061ae1a67691c76dc27d0b457e5fa9f2dd4e022e49 + checksum: a369b4fb73415a2ed902a15576b49696ae9777ddee394a7a904c62e6fbb31f43906b0147ae0b8f03ac17f20c248eac093df349e33c65c94617b12e524b759694 languageName: node linkType: hard @@ -1660,16 +2134,6 @@ __metadata: languageName: node linkType: hard -"@bundled-es-modules/tough-cookie@npm:^0.1.6": - version: 0.1.6 - resolution: "@bundled-es-modules/tough-cookie@npm:0.1.6" - dependencies: - "@types/tough-cookie": ^4.0.5 - tough-cookie: ^4.1.4 - checksum: e31c1262cbc044373e757117b1b152acc86ba5d088124153b3d1ae83e0de0a2b4d2362758cec3e1a49cf15c39a4447587cc2672e4f5a961754c91ef9ca3221e1 - languageName: node - linkType: hard - "@cspotcode/source-map-support@npm:^0.8.0": version: 0.8.1 resolution: "@cspotcode/source-map-support@npm:0.8.1" @@ -1892,11 +2356,11 @@ __metadata: linkType: hard "@emotion/is-prop-valid@npm:^1.3.0": - version: 1.3.1 - resolution: "@emotion/is-prop-valid@npm:1.3.1" + version: 1.4.0 + resolution: "@emotion/is-prop-valid@npm:1.4.0" dependencies: "@emotion/memoize": ^0.9.0 - checksum: fe6549d54f389e1a17cb02d832af7ee85fb6ea126fc18d02ca47216e8ff19332c1983f4a0ba68602cfcd3b325ffd4ebf0b2d0c6270f1e7e6fe3fca4ba7741e1a + checksum: 6b003cdc62106c2d5d12207c2d1352d674339252a2d7ac8d96974781d7c639833f35d22e7e331411795daaafa62f126c2824a4983584292b431e08b42877d51e languageName: node linkType: hard @@ -2012,9 +2476,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/aix-ppc64@npm:0.25.8" +"@esbuild/aix-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/aix-ppc64@npm:0.25.9" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -2040,9 +2504,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/android-arm64@npm:0.25.8" +"@esbuild/android-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm64@npm:0.25.9" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -2068,9 +2532,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/android-arm@npm:0.25.8" +"@esbuild/android-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm@npm:0.25.9" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -2096,9 +2560,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/android-x64@npm:0.25.8" +"@esbuild/android-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-x64@npm:0.25.9" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -2124,9 +2588,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/darwin-arm64@npm:0.25.8" +"@esbuild/darwin-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-arm64@npm:0.25.9" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -2152,9 +2616,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/darwin-x64@npm:0.25.8" +"@esbuild/darwin-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-x64@npm:0.25.9" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -2180,9 +2644,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/freebsd-arm64@npm:0.25.8" +"@esbuild/freebsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-arm64@npm:0.25.9" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -2208,9 +2672,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/freebsd-x64@npm:0.25.8" +"@esbuild/freebsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-x64@npm:0.25.9" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -2236,9 +2700,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-arm64@npm:0.25.8" +"@esbuild/linux-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm64@npm:0.25.9" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -2264,9 +2728,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-arm@npm:0.25.8" +"@esbuild/linux-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm@npm:0.25.9" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -2292,9 +2756,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-ia32@npm:0.25.8" +"@esbuild/linux-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ia32@npm:0.25.9" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2320,9 +2784,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-loong64@npm:0.25.8" +"@esbuild/linux-loong64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-loong64@npm:0.25.9" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -2348,9 +2812,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-mips64el@npm:0.25.8" +"@esbuild/linux-mips64el@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-mips64el@npm:0.25.9" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -2376,9 +2840,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-ppc64@npm:0.25.8" +"@esbuild/linux-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ppc64@npm:0.25.9" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -2404,9 +2868,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-riscv64@npm:0.25.8" +"@esbuild/linux-riscv64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-riscv64@npm:0.25.9" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -2432,9 +2896,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-s390x@npm:0.25.8" +"@esbuild/linux-s390x@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-s390x@npm:0.25.9" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -2460,9 +2924,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/linux-x64@npm:0.25.8" +"@esbuild/linux-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-x64@npm:0.25.9" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -2474,9 +2938,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/netbsd-arm64@npm:0.25.8" +"@esbuild/netbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-arm64@npm:0.25.9" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard @@ -2502,9 +2966,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/netbsd-x64@npm:0.25.8" +"@esbuild/netbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-x64@npm:0.25.9" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -2516,9 +2980,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/openbsd-arm64@npm:0.25.8" +"@esbuild/openbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-arm64@npm:0.25.9" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -2544,16 +3008,16 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/openbsd-x64@npm:0.25.8" +"@esbuild/openbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-x64@npm:0.25.9" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openharmony-arm64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/openharmony-arm64@npm:0.25.8" +"@esbuild/openharmony-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openharmony-arm64@npm:0.25.9" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard @@ -2579,9 +3043,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/sunos-x64@npm:0.25.8" +"@esbuild/sunos-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/sunos-x64@npm:0.25.9" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -2607,9 +3071,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/win32-arm64@npm:0.25.8" +"@esbuild/win32-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-arm64@npm:0.25.9" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -2635,9 +3099,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/win32-ia32@npm:0.25.8" +"@esbuild/win32-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-ia32@npm:0.25.9" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -2663,21 +3127,21 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.25.8": - version: 0.25.8 - resolution: "@esbuild/win32-x64@npm:0.25.8" +"@esbuild/win32-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-x64@npm:0.25.9" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.7.0 - resolution: "@eslint-community/eslint-utils@npm:4.7.0" + version: 4.9.0 + resolution: "@eslint-community/eslint-utils@npm:4.9.0" dependencies: eslint-visitor-keys: ^3.4.3 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: b177e3b75c0b8d0e5d71f1c532edb7e40b31313db61f0c879f9bf19c3abb2783c6c372b5deb2396dab4432f2946b9972122ac682e77010376c029dfd0149c681 + checksum: ae9b98eea006d1354368804b0116b8b45017a4e47b486d1b9cfa048a8ed3dc69b9b074eb2b2acb14034e6897c24048fd42b6a6816d9dc8bb9daad79db7d478d2 languageName: node linkType: hard @@ -2738,25 +3202,25 @@ __metadata: languageName: node linkType: hard -"@floating-ui/dom@npm:^1.7.3": - version: 1.7.3 - resolution: "@floating-ui/dom@npm:1.7.3" +"@floating-ui/dom@npm:^1.7.4": + version: 1.7.4 + resolution: "@floating-ui/dom@npm:1.7.4" dependencies: "@floating-ui/core": ^1.7.3 "@floating-ui/utils": ^0.2.10 - checksum: 37a02ed991f0c580ba65bb67040656bbe45b0331fc8ebe35fdf7bacb13555641e1260d18599d5c1eb81ca0479873b18f15f2288e928d52cf8908efc154de989b + checksum: 806923e6f5b09e024c366070f2115a4db6e8ad28462bac29cd075170a6f7d900497da3ee542439bd0770b8e2fff12b636cc30873d1c82e9ec4a487870b080643 languageName: node linkType: hard "@floating-ui/react-dom@npm:^2.1.1": - version: 2.1.5 - resolution: "@floating-ui/react-dom@npm:2.1.5" + version: 2.1.6 + resolution: "@floating-ui/react-dom@npm:2.1.6" dependencies: - "@floating-ui/dom": ^1.7.3 + "@floating-ui/dom": ^1.7.4 peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 95bc27fcae10ebcaa7e9ee88dfa99b21e544e84f2b2e779655969e0fab224018c61a90d0ce9b7c82a5e4d55bbda08a3e8e475bca8022326a135bd80b256dfdb1 + checksum: 24ff266806cd4cba6ad066f0eda7b99583f68af877f41df0b2a8d10a392692e3a1c1d666ebb75571a060818ede940bae59d833aa517ed538f7dba9dddd9991ae languageName: node linkType: hard @@ -2838,23 +3302,23 @@ __metadata: linkType: hard "@inquirer/confirm@npm:^5.0.0": - version: 5.1.14 - resolution: "@inquirer/confirm@npm:5.1.14" + version: 5.1.16 + resolution: "@inquirer/confirm@npm:5.1.16" dependencies: - "@inquirer/core": ^10.1.15 + "@inquirer/core": ^10.2.0 "@inquirer/type": ^3.0.8 peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 18e56ca1a46bd7b03064cc01b467f9c699d0c27abdccafb14174192875d7a39a1802eb968386f33668303a28b0b1859dac07ac0323422c35a62f5a80a0987a7a + checksum: c81a1394125a68e47a82cd819392f9ee0dcbd736b49ab1907197e032718c2f8e03e31b5fdf65ca6f9b5d512155e8df19be9eca258e9c38ed3a36628a54584a2a languageName: node linkType: hard -"@inquirer/core@npm:^10.1.15": - version: 10.1.15 - resolution: "@inquirer/core@npm:10.1.15" +"@inquirer/core@npm:^10.2.0": + version: 10.2.0 + resolution: "@inquirer/core@npm:10.2.0" dependencies: "@inquirer/figures": ^1.0.13 "@inquirer/type": ^3.0.8 @@ -2869,7 +3333,7 @@ __metadata: peerDependenciesMeta: "@types/node": optional: true - checksum: 84b262dcdb7c4c800e65d79aa87b1c6449b2ccade5797a53e6e2d07d1f54db8bc4e3a529c87dfb20b5bb69f0dd46077582b2394aed1a44f3b79a67b402c990d3 + checksum: 8302712646d52e2bf210f7529143a0422cb706979d1d7f344557a2f78773457d6c9ac0aba04678b3fdf9c528dbce1c9e671636d06cf9d14da5b2e08bbf2a8356 languageName: node linkType: hard @@ -3234,12 +3698,22 @@ __metadata: linkType: hard "@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.12 - resolution: "@jridgewell/gen-mapping@npm:0.3.12" + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" dependencies: "@jridgewell/sourcemap-codec": ^1.5.0 "@jridgewell/trace-mapping": ^0.3.24 - checksum: 56ee1631945084897f274e65348afbaca7970ce92e3c23b3a23b2fe5d0d2f0c67614f0df0f2bb070e585e944bbaaf0c11cee3a36318ab8a36af46f2fd566bc40 + checksum: f2105acefc433337145caa3c84bba286de954f61c0bc46279bbd85a9e6a02871089717fa060413cfb6a9d44189fe8313b2d1cabf3a2eb3284d208fd5f75c54ff + languageName: node + linkType: hard + +"@jridgewell/remapping@npm:^2.3.5": + version: 2.3.5 + resolution: "@jridgewell/remapping@npm:2.3.5" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: 4a66a7397c3dc9c6b5c14a0024b1f98c5e1d90a0dbc1e5955b5038f2db339904df2a0ee8a66559fafb4fc23ff33700a2639fd40bbdd2e9e82b58b3bdf83738e3 languageName: node linkType: hard @@ -3251,19 +3725,19 @@ __metadata: linkType: hard "@jridgewell/source-map@npm:^0.3.3": - version: 0.3.10 - resolution: "@jridgewell/source-map@npm:0.3.10" + version: 0.3.11 + resolution: "@jridgewell/source-map@npm:0.3.11" dependencies: "@jridgewell/gen-mapping": ^0.3.5 "@jridgewell/trace-mapping": ^0.3.25 - checksum: 035d6e6df0e60744506b14033f1569fd5ddc269abeb68bf50c2911118e2a4fa50dab474d49a59a993e4ee6795c4ae5940381e0d09fc204972c5387788d22d010 + checksum: c8a0011cc67e701f270fa042e32b312f382c413bcc70ca9c03684687cbf5b64d5eed87d4afa36dddaabe60ab3da6db4935f878febd9cfc7f82724ea1a114d344 languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": - version: 1.5.4 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.4" - checksum: 959093724bfbc7c1c9aadc08066154f5c1f2acc647b45bd59beec46922cbfc6a9eda4a2114656de5bc00bb3600e420ea9a4cb05e68dcf388619f573b77bd9f0c +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: c2e36e67971f719a8a3a85ef5a5f580622437cc723c35d03ebd0c9c0b06418700ef006f58af742791f71f6a4fc68fcfaf1f6a74ec2f9a3332860e9373459dae7 languageName: node linkType: hard @@ -3278,12 +3752,12 @@ __metadata: linkType: hard "@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": - version: 0.3.29 - resolution: "@jridgewell/trace-mapping@npm:0.3.29" + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" dependencies: "@jridgewell/resolve-uri": ^3.1.0 "@jridgewell/sourcemap-codec": ^1.4.14 - checksum: 5e92eeafa5131a4f6b7122063833d657f885cb581c812da54f705d7a599ff36a75a4a093a83b0f6c7e95642f5772dd94753f696915e8afea082237abf7423ca3 + checksum: af8fda2431348ad507fbddf8e25f5d08c79ecc94594061ce402cf41bc5aba1a7b3e59bf0fd70a619b35f33983a3f488ceeba8faf56bff784f98bb5394a8b7d47 languageName: node linkType: hard @@ -3302,8 +3776,8 @@ __metadata: linkType: hard "@mswjs/interceptors@npm:^0.39.1": - version: 0.39.5 - resolution: "@mswjs/interceptors@npm:0.39.5" + version: 0.39.6 + resolution: "@mswjs/interceptors@npm:0.39.6" dependencies: "@open-draft/deferred-promise": ^2.2.0 "@open-draft/logger": ^0.3.0 @@ -3311,7 +3785,7 @@ __metadata: is-node-process: ^1.2.0 outvariant: ^1.4.3 strict-event-emitter: ^0.5.1 - checksum: ba555a9023a6e156feb195b4d47194aa8ae77b2e73affc7b378f97e9b9c77a8a29396c184e066b9d554fafbc0a092d6e70811916dfe8448f15c32857c9565241 + checksum: 4960ad247aeabdb6465754ab4646b6441032bdc26cef8c38696240cd3968e99533363f7e71f5d3f8f170b49456c2f1294920c28031327ea7d721320e3863b546 languageName: node linkType: hard @@ -3496,17 +3970,17 @@ __metadata: languageName: node linkType: hard -"@mui/types@npm:^7.2.15, @mui/types@npm:^7.2.17, @mui/types@npm:^7.4.5": - version: 7.4.5 - resolution: "@mui/types@npm:7.4.5" +"@mui/types@npm:^7.2.15, @mui/types@npm:^7.2.17, @mui/types@npm:^7.4.6": + version: 7.4.6 + resolution: "@mui/types@npm:7.4.6" dependencies: - "@babel/runtime": ^7.28.2 + "@babel/runtime": ^7.28.3 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 2468000bc1d003c1d1eb71e0537b8ed63b9dff96e077a7de31f7dd5db28f8b07f415e835240b5fd1b2d07ba5823283c90af7419a7d582496599717248103fcd5 + checksum: 7e4b4ae06066468e8a8211376d0a08250325f4b92f6d2ea24576df37dfcd0f683602567debdf15889e0e4510eb48d677aa0d71a2ed9423c16dbd4b4ecfbccbb9 languageName: node linkType: hard @@ -3563,11 +4037,11 @@ __metadata: linkType: hard "@mui/utils@npm:^5.16.6 || ^6.0.0 || ^7.0.0": - version: 7.3.1 - resolution: "@mui/utils@npm:7.3.1" + version: 7.3.2 + resolution: "@mui/utils@npm:7.3.2" dependencies: - "@babel/runtime": ^7.28.2 - "@mui/types": ^7.4.5 + "@babel/runtime": ^7.28.3 + "@mui/types": ^7.4.6 "@types/prop-types": ^15.7.15 clsx: ^2.1.1 prop-types: ^15.8.1 @@ -3578,7 +4052,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 2f4777b7bba142a78ce881682b0d012e341a38ec19f8c33ce82eadcab626ae032fb587e9ea9c75e5acf8cfd5eb53d2e70b424ab315d3421dab7c621835164ef9 + checksum: 201fb1f49434c3ee12de3a177660af04cb6411a68f8c13dc62ea828c522758b53040046daf2341b38da3b0a8a455ef4454a49cca4fa4e7b4d345d05e3ca61ecc languageName: node linkType: hard @@ -4131,142 +4605,149 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.46.2" +"@rollup/rollup-android-arm-eabi@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.50.1" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-android-arm64@npm:4.46.2" +"@rollup/rollup-android-arm64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-android-arm64@npm:4.50.1" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-darwin-arm64@npm:4.46.2" +"@rollup/rollup-darwin-arm64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.50.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-darwin-x64@npm:4.46.2" +"@rollup/rollup-darwin-x64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.50.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.46.2" +"@rollup/rollup-freebsd-arm64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.50.1" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-freebsd-x64@npm:4.46.2" +"@rollup/rollup-freebsd-x64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-freebsd-x64@npm:4.50.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.46.2" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.1" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.46.2" +"@rollup/rollup-linux-arm-musleabihf@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.50.1" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.46.2" +"@rollup/rollup-linux-arm64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.50.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.46.2" +"@rollup/rollup-linux-arm64-musl@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.50.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loongarch64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.46.2" +"@rollup/rollup-linux-loongarch64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.50.1" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-ppc64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.46.2" +"@rollup/rollup-linux-ppc64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.50.1" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.46.2" +"@rollup/rollup-linux-riscv64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.50.1" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.46.2" +"@rollup/rollup-linux-riscv64-musl@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.50.1" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.46.2" +"@rollup/rollup-linux-s390x-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.50.1" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.46.2" +"@rollup/rollup-linux-x64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.50.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.46.2" +"@rollup/rollup-linux-x64-musl@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.50.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.46.2" +"@rollup/rollup-openharmony-arm64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.50.1" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.50.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.46.2" +"@rollup/rollup-win32-ia32-msvc@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.50.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.46.2" +"@rollup/rollup-win32-x64-msvc@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.50.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4351,29 +4832,522 @@ __metadata: linkType: hard "@slack/types@npm:^2.9.0": - version: 2.15.0 - resolution: "@slack/types@npm:2.15.0" - checksum: 9c7e719d91fb206d936ab7802277141cbfeb55501ecc9f64d4b396b014ffc4fd9d1608ec957c24cf83212e5985542e1c87ec5ad5ae0abeddc00190a7a1d9b9b6 + version: 2.16.0 + resolution: "@slack/types@npm:2.16.0" + checksum: f1db2b8c18af245f78d5c178d98ed57fa5c8c18a1ea2e922bc0d330178a483ee7a29834b42a6710ece005789d91266d62195c93e8e2411ca707f8e438442c7f1 languageName: node linkType: hard "@slack/web-api@npm:^7.8.0": - version: 7.9.3 - resolution: "@slack/web-api@npm:7.9.3" + version: 7.10.0 + resolution: "@slack/web-api@npm:7.10.0" dependencies: "@slack/logger": ^4.0.0 "@slack/types": ^2.9.0 "@types/node": ">=18.0.0" "@types/retry": 0.12.0 - axios: ^1.8.3 + axios: ^1.11.0 eventemitter3: ^5.0.1 - form-data: ^4.0.0 + form-data: ^4.0.4 is-electron: 2.2.2 is-stream: ^2 p-queue: ^6 p-retry: ^4 retry: ^0.13.1 - checksum: a683d92496f0f654cc5e6e8daf6618d27b2a844ea9195ae49d689ae1602b1077920e960e19bb6f85dcd71106db0101d82037dd6b3202f41eddc9a605d90d5e75 + checksum: 6aa3f19892713c1efd5ec4dbca493f28725d185de478226b179cc9e8456c5fb7e38dc6092a5a93a6e4ce49e45a6cf2c287d18969b9563b52941db1e1679ecb96 + languageName: node + linkType: hard + +"@smithy/abort-controller@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/abort-controller@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: c05ba27366becd5ad6eddaf648e440efd51ac21c3721f3da8d03d977826a139cbe48f2c5f52be2ef3178c8692e899c568e7c1dba3724a92fbf248a65e3eeb15b + languageName: node + linkType: hard + +"@smithy/config-resolver@npm:^4.2.1": + version: 4.2.1 + resolution: "@smithy/config-resolver@npm:4.2.1" + dependencies: + "@smithy/node-config-provider": ^4.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-config-provider": ^4.1.0 + "@smithy/util-middleware": ^4.1.1 + tslib: ^2.6.2 + checksum: b993a32f4d89e4db6cf1e4ce58f26966a2ffb57fa47508997ce5c3b14dc75141fe980f418e41984f9c0df65d69bdf90bafcca06b33ad5ea62d79fea016153ce1 + languageName: node + linkType: hard + +"@smithy/core@npm:^3.11.0": + version: 3.11.0 + resolution: "@smithy/core@npm:3.11.0" + dependencies: + "@smithy/middleware-serde": ^4.1.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-stream": ^4.3.1 + "@smithy/util-utf8": ^4.1.0 + "@types/uuid": ^9.0.1 + tslib: ^2.6.2 + uuid: ^9.0.1 + checksum: 1e6274090961398776fbc5e00b93bc84d5fe2aff6bf0909c84d0a03a3e384db03d52bd9a7c147cc5834b9c9511db80121d09a3c81497405718d8cff20892ab02 + languageName: node + linkType: hard + +"@smithy/credential-provider-imds@npm:^4.0.7, @smithy/credential-provider-imds@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/credential-provider-imds@npm:4.1.1" + dependencies: + "@smithy/node-config-provider": ^4.2.1 + "@smithy/property-provider": ^4.1.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + tslib: ^2.6.2 + checksum: ae6faec4626d6cbe4e1a403761163309d4f225a18851b10e4b743556c7842ced69812fd7fd9873322596fae4465424342ab6d00a24231d5800b76483c3b0c896 + languageName: node + linkType: hard + +"@smithy/fetch-http-handler@npm:^5.2.1": + version: 5.2.1 + resolution: "@smithy/fetch-http-handler@npm:5.2.1" + dependencies: + "@smithy/protocol-http": ^5.2.1 + "@smithy/querystring-builder": ^4.1.1 + "@smithy/types": ^4.5.0 + "@smithy/util-base64": ^4.1.0 + tslib: ^2.6.2 + checksum: 68733a2d4a47002c9059af23078712ebc451dacca9542a3f6a70ba2288a017bb474a15ff6c10816c04296011c833d9ad8f957d22eedb33ea3a0edc12ad62160e + languageName: node + linkType: hard + +"@smithy/hash-node@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/hash-node@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + "@smithy/util-buffer-from": ^4.1.0 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: ee0d5ed0355d5551cc8805e55dcca582d75b062c15b5f1cde15a0376b3e0254ef4803a80f16f1c4125a985545e4fa99b4a7021199cc5ffa5457f829056962146 + languageName: node + linkType: hard + +"@smithy/invalid-dependency@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/invalid-dependency@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 039893fddde6786eb0c50c1a7c33768e9b052c5bc36c5ff1bec517290dab06f9e8ddf07323a3ef594f80b30fc4eaeb35bed1e0ef9b7aa9588aa99f169dd02ada + languageName: node + linkType: hard + +"@smithy/is-array-buffer@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/is-array-buffer@npm:2.2.0" + dependencies: + tslib: ^2.6.2 + checksum: cd12c2e27884fec89ca8966d33c9dc34d3234efe89b33a9b309c61ebcde463e6f15f6a02d31d4fddbfd6e5904743524ca5b95021b517b98fe10957c2da0cd5fc + languageName: node + linkType: hard + +"@smithy/is-array-buffer@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/is-array-buffer@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: 8ab4c920f9f9dc10dadcbc32fef439e9809da8065898ef05007c46c9d4a6494b512240cd25652b8be533f17aee0ce441c412fa0de535128ea7f8e610fda3acbd + languageName: node + linkType: hard + +"@smithy/middleware-content-length@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-content-length@npm:4.1.1" + dependencies: + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: e136bd0f2a95b6baba0d226289bfa430f2cad9180f952d4b8abda49362adbbe02cfed85726dd54d4be3f7e07196e6dffd1af56616ab922b1485571891dae3633 + languageName: node + linkType: hard + +"@smithy/middleware-endpoint@npm:^4.2.1": + version: 4.2.1 + resolution: "@smithy/middleware-endpoint@npm:4.2.1" + dependencies: + "@smithy/core": ^3.11.0 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/shared-ini-file-loader": ^4.1.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-middleware": ^4.1.1 + tslib: ^2.6.2 + checksum: c1da39fe173c8d88214bec6c57d7210d2aac682672b9e54228a8f15232bd884f7362e00177241c3e0015e68e16dafd04011284ad2bdb4c54c55661737df9b536 + languageName: node + linkType: hard + +"@smithy/middleware-retry@npm:^4.2.1": + version: 4.2.1 + resolution: "@smithy/middleware-retry@npm:4.2.1" + dependencies: + "@smithy/node-config-provider": ^4.2.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/service-error-classification": ^4.1.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-retry": ^4.1.1 + "@types/uuid": ^9.0.1 + tslib: ^2.6.2 + uuid: ^9.0.1 + checksum: 3d1e723f90cb11b9c118cce7a55e30dca84db6e752b6d4abffb99acce3383a23063027774fec46ff7c2bc5b926cbe34d4cbfe4506d8aaa7606d8325a046dcd7c + languageName: node + linkType: hard + +"@smithy/middleware-serde@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-serde@npm:4.1.1" + dependencies: + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: e0f6d3895ec83b2e70a8282d058c1862d73ed4d6a2ca878cda6c97b439e52bf3df3f3b4c44e7749262cdf87e5e7c30d10f1fb081ade79689cf0ac17061cf447b + languageName: node + linkType: hard + +"@smithy/middleware-stack@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-stack@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 9046afc321356a8d26d1db41a700a5ac0d9d370d561725c0bb9239db7aaa2ad02b3747998da6497238a3c4bd7169cbbf8bd4936c123f0fc219c4b17611a663ea + languageName: node + linkType: hard + +"@smithy/node-config-provider@npm:^4.2.1": + version: 4.2.1 + resolution: "@smithy/node-config-provider@npm:4.2.1" + dependencies: + "@smithy/property-provider": ^4.1.1 + "@smithy/shared-ini-file-loader": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 0750bc5d6a1e29eec83c842642fb1a2b2918f4700cfe741139e9f2bd84da8a76f194d3308000731397b73bcc79fa67614029faea8beed928fd1223002b9444de + languageName: node + linkType: hard + +"@smithy/node-http-handler@npm:^4.2.1": + version: 4.2.1 + resolution: "@smithy/node-http-handler@npm:4.2.1" + dependencies: + "@smithy/abort-controller": ^4.1.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/querystring-builder": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 93d006a5908b41cf8bb9b4564c4f2274825db44755dd6949490405e859419cba73afd6c34de93a4e2ee4ef7cc2524a91853fbcca16261ab302b1bd08e73694c9 + languageName: node + linkType: hard + +"@smithy/property-provider@npm:^4.0.5, @smithy/property-provider@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/property-provider@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 0173716227d82d50845121202dc157dd23e75786d3ab994ea91666e2441a66c972c27e71d67992688a10b7ca4e988a7b809668d20c0c35a66a39c824842fd6ee + languageName: node + linkType: hard + +"@smithy/protocol-http@npm:^5.2.1": + version: 5.2.1 + resolution: "@smithy/protocol-http@npm:5.2.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 6a8509a7fd38a039e6db10d372f0698ea841fe73c49cb7f03a7718ff2b5e60776f4f3a9d7658020f9ad981917ce46e40d7d38fbd8675330031d6483ef3aafc42 + languageName: node + linkType: hard + +"@smithy/querystring-builder@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/querystring-builder@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + "@smithy/util-uri-escape": ^4.1.0 + tslib: ^2.6.2 + checksum: 01d7ff1a21547a8a7e687ebcb7f2b9c94c8cd62403e1c5e88fab340c7e5bc11162e66b08d1b75876c7221e352272e33dd2066a19e270171f8eb63bbf6a1d92a6 + languageName: node + linkType: hard + +"@smithy/querystring-parser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/querystring-parser@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: b70f09e2a778a6037d9ff3e9c67707d4744dba4d0f760b9e79a0d4469ff6f68d493d1c3d4104441de040cf8ab6e15acc06ae5dbba7a30a418306af3771117cba + languageName: node + linkType: hard + +"@smithy/service-error-classification@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/service-error-classification@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + checksum: 7d8bc8fa9faf4047b8386e45e74f033feedd8824483ab8ab9a37046405a6a5c15cf66d1f7e32a179336b415974d1b55b750727c823d55b288618793dfefb0633 + languageName: node + linkType: hard + +"@smithy/shared-ini-file-loader@npm:^4.0.5, @smithy/shared-ini-file-loader@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/shared-ini-file-loader@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: ee5262e6134d391145f4ad91e43997ee8aaf73ce46b1b38b715edbfb4576a01b0f2828e3710402fcbb19ef86332cb1d432f502c95b14978e617bba7ad3d2b93f + languageName: node + linkType: hard + +"@smithy/signature-v4@npm:^5.1.3": + version: 5.2.1 + resolution: "@smithy/signature-v4@npm:5.2.1" + dependencies: + "@smithy/is-array-buffer": ^4.1.0 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-hex-encoding": ^4.1.0 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-uri-escape": ^4.1.0 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: d609451fead77465d04b3d2fb614cfd51c5c66020429ecf97c871952e70d0cacb9d4ff8b15271cc7b38fcfa852b3d141e1811804ecab0eb522cadb9d43f3c10c + languageName: node + linkType: hard + +"@smithy/smithy-client@npm:^4.6.1": + version: 4.6.1 + resolution: "@smithy/smithy-client@npm:4.6.1" + dependencies: + "@smithy/core": ^3.11.0 + "@smithy/middleware-endpoint": ^4.2.1 + "@smithy/middleware-stack": ^4.1.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-stream": ^4.3.1 + tslib: ^2.6.2 + checksum: 22aa3b67f91e5cf509f157605144fd1e937b3d19c1bb40c8e65e4e2d2c53a80f22082d94c24279d70ae60547b21d93fffb44fb9c09244793c746c5001e6db9ec + languageName: node + linkType: hard + +"@smithy/types@npm:^4.5.0": + version: 4.5.0 + resolution: "@smithy/types@npm:4.5.0" + dependencies: + tslib: ^2.6.2 + checksum: 5fb38dcf554e8ecf3654cbcc295fffcf35517f7e792ed158f4119223982f57d4e3ec79ad56e8e9a590c8843990bef217da8a88e02e197ee7f6d4737abcc9c075 + languageName: node + linkType: hard + +"@smithy/url-parser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/url-parser@npm:4.1.1" + dependencies: + "@smithy/querystring-parser": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 189d60c99b3610bb4be2f32474551e4431273891093232f38553a27541ba1379df70a625b83390f259aafbddb3307e531b8210148c854eb39763e2d0e5ec3769 + languageName: node + linkType: hard + +"@smithy/util-base64@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-base64@npm:4.1.0" + dependencies: + "@smithy/util-buffer-from": ^4.1.0 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: 8855de07897631f835fc47b9c17938a5e927291ce6ef08cfd1424431333fc4c4797c18e2094790c5331388f39bd5ed0a76a913e9b7f3c7f61c0e228bf18a3cf9 + languageName: node + linkType: hard + +"@smithy/util-body-length-browser@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-body-length-browser@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: 7aa162eb084ffeb7b0b6d504494e248e7da72447f08cda02120d5594ddb146544dcee19b92d6e57dc3115372e2ce018147692e44c7cb1498f634a3fa17d22aa9 + languageName: node + linkType: hard + +"@smithy/util-body-length-node@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-body-length-node@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: dfaf22fd6fc086544f582dd5c64a4416c01bad8b92f5891add84b9086a9b0a8815659269c91b8adee7ef3b36f21701c6aaab2313bfbe21a2c189eb15943a0c25 + languageName: node + linkType: hard + +"@smithy/util-buffer-from@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-buffer-from@npm:2.2.0" + dependencies: + "@smithy/is-array-buffer": ^2.2.0 + tslib: ^2.6.2 + checksum: 424c5b7368ae5880a8f2732e298d17879a19ca925f24ca45e1c6c005f717bb15b76eb28174d308d81631ad457ea0088aab0fd3255dd42f45a535c81944ad64d3 + languageName: node + linkType: hard + +"@smithy/util-buffer-from@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-buffer-from@npm:4.1.0" + dependencies: + "@smithy/is-array-buffer": ^4.1.0 + tslib: ^2.6.2 + checksum: a8523e142cfa8a5526ada1bb2f4264c7dc6027875a16752995324c294ea6b2bd502303db16ac74eb49fe602f20d847cdb09054d611e3aa9916c09b7a41e379c0 + languageName: node + linkType: hard + +"@smithy/util-config-provider@npm:^4.0.0, @smithy/util-config-provider@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-config-provider@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: 8d13ec9246b05bc3b8af9312ba53d266cb9fff6400957630e3288ed1807c6fb433a7383df385282b84f699f112653069008b9c972e520393a4fed88d19a2e8e3 + languageName: node + linkType: hard + +"@smithy/util-defaults-mode-browser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-defaults-mode-browser@npm:4.1.1" + dependencies: + "@smithy/property-provider": ^4.1.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: d11a05ecfa89b8ea68d991d925b6799e0b52ae80a3e7e319d41365d1f3ee7852321f84f60997fbd343ef3f51b0148c2b5777e886912f7426b74fd4867d132744 + languageName: node + linkType: hard + +"@smithy/util-defaults-mode-node@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-defaults-mode-node@npm:4.1.1" + dependencies: + "@smithy/config-resolver": ^4.2.1 + "@smithy/credential-provider-imds": ^4.1.1 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/property-provider": ^4.1.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: e28e0febb781f033ff9715e6e17ba0c228507238145ac9c81735c22d3fbff193f42ca2f281cf4fa8a954f1ea629b4ab867a3bae634a92df65ec254498624157a + languageName: node + linkType: hard + +"@smithy/util-endpoints@npm:^3.1.1": + version: 3.1.1 + resolution: "@smithy/util-endpoints@npm:3.1.1" + dependencies: + "@smithy/node-config-provider": ^4.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 8c455e689f915c3cd1608f07e0e0e225d6a2eb0d777afb5a950a6332af8928c2688b9089dd56a15dbe3fff52da5f4532b8d630f4abb3a2b934ca01b701e44821 + languageName: node + linkType: hard + +"@smithy/util-hex-encoding@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-hex-encoding@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: 0005c0569a18edc9a6fe991acca95c35e1bfecaf7bb4a9ed2a54eed249e7ccc3662c7d5e3c995db5c47dece9841690f56c4cb93b5adc8681c9436dd7cb8ebff5 + languageName: node + linkType: hard + +"@smithy/util-middleware@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-middleware@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 9f8dc9f29730f70c0575920f9f88073af0c8359e1e0a4114a60834cf1053f6ee8df687814f8f4f9b87a02a591a2a3592ffa2b0d7b93234309fe1cdc52cd51e3a + languageName: node + linkType: hard + +"@smithy/util-retry@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-retry@npm:4.1.1" + dependencies: + "@smithy/service-error-classification": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 7ed26ae7b9cd810752f692c749bb8ad083c8fd5000cfd00c9c917806156486b84afb7b8fcf968395b84b3552a6bf46562ec479b97ab4f0cb9d4b121958f1cd5f + languageName: node + linkType: hard + +"@smithy/util-stream@npm:^4.3.1": + version: 4.3.1 + resolution: "@smithy/util-stream@npm:4.3.1" + dependencies: + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-buffer-from": ^4.1.0 + "@smithy/util-hex-encoding": ^4.1.0 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: a1b73d9f39811065729bd7304a6deaceea99ddb2f736fb5b95c20d3db53f84e4e53f956c358d95fa747967488b2193b581e96ed75d841164cdb5176fef928eb8 + languageName: node + linkType: hard + +"@smithy/util-uri-escape@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-uri-escape@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: 0c55f4981af8be1a67fdd154497d41b3ea130da2a409b06a5e899d5f86b498fe4e5b9c065ee018379b976d74ae9aaf45180548e0d96bf7e474fb039da667aac6 + languageName: node + linkType: hard + +"@smithy/util-utf8@npm:^2.0.0": + version: 2.3.0 + resolution: "@smithy/util-utf8@npm:2.3.0" + dependencies: + "@smithy/util-buffer-from": ^2.2.0 + tslib: ^2.6.2 + checksum: 00e55d4b4e37d48be0eef3599082402b933c52a1407fed7e8e8ad76d94d81a0b30b8bfaf2047c59d9c3af31e5f20e7a8c959cb7ae270f894255e05a2229964f0 + languageName: node + linkType: hard + +"@smithy/util-utf8@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-utf8@npm:4.1.0" + dependencies: + "@smithy/util-buffer-from": ^4.1.0 + tslib: ^2.6.2 + checksum: 3a5a1420a5f06bfcc1c15935344f245ea5d297c0d021c52589cb7125fe5a3546e69cedf37940fd84962405116d59c81f56d1adb463105715f4b534f0fe3bf9db + languageName: node + linkType: hard + +"@smithy/util-waiter@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-waiter@npm:4.1.1" + dependencies: + "@smithy/abort-controller": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: f4d16ee1cbcc34a2519e835f70b4e3430fe1bbff611e30951ea83ed997ee6a6c01a3189e4e8c8c2bae441520622f03c6324bd4decac77b02f7001637f26cf83a languageName: node linkType: hard @@ -4537,17 +5511,16 @@ __metadata: linkType: hard "@testing-library/jest-dom@npm:^6.6.3": - version: 6.6.4 - resolution: "@testing-library/jest-dom@npm:6.6.4" + version: 6.8.0 + resolution: "@testing-library/jest-dom@npm:6.8.0" dependencies: "@adobe/css-tools": ^4.4.0 aria-query: ^5.0.0 css.escape: ^1.5.1 dom-accessibility-api: ^0.6.3 - lodash: ^4.17.21 picocolors: ^1.1.1 redent: ^3.0.0 - checksum: 45c8be7b4a577d926210ff10a444dcc5a40132ff6865512406b76c2768d0530c0b3c4d6babccf97c63108bd8b59d1fab58fab08b02452d286be76320323d91be + checksum: a3cfb162b6ec6e98277187d9488234ba3e3ee25f24a86facdae092dbe54a015c845bcb81daa6de7afadcac5a5fe25becd7c7e9b67bb01ee4ccf7d67ee907adc9 languageName: node linkType: hard @@ -4781,9 +5754,9 @@ __metadata: linkType: hard "@types/d3-array@npm:^3.0.3": - version: 3.2.1 - resolution: "@types/d3-array@npm:3.2.1" - checksum: 8a41cee0969e53bab3f56cc15c4e6c9d76868d6daecb2b7d8c9ce71e0ececccc5a8239697cc52dadf5c665f287426de5c8ef31a49e7ad0f36e8846889a383df4 + version: 3.2.2 + resolution: "@types/d3-array@npm:3.2.2" + checksum: 72e8e2abe0911cb431d6f3fe0a1f71b915356b679d4d9c826f52941bb30210c0fe8299dde066b08d9986754c620f031b13b13ab6dfc60d404eceab66a075dd5d languageName: node linkType: hard @@ -5153,20 +6126,20 @@ __metadata: linkType: hard "@types/node-forge@npm:^1.3.0": - version: 1.3.13 - resolution: "@types/node-forge@npm:1.3.13" + version: 1.3.14 + resolution: "@types/node-forge@npm:1.3.14" dependencies: "@types/node": "*" - checksum: dee446d958e7098c8ad74076843d27cb46908632cf289f732ccc5c0a2c1e62927df44d22725bd37a84579ea3336e52b4c064385c53e22b741e277d07c9da20cb + checksum: ff621803390e723e56b289a89fca3a06f9f8b438add1b843203a0f64bcbc7ac03d457136b3c15010b5bc89d81f57b35f62964e6e980f6290597bb21b4463c009 languageName: node linkType: hard "@types/node@npm:*, @types/node@npm:>=18.0.0": - version: 24.2.1 - resolution: "@types/node@npm:24.2.1" + version: 24.3.3 + resolution: "@types/node@npm:24.3.3" dependencies: undici-types: ~7.10.0 - checksum: d7a12a35bcb6ade13787bd9b40d8f59b96170f228dfbd19326170b4df2a66ae86cf21eec6867e92f979405235431e580a9668b167aa3ce8e89531c00792551d3 + checksum: b67244aa37ab53690ac6f3565f06ad2e3ca5fae78ef3f60431e1c78e014426106643d3dc31d6f00b62aa8051cd1360178cafb6ce6a49afa5dcecba8339e23462 languageName: node linkType: hard @@ -5192,20 +6165,21 @@ __metadata: linkType: hard "@types/node@npm:^20.0.0": - version: 20.19.10 - resolution: "@types/node@npm:20.19.10" + version: 20.19.14 + resolution: "@types/node@npm:20.19.14" dependencies: undici-types: ~6.21.0 - checksum: e294ec0d37ce5a1ae9e4c255ef837b584d793a4d2f89472d580024a4c008de0d5df595c919e96e95fcdf56bf55d567213f90c0c5874b369a30526bedfaa3f418 + checksum: a19533f35718cfb543caa33a65abe020bf6ca9e8ae1db0b6802df152adcdc7d00a3793e811c89b5b51c1d0f4ee32e6650f1ed21e0f49948e4d36c849b5a2917a languageName: node linkType: hard "@types/nodemailer@npm:^6.4.0": - version: 6.4.17 - resolution: "@types/nodemailer@npm:6.4.17" + version: 6.4.19 + resolution: "@types/nodemailer@npm:6.4.19" dependencies: + "@aws-sdk/client-ses": ^3.731.1 "@types/node": "*" - checksum: 498b702575111494a42cf9cdd3d399f0308c3b3b0244e7f53008924327955a16b39ba0bf99a5ccf17af9fd2bc50a61a76ae7e8a75498a426ea2f828a05202eab + checksum: 7f449db31d8c0b150da554158e04d9fd631832ff2c01cc7c906ec9619a5295d7f525db959bfd3fc0eb451f386dd052ddbcbe1a337e3f776a3d9d554701a9df53 languageName: node linkType: hard @@ -5335,9 +6309,9 @@ __metadata: linkType: hard "@types/semver@npm:^7.3.12": - version: 7.7.0 - resolution: "@types/semver@npm:7.7.0" - checksum: d488eaeddb23879a0a8a759bed667e1a76cb0dd4d23e3255538e24c189db387357953ca9e7a3bda2bb7f95e84cac8fe0db4fbe6b3456e893043337732d1d23cc + version: 7.7.1 + resolution: "@types/semver@npm:7.7.1" + checksum: 76d218e414482a398148d5c28f2bfa017108869f3fc18cda379c9d8d062348f8b9653ae2fa8642d3b5b52e211928fe8be34f22da4e1f08245c84e0e51e040673 languageName: node linkType: hard @@ -5415,13 +6389,6 @@ __metadata: languageName: node linkType: hard -"@types/tough-cookie@npm:^4.0.5": - version: 4.0.5 - resolution: "@types/tough-cookie@npm:4.0.5" - checksum: f19409d0190b179331586365912920d192733112a195e870c7f18d20ac8adb7ad0b0ff69dad430dba8bc2be09593453a719cfea92dc3bda19748fd158fe1498d - languageName: node - linkType: hard - "@types/trusted-types@npm:^2.0.2": version: 2.0.7 resolution: "@types/trusted-types@npm:2.0.7" @@ -5457,6 +6424,13 @@ __metadata: languageName: node linkType: hard +"@types/uuid@npm:^9.0.1": + version: 9.0.8 + resolution: "@types/uuid@npm:9.0.8" + checksum: b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 + languageName: node + linkType: hard + "@types/ws@npm:^8.5.5": version: 8.18.1 resolution: "@types/ws@npm:8.18.1" @@ -6183,7 +7157,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.9.0": +"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.9.0": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -6325,9 +7299,9 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.1.0 - resolution: "ansi-regex@npm:6.1.0" - checksum: 495834a53b0856c02acd40446f7130cb0f8284f4a39afdab20d5dc42b2e198b1196119fe887beed8f9055c4ff2055e3b2f6d4641d0be018cdfb64fedf6fc1aac + version: 6.2.2 + resolution: "ansi-regex@npm:6.2.2" + checksum: 9b17ce2c6daecc75bcd5966b9ad672c23b184dc3ed9bf3c98a0702f0d2f736c15c10d461913568f2cf527a5e64291c7473358885dd493305c84a1cfed66ba94f languageName: node linkType: hard @@ -6357,9 +7331,9 @@ __metadata: linkType: hard "ansi-styles@npm:^6.1.0": - version: 6.2.1 - resolution: "ansi-styles@npm:6.2.1" - checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 + version: 6.2.3 + resolution: "ansi-styles@npm:6.2.3" + checksum: f1b0829cf048cce870a305819f65ce2adcebc097b6d6479e12e955fd6225df9b9eb8b497083b764df796d94383ff20016cc4dbbae5b40f36138fb65a9d33c2e2 languageName: node linkType: hard @@ -6667,14 +7641,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.7.9, axios@npm:^1.8.3": - version: 1.11.0 - resolution: "axios@npm:1.11.0" +"axios@npm:^1.11.0, axios@npm:^1.7.9": + version: 1.12.1 + resolution: "axios@npm:1.12.1" dependencies: follow-redirects: ^1.15.6 form-data: ^4.0.4 proxy-from-env: ^1.1.0 - checksum: 0a33dc600b588bfd3111b198d5985527ed89f722817455d7cdb66c1d055e5f8859cc2bebb7320888957fc8458ebe77d5f83af02af9cd260217c91c4e92b6dfb6 + checksum: 5160cf4e319ecd22de2bc4ad263881b5fb4cea1dfd9b8032ce349609fff041e0434f14e72bf2571b37ea88d1860f3456a95f3f40f2c14e84edfb6e81e5f27c4d languageName: node linkType: hard @@ -6930,6 +7904,15 @@ __metadata: languageName: node linkType: hard +"baseline-browser-mapping@npm:^2.8.2": + version: 2.8.3 + resolution: "baseline-browser-mapping@npm:2.8.3" + bin: + baseline-browser-mapping: dist/cli.js + checksum: 5b68bebb5ff1e2266e9252fdf13f23679ebd3b884cc4165a7257e6a09c5fdc51a1fb98bac24a78e3bf7c429f7a4c05743733e6255f0a6403ace8e6fcefd2ed53 + languageName: node + linkType: hard + "batch@npm:0.6.1": version: 0.6.1 resolution: "batch@npm:0.6.1" @@ -7051,11 +8034,18 @@ __metadata: linkType: hard "bootstrap@npm:^5.3.0": - version: 5.3.7 - resolution: "bootstrap@npm:5.3.7" + version: 5.3.8 + resolution: "bootstrap@npm:5.3.8" peerDependencies: "@popperjs/core": ^2.11.8 - checksum: ac3ebcbdd37caed60cf515953a007af31265548271471ab1aff070cd4ad2aa3ec215b25144b3172882953ad107fe04548fe0bb6c71fcde95153b8605c564173c + checksum: 6813254a1140646ca53f33f2d0c5fbf7cf544dabba06cddc061243acf4ec71fadff348860ed4623e1b486c05c151d7807da017dc473e748add0926d2cf9f1a04 + languageName: node + linkType: hard + +"bowser@npm:^2.11.0": + version: 2.12.1 + resolution: "bowser@npm:2.12.1" + checksum: 994a3da9e9b628892e0fbc4fd5afeec672003a9a72300ec8ac832f6707ba6ce68d137d50316f08e6197f9e0cca5c486aa4b9ce9db50013061225cab4e432f8a0 languageName: node linkType: hard @@ -7110,17 +8100,18 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.25.1": - version: 4.25.2 - resolution: "browserslist@npm:4.25.2" +"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.25.3": + version: 4.26.0 + resolution: "browserslist@npm:4.26.0" dependencies: - caniuse-lite: ^1.0.30001733 - electron-to-chromium: ^1.5.199 - node-releases: ^2.0.19 + baseline-browser-mapping: ^2.8.2 + caniuse-lite: ^1.0.30001741 + electron-to-chromium: ^1.5.218 + node-releases: ^2.0.21 update-browserslist-db: ^1.1.3 bin: browserslist: cli.js - checksum: 104f151563a797f95cda7ae862938939c41b89975960cba4615a389238cdd98dcf2ec4ea804c97374c39457f1f476bc58cfd2826fdccff5dba91e2ca45f5b1b3 + checksum: 7188de936499e7a68234c740f10fd5167191d7a033964f572201d4df71919997c8ba1053027f066e8c01189df06840a1570b35e871796fd87fcb05141e8428f2 languageName: node linkType: hard @@ -7300,21 +8291,21 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001733": - version: 1.0.30001733 - resolution: "caniuse-lite@npm:1.0.30001733" - checksum: cf9d0701ef5617231072be7db74a077ac7a453c8672fe0f17df14aee73f8f253b42cd0d95e1f150ff73453edb115b7131e98b416070b798c8f41b25606f15292 +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001741": + version: 1.0.30001741 + resolution: "caniuse-lite@npm:1.0.30001741" + checksum: 0f2e90e1418a0b35923735420a0a0f9d2aa91eb6e0e2ae955e386155b402892ed4aa9996aae644b9f0cf2cf6a2af52c9467d4f8fc1d1710e8e4c961f12bdec67 languageName: node linkType: hard "canvas@npm:^3.0.0-rc2": - version: 3.1.2 - resolution: "canvas@npm:3.1.2" + version: 3.2.0 + resolution: "canvas@npm:3.2.0" dependencies: node-addon-api: ^7.0.0 node-gyp: latest prebuild-install: ^7.1.3 - checksum: 12de08247fb90f9e442ea4c04b47dffac0b66a58587619bc354495195168063d8d1a870c52bd35b17a95697bb0e99c4cb562d9fc9752bf11b7ba2e5b81eb5ba9 + checksum: 68c7fe3c0c79efb3358d4ab4b04586068fefe06c7137e6636111ae91e68122ac069f05d883fdf11eb7fd08eba841096cb700324d02efca7abbf92d3476c567e4 languageName: node linkType: hard @@ -7344,15 +8335,15 @@ __metadata: linkType: hard "chai@npm:^5.1.2, chai@npm:^5.2.0": - version: 5.2.1 - resolution: "chai@npm:5.2.1" + version: 5.3.3 + resolution: "chai@npm:5.3.3" dependencies: assertion-error: ^2.0.1 check-error: ^2.1.1 deep-eql: ^5.0.1 loupe: ^3.1.0 pathval: ^2.0.0 - checksum: 15e2923de73bc4a361fa016b3322c8258c1ec7a33794f6dfa8000b4cd7fb64521363e59fcf08b90b9dd2d787b25ac9e2420535ce31c530501296d4bc03b48576 + checksum: bc4091f1cccfee63f6a3d02ce477fe847f5c57e747916a11bd72675c9459125084e2e55dc2363ee2b82b088a878039ee7ee27c75d6d90f7de9202bf1b12ce573 languageName: node linkType: hard @@ -7796,20 +8787,19 @@ __metadata: linkType: hard "concurrently@npm:^9.1.0": - version: 9.2.0 - resolution: "concurrently@npm:9.2.0" + version: 9.2.1 + resolution: "concurrently@npm:9.2.1" dependencies: - chalk: ^4.1.2 - lodash: ^4.17.21 - rxjs: ^7.8.1 - shell-quote: ^1.8.1 - supports-color: ^8.1.1 - tree-kill: ^1.2.2 - yargs: ^17.7.2 + chalk: 4.1.2 + rxjs: 7.8.2 + shell-quote: 1.8.3 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 bin: conc: dist/bin/concurrently.js concurrently: dist/bin/concurrently.js - checksum: a138458968c791e0c5719771d3181c5add8b865beebf19fae43365ab4d49ac79de634de29ef150697e3aaf1145f27dcf634910bdc2bcb779c5dd92621607b854 + checksum: 95c6cdde21b6304d53005d872318805f69e153d4cedfd4d720cc5776f56fbd073b38297cfe56bacfc8fbdba9b6c38ac1233739abd25b023761fd03b896a4cea5 languageName: node linkType: hard @@ -7923,25 +8913,25 @@ __metadata: linkType: hard "core-js-compat@npm:^3.43.0": - version: 3.45.0 - resolution: "core-js-compat@npm:3.45.0" + version: 3.45.1 + resolution: "core-js-compat@npm:3.45.1" dependencies: - browserslist: ^4.25.1 - checksum: 98808620626b761eb4772cb8719d959289e9a9127d4fd4d2e3e78aa8341c4935bdc395883134c9419f718776222c0d3eda1ae2337e67e171388e4547d3097b51 + browserslist: ^4.25.3 + checksum: 817286f6b7deb90278fd1f46131664fda36b74983e2fc4859a36ae85ef9361868b307964eea0e364251763e415eab7589e9abe2a4ec4d1672c2870f03c52b1ac languageName: node linkType: hard "core-js-pure@npm:^3.23.3": - version: 3.45.0 - resolution: "core-js-pure@npm:3.45.0" - checksum: 2a53eff76a3ba609ba57a82cca08f8832cc4e68fbca08b449361c4fcf319534d1e83ca534305212d113c311d38c37c30a6ac473f295df43836db405a0404cfd8 + version: 3.45.1 + resolution: "core-js-pure@npm:3.45.1" + checksum: 7427bc4c8991acabc537bc30da5da9e7afb12754c7cf59d5271b01d1750d4b216c44e2ea298b4354efa83873eeeff62e71d858e5c9cd0a3a69fea933971a6a8d languageName: node linkType: hard "core-js@npm:^3.19.2": - version: 3.45.0 - resolution: "core-js@npm:3.45.0" - checksum: 05706def467637c0392cb3d37d9e29714070d53feceea2715b4c805f9d55a62caac5d9f40c679a5f56e7fed4198a0e923392c704140fd617c111b239968d5bf1 + version: 3.45.1 + resolution: "core-js@npm:3.45.1" + checksum: 674c79e9c58ed923280cd4afbc3bc4c921b8b11bce70d269f1bd98db484e27f0ff436d1de34e198f27065a10386761b39f110309c471f329fe7376ab0fb32bf6 languageName: node linkType: hard @@ -8467,9 +9457,9 @@ __metadata: linkType: hard "dayjs@npm:^1.11.10": - version: 1.11.13 - resolution: "dayjs@npm:1.11.13" - checksum: f388db88a6aa93956c1f6121644e783391c7b738b73dbc54485578736565c8931bdfba4bb94e9b1535c6e509c97d5deb918bbe1ae6b34358d994de735055cca9 + version: 1.11.18 + resolution: "dayjs@npm:1.11.18" + checksum: cc90054bad30ab011417a7a474b2ffa70e7a28ca6f834d7e86fe53a408a40a14c174f26155072628670e9eda4c48c4ed0d847d2edf83d47c0bfb78be15bbf2dd languageName: node linkType: hard @@ -8483,14 +9473,14 @@ __metadata: linkType: hard "debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": - version: 4.4.1 - resolution: "debug@npm:4.4.1" + version: 4.4.3 + resolution: "debug@npm:4.4.3" dependencies: ms: ^2.1.3 peerDependenciesMeta: supports-color: optional: true - checksum: a43826a01cda685ee4cec00fb2d3322eaa90ccadbef60d9287debc2a886be3e835d9199c80070ede75a409ee57828c4c6cd80e4b154f2843f0dc95a570dc0729 + checksum: 4805abd570e601acdca85b6aa3757186084a45cff9b2fa6eee1f3b173caa776b45f478b2a71a572d616d2010cea9211d0ac4a02a610e4c18ac4324bde3760834 languageName: node linkType: hard @@ -8973,10 +9963,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.199": - version: 1.5.199 - resolution: "electron-to-chromium@npm:1.5.199" - checksum: e34ec35366a083b54dd489a23d2e7d7bf21f2971cf52a9f47bc63a64fdbc53adda1c4e15bd7bb33648f045e9f251fc9585e47651f760fdc11b4e9fb793b419ce +"electron-to-chromium@npm:^1.5.218": + version: 1.5.218 + resolution: "electron-to-chromium@npm:1.5.218" + checksum: 869953636f9d7ff865c827a65e3a8e5f2b4162f1ba58389d93e19f2c945001a2e5925d2c29b49af57c2ddbbf75c6205d01d472bf0d54085c42d606b97fd76eab languageName: node linkType: hard @@ -9047,7 +10037,7 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.17.2": +"enhanced-resolve@npm:^5.17.3": version: 5.18.3 resolution: "enhanced-resolve@npm:5.18.3" dependencies: @@ -9505,35 +10495,35 @@ __metadata: linkType: hard "esbuild@npm:^0.25.0": - version: 0.25.8 - resolution: "esbuild@npm:0.25.8" - dependencies: - "@esbuild/aix-ppc64": 0.25.8 - "@esbuild/android-arm": 0.25.8 - "@esbuild/android-arm64": 0.25.8 - "@esbuild/android-x64": 0.25.8 - "@esbuild/darwin-arm64": 0.25.8 - "@esbuild/darwin-x64": 0.25.8 - "@esbuild/freebsd-arm64": 0.25.8 - "@esbuild/freebsd-x64": 0.25.8 - "@esbuild/linux-arm": 0.25.8 - "@esbuild/linux-arm64": 0.25.8 - "@esbuild/linux-ia32": 0.25.8 - "@esbuild/linux-loong64": 0.25.8 - "@esbuild/linux-mips64el": 0.25.8 - "@esbuild/linux-ppc64": 0.25.8 - "@esbuild/linux-riscv64": 0.25.8 - "@esbuild/linux-s390x": 0.25.8 - "@esbuild/linux-x64": 0.25.8 - "@esbuild/netbsd-arm64": 0.25.8 - "@esbuild/netbsd-x64": 0.25.8 - "@esbuild/openbsd-arm64": 0.25.8 - "@esbuild/openbsd-x64": 0.25.8 - "@esbuild/openharmony-arm64": 0.25.8 - "@esbuild/sunos-x64": 0.25.8 - "@esbuild/win32-arm64": 0.25.8 - "@esbuild/win32-ia32": 0.25.8 - "@esbuild/win32-x64": 0.25.8 + version: 0.25.9 + resolution: "esbuild@npm:0.25.9" + dependencies: + "@esbuild/aix-ppc64": 0.25.9 + "@esbuild/android-arm": 0.25.9 + "@esbuild/android-arm64": 0.25.9 + "@esbuild/android-x64": 0.25.9 + "@esbuild/darwin-arm64": 0.25.9 + "@esbuild/darwin-x64": 0.25.9 + "@esbuild/freebsd-arm64": 0.25.9 + "@esbuild/freebsd-x64": 0.25.9 + "@esbuild/linux-arm": 0.25.9 + "@esbuild/linux-arm64": 0.25.9 + "@esbuild/linux-ia32": 0.25.9 + "@esbuild/linux-loong64": 0.25.9 + "@esbuild/linux-mips64el": 0.25.9 + "@esbuild/linux-ppc64": 0.25.9 + "@esbuild/linux-riscv64": 0.25.9 + "@esbuild/linux-s390x": 0.25.9 + "@esbuild/linux-x64": 0.25.9 + "@esbuild/netbsd-arm64": 0.25.9 + "@esbuild/netbsd-x64": 0.25.9 + "@esbuild/openbsd-arm64": 0.25.9 + "@esbuild/openbsd-x64": 0.25.9 + "@esbuild/openharmony-arm64": 0.25.9 + "@esbuild/sunos-x64": 0.25.9 + "@esbuild/win32-arm64": 0.25.9 + "@esbuild/win32-ia32": 0.25.9 + "@esbuild/win32-x64": 0.25.9 dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -9589,7 +10579,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 018e7b151c86df559f30e9b4da95cd5f6c76715818ee1c584ea3a4d19400be75f705f6d57486af2884ad7c1654b791e28419d34c0755186b194d3411745d074c + checksum: 718bc15016266da5b4675c2226923cadfe014b119e5c7a9240a6fe826c01ec2e7d5492af052e1c8a03b511778187f234cef2e994e6195287945ce0a824b79974 languageName: node linkType: hard @@ -10432,9 +11422,20 @@ __metadata: linkType: hard "fast-uri@npm:^3.0.1": - version: 3.0.6 - resolution: "fast-uri@npm:3.0.6" - checksum: 7161ba2a7944778d679ba8e5f00d6a2bb479a2142df0982f541d67be6c979b17808f7edbb0ce78161c85035974bde3fa52b5137df31da46c0828cb629ba67c4e + version: 3.1.0 + resolution: "fast-uri@npm:3.1.0" + checksum: daab0efd3548cc53d0db38ecc764d125773f8bd70c34552ff21abdc6530f26fa4cb1771f944222ca5e61a0a1a85d01a104848ff88c61736de445d97bd616ea7e + languageName: node + linkType: hard + +"fast-xml-parser@npm:5.2.5": + version: 5.2.5 + resolution: "fast-xml-parser@npm:5.2.5" + dependencies: + strnum: ^2.1.0 + bin: + fxparser: src/cli/cli.js + checksum: b12daa933bc226bd7df1e1ecbd305e561c83fd6e4a234b5e2728901deca25a9b9522b9d3ebafde41b1f4d87ab814e3efe18c636638580795fdbe4670a556be88 languageName: node linkType: hard @@ -10465,15 +11466,15 @@ __metadata: languageName: node linkType: hard -"fdir@npm:^6.4.4, fdir@npm:^6.4.6": - version: 6.4.6 - resolution: "fdir@npm:6.4.6" +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: picomatch: optional: true - checksum: fe9f3014901d023cf631831dcb9eae5447f4d7f69218001dd01ecf007eccc40f6c129a04411b5cc273a5f93c14e02e971e17270afc9022041c80be924091eb6f + checksum: bd537daa9d3cd53887eed35efa0eab2dbb1ca408790e10e024120e7a36c6e9ae2b33710cb8381e35def01bc9c1d7eaba746f886338413e68ff6ebaee07b9a6e8 languageName: node linkType: hard @@ -11579,8 +12580,8 @@ __metadata: linkType: hard "html-webpack-plugin@npm:^5.5.0": - version: 5.6.3 - resolution: "html-webpack-plugin@npm:5.6.3" + version: 5.6.4 + resolution: "html-webpack-plugin@npm:5.6.4" dependencies: "@types/html-minifier-terser": ^6.0.0 html-minifier-terser: ^6.0.2 @@ -11595,7 +12596,7 @@ __metadata: optional: true webpack: optional: true - checksum: 59e7d971b0cfd9ba34c7acaa3c161e43c62596474dd8cd35d7b690498ff5891f21296de0aa1d2e7810348caa657e938461267155dda47913b5eeca7124406270 + checksum: b486d99ce820d563dda215f8b6bbeb78127a738b88b419c95d577165e10dd29125e151010b5745ce933e8055f2445c2f9ad1c93024ad3b752db9ac613e84cfac languageName: node linkType: hard @@ -11743,7 +12744,16 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": +"iconv-lite@npm:0.7.0": + version: 0.7.0 + resolution: "iconv-lite@npm:0.7.0" + dependencies: + safer-buffer: ">= 2.1.2 < 3.0.0" + checksum: f362a8befb95e37f29be1d1290c17e0c9d0d4ad4fa62fcfd813cc9c937ab89401abed9a011f83e10651a267abb2aa231ec7da91d843570bec873bd98489b5bf8 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -11911,13 +12921,10 @@ __metadata: languageName: node linkType: hard -"ip-address@npm:^9.0.5": - version: 9.0.5 - resolution: "ip-address@npm:9.0.5" - dependencies: - jsbn: 1.1.0 - sprintf-js: ^1.1.3 - checksum: aa15f12cfd0ef5e38349744e3654bae649a34c3b10c77a674a167e99925d1549486c5b14730eebce9fea26f6db9d5e42097b00aa4f9f612e68c79121c71652dc +"ip-address@npm:^10.0.1": + version: 10.0.1 + resolution: "ip-address@npm:10.0.1" + checksum: 525d5391cfd31a91f80f5857e98487aeaa8474e860a6725a0b6461ac8e436c7f8c869774dece391c8f8e7486306a34a4d1c094778c4c583a3f1f2cd905e5ed50 languageName: node linkType: hard @@ -12415,12 +13422,12 @@ __metadata: linkType: hard "istanbul-reports@npm:^3.1.3": - version: 3.1.7 - resolution: "istanbul-reports@npm:3.1.7" + version: 3.2.0 + resolution: "istanbul-reports@npm:3.2.0" dependencies: html-escaper: ^2.0.0 istanbul-lib-report: ^3.0.0 - checksum: 2072db6e07bfbb4d0eb30e2700250636182398c1af811aea5032acb219d2080f7586923c09fa194029efd6b92361afb3dcbe1ebcc3ee6651d13340f7c6c4ed95 + checksum: 72b4c8525276147908d28b0917bc675b1019836b638e50875521ca3b8ec63672681aa98dbab88a6f49ef798c08fe041d428abdcf84f4f3fcff5844eee54af65a languageName: node linkType: hard @@ -13184,13 +14191,6 @@ __metadata: languageName: node linkType: hard -"jsbn@npm:1.1.0": - version: 1.1.0 - resolution: "jsbn@npm:1.1.0" - checksum: 944f924f2bd67ad533b3850eee47603eed0f6ae425fd1ee8c760f477e8c34a05f144c1bd4f5a5dd1963141dc79a2c55f89ccc5ab77d039e7077f3ad196b64965 - languageName: node - linkType: hard - "jsdom@npm:^16.6.0": version: 16.7.0 resolution: "jsdom@npm:16.7.0" @@ -13321,15 +14321,15 @@ __metadata: linkType: hard "jsonfile@npm:^6.0.1": - version: 6.1.0 - resolution: "jsonfile@npm:6.1.0" + version: 6.2.0 + resolution: "jsonfile@npm:6.2.0" dependencies: graceful-fs: ^4.1.6 universalify: ^2.0.0 dependenciesMeta: graceful-fs: optional: true - checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354 + checksum: c3028ec5c770bb41290c9bb9ca04bdd0a1b698ddbdf6517c9453d3f90fc9e000c9675959fb46891d317690a93c62de03ff1735d8dbe02be83e51168ce85815d3 languageName: node linkType: hard @@ -13736,9 +14736,9 @@ __metadata: linkType: hard "loupe@npm:^3.1.0, loupe@npm:^3.1.2, loupe@npm:^3.1.4": - version: 3.2.0 - resolution: "loupe@npm:3.2.0" - checksum: 4bfb4d9cf9e482b7f8c2f1d245cf0a14dd690b08d85356b0f0f6da94787c005ead7d2e4812a77ccddae42b86212b168beb1f65da711dc1709e9bf972beb51213 + version: 3.2.1 + resolution: "loupe@npm:3.2.1" + checksum: 3ce9ecc5b2c56ffc073bf065ad3a4644cccce3eac81e61a8732e9c8ebfe05513ed478592d25f9dba24cfe82766913be045ab384c04711c7c6447deaf800ad94c languageName: node linkType: hard @@ -13759,9 +14759,9 @@ __metadata: linkType: hard "lru-cache@npm:^11.0.0": - version: 11.1.0 - resolution: "lru-cache@npm:11.1.0" - checksum: 6274e90b5fdff87570fe26fe971467a5ae1f25f132bebe187e71c5627c7cd2abb94b47addd0ecdad034107667726ebde1abcef083d80f2126e83476b2c4e7c82 + version: 11.2.1 + resolution: "lru-cache@npm:11.2.1" + checksum: d54584b6f03e6de64c9e9f01e48abce5a9bc04318874d5204cee9e4275719544624d51eea6a167672576794af8bba3a7cfc23455d28b270a278cc387d1965131 languageName: node linkType: hard @@ -13802,11 +14802,11 @@ __metadata: linkType: hard "magic-string@npm:^0.30.12, magic-string@npm:^0.30.17": - version: 0.30.17 - resolution: "magic-string@npm:0.30.17" + version: 0.30.19 + resolution: "magic-string@npm:0.30.19" dependencies: - "@jridgewell/sourcemap-codec": ^1.5.0 - checksum: f4b4ed17c5ada64f77fc98491847302ebad64894a905c417c943840c0384662118c9b37f9f68bb86add159fa4749ff6f118c4627d69a470121b46731f8debc6d + "@jridgewell/sourcemap-codec": ^1.5.5 + checksum: f360b87febeceddb35238e55963b70ef68381688c1aada6d842833a7be440a08cb0a8776e23b5e4e34785edc6b42b92dc08c829f43ecdb58547122f3fd79fdc7 languageName: node linkType: hard @@ -14431,14 +15431,14 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.4.5": - version: 2.9.3 - resolution: "mini-css-extract-plugin@npm:2.9.3" + version: 2.9.4 + resolution: "mini-css-extract-plugin@npm:2.9.4" dependencies: schema-utils: ^4.0.0 tapable: ^2.2.1 peerDependencies: webpack: ^5.0.0 - checksum: a404565949c3601bf9e8363a2489ce41c6fd9b03a8d8e5f6b5ee49ba209357b07db05475f89ff1c4670f0fdde64d53637dc357d72519deabb2428ef53ccf8400 + checksum: 4ec46ebdcb5dae4b1c012debca90fea27b1e8e7790d408154232d77d25f56f839e7b1ec5401a962d6356e7b9301c760d2ef62e1cb0d4d7b6ec8209f812733dda languageName: node linkType: hard @@ -14617,12 +15617,11 @@ __metadata: linkType: hard "msw@npm:^2.7.0": - version: 2.10.4 - resolution: "msw@npm:2.10.4" + version: 2.11.2 + resolution: "msw@npm:2.11.2" dependencies: "@bundled-es-modules/cookie": ^2.0.1 "@bundled-es-modules/statuses": ^1.0.1 - "@bundled-es-modules/tough-cookie": ^0.1.6 "@inquirer/confirm": ^5.0.0 "@mswjs/interceptors": ^0.39.1 "@open-draft/deferred-promise": ^2.2.0 @@ -14635,7 +15634,9 @@ __metadata: outvariant: ^1.4.3 path-to-regexp: ^6.3.0 picocolors: ^1.1.1 + rettime: ^0.7.0 strict-event-emitter: ^0.5.1 + tough-cookie: ^6.0.0 type-fest: ^4.26.1 yargs: ^17.7.2 peerDependencies: @@ -14645,7 +15646,7 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: 7a0b30ffd982a4f99493c24efae48a333a007f53ddd53657ac8d850c86bd08cefd5fdff4af859ad3e9624a686fb57ff9061075ffb5abee7145b521401d515155 + checksum: 599aa3ed6e5043479bef473fa427a7aaf343d32aedba301ec62cac1a30c50b2a2898c4b9fe11b939ab03768807860eff64ce2fbdd28f78d0c6be4f4318d8b276 languageName: node linkType: hard @@ -14772,11 +15773,11 @@ __metadata: linkType: hard "node-abi@npm:^3.3.0": - version: 3.75.0 - resolution: "node-abi@npm:3.75.0" + version: 3.77.0 + resolution: "node-abi@npm:3.77.0" dependencies: semver: ^7.3.5 - checksum: b86021c748b316b31efda4f1f4a74db9fd411b0ae63fa50be5b0247546285ae7e31c737e92013478877eaf39a3fd0a06072d48b1cace21ad629862373410416f + checksum: 62ab12fe90e2c2081c1e0dfc3819d60dc181aff36c5dd2ca99cece3f1f19efb284be90353bd0cb911c44f77a23ce111635937e8c6b48dd8cfaa24e34221d4a9f languageName: node linkType: hard @@ -14811,8 +15812,8 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 11.3.0 - resolution: "node-gyp@npm:11.3.0" + version: 11.4.2 + resolution: "node-gyp@npm:11.4.2" dependencies: env-paths: ^2.2.0 exponential-backoff: ^3.1.1 @@ -14826,7 +15827,7 @@ __metadata: which: ^5.0.0 bin: node-gyp: bin/node-gyp.js - checksum: 64255952af18222e930a0bb8239e8fc86ec25eddfbf61523ab30b45f19670c1e66384ceda0472f5d59e63a7779b2134eab8ec5322b9f092f60202b0e312a66c8 + checksum: d8041cee7ec60c86fb2961d77c12a2d083a481fb28b08e6d9583153186c0e7766044dc30bdb1f3ac01ddc5763b83caeed3d1ea35787ec4ffd8cc4aeedfc34f2b languageName: node linkType: hard @@ -14837,10 +15838,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.19": - version: 2.0.19 - resolution: "node-releases@npm:2.0.19" - checksum: 917dbced519f48c6289a44830a0ca6dc944c3ee9243c468ebd8515a41c97c8b2c256edb7f3f750416bc37952cc9608684e6483c7b6c6f39f6bd8d86c52cfe658 +"node-releases@npm:^2.0.21": + version: 2.0.21 + resolution: "node-releases@npm:2.0.21" + checksum: 191f8245e18272971650eb45151c5891313bca27507a8f634085bd8c98a9cb9492686ef6182176866ceebff049646ef6cd5fb5ca46d5b5ca00ce2c69185d84c4 languageName: node linkType: hard @@ -14931,9 +15932,9 @@ __metadata: linkType: hard "nwsapi@npm:^2.2.0": - version: 2.2.21 - resolution: "nwsapi@npm:2.2.21" - checksum: 1378b2556b01063c95d88932aefc0516e853b1a5b9c94457e03aabfd4e6a133c32c636c3ccaaebdc3a4e316390e61cdb380f39aa4009c20d2e8c0fec869e6a66 + version: 2.2.22 + resolution: "nwsapi@npm:2.2.22" + checksum: 9491f0396d8aaf7fd1f9ebbbbff5d9bb9090e5d200263cf31b117bbaad7eb79da86b4c9b9bcd64c4b35f6d7e1630d14ee21c0959c01131e89c1c5e22d72530bf languageName: node linkType: hard @@ -15414,9 +16415,9 @@ __metadata: linkType: hard "path-to-regexp@npm:^8.0.0": - version: 8.2.0 - resolution: "path-to-regexp@npm:8.2.0" - checksum: 56e13e45962e776e9e7cd72e87a441cfe41f33fd539d097237ceb16adc922281136ca12f5a742962e33d8dda9569f630ba594de56d8b7b6e49adf31803c5e771 + version: 8.3.0 + resolution: "path-to-regexp@npm:8.3.0" + checksum: 73e0d3db449f9899692b10be8480bbcfa294fd575be2d09bce3e63f2f708d1fccd3aaa8591709f8b82062c528df116e118ff9df8f5c52ccc4c2443a90be73e10 languageName: node linkType: hard @@ -16754,14 +17755,14 @@ __metadata: linkType: hard "raw-body@npm:^3.0.0": - version: 3.0.0 - resolution: "raw-body@npm:3.0.0" + version: 3.0.1 + resolution: "raw-body@npm:3.0.1" dependencies: bytes: 3.1.2 http-errors: 2.0.0 - iconv-lite: 0.6.3 + iconv-lite: 0.7.0 unpipe: 1.0.0 - checksum: 25b7cf7964183db322e819050d758a5abd0f22c51e9f37884ea44a9ed6855a1fb61f8caa8ec5b61d07e69f54db43dbbc08ad98ef84556696d6aa806be247af0e + checksum: e75e1db74337e01b78cc07f7e65692ed46aef2e0c4fb39cb25bb365a7ab04cbdb8b3541aabebe50b07a5bffec5def5674b587fd9e8fbde84c8838cbab1ad9836 languageName: node linkType: hard @@ -17372,12 +18373,12 @@ __metadata: languageName: node linkType: hard -"regenerate-unicode-properties@npm:^10.2.0": - version: 10.2.0 - resolution: "regenerate-unicode-properties@npm:10.2.0" +"regenerate-unicode-properties@npm:^10.2.2": + version: 10.2.2 + resolution: "regenerate-unicode-properties@npm:10.2.2" dependencies: regenerate: ^1.4.2 - checksum: d5c5fc13f8b8d7e16e791637a4bfef741f8d70e267d51845ee7d5404a32fa14c75b181c4efba33e4bff8b0000a2f13e9773593713dfe5b66597df4259275ce63 + checksum: 7ae4c1c32460c4360e3118c45eec0621424908f430fdd6f162c9172067786bf2b1682fbc885a33b26bc85e76e06f4d3f398b52425e801b0bb0cbae147dafb0b2 languageName: node linkType: hard @@ -17424,16 +18425,16 @@ __metadata: linkType: hard "regexpu-core@npm:^6.2.0": - version: 6.2.0 - resolution: "regexpu-core@npm:6.2.0" + version: 6.3.1 + resolution: "regexpu-core@npm:6.3.1" dependencies: regenerate: ^1.4.2 - regenerate-unicode-properties: ^10.2.0 + regenerate-unicode-properties: ^10.2.2 regjsgen: ^0.8.0 regjsparser: ^0.12.0 unicode-match-property-ecmascript: ^2.0.0 - unicode-match-property-value-ecmascript: ^2.1.0 - checksum: 67d3c4a3f6c99bc80b5d690074a27e6f675be1c1739f8a9acf028fbc36f1a468472574ea65e331e217995198ba4404d7878f3cb3739a73552dd3c70d3fb7f8e6 + unicode-match-property-value-ecmascript: ^2.2.1 + checksum: 601a8298bca4d074c239e3b989b3b5f7532e4c8bde4e6d45690d4ba01d4f331869df3899a260a0fd88ecdb8902082725845447b0e2a3e1b0a1364131970489cb languageName: node linkType: hard @@ -17680,6 +18681,13 @@ __metadata: languageName: node linkType: hard +"rettime@npm:^0.7.0": + version: 0.7.0 + resolution: "rettime@npm:0.7.0" + checksum: 1ad3984a4f8000adf56c623882170115d7453b3bbaed56429a40077b067fad98c1c5db9a58e63793add15a97006fa7c817516d985c3347df40b5d274dc087803 + languageName: node + linkType: hard + "reusify@npm:^1.0.4": version: 1.1.0 resolution: "reusify@npm:1.1.0" @@ -17739,29 +18747,30 @@ __metadata: linkType: hard "rollup@npm:^4.20.0, rollup@npm:^4.23.0, rollup@npm:^4.43.0": - version: 4.46.2 - resolution: "rollup@npm:4.46.2" - dependencies: - "@rollup/rollup-android-arm-eabi": 4.46.2 - "@rollup/rollup-android-arm64": 4.46.2 - "@rollup/rollup-darwin-arm64": 4.46.2 - "@rollup/rollup-darwin-x64": 4.46.2 - "@rollup/rollup-freebsd-arm64": 4.46.2 - "@rollup/rollup-freebsd-x64": 4.46.2 - "@rollup/rollup-linux-arm-gnueabihf": 4.46.2 - "@rollup/rollup-linux-arm-musleabihf": 4.46.2 - "@rollup/rollup-linux-arm64-gnu": 4.46.2 - "@rollup/rollup-linux-arm64-musl": 4.46.2 - "@rollup/rollup-linux-loongarch64-gnu": 4.46.2 - "@rollup/rollup-linux-ppc64-gnu": 4.46.2 - "@rollup/rollup-linux-riscv64-gnu": 4.46.2 - "@rollup/rollup-linux-riscv64-musl": 4.46.2 - "@rollup/rollup-linux-s390x-gnu": 4.46.2 - "@rollup/rollup-linux-x64-gnu": 4.46.2 - "@rollup/rollup-linux-x64-musl": 4.46.2 - "@rollup/rollup-win32-arm64-msvc": 4.46.2 - "@rollup/rollup-win32-ia32-msvc": 4.46.2 - "@rollup/rollup-win32-x64-msvc": 4.46.2 + version: 4.50.1 + resolution: "rollup@npm:4.50.1" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.50.1 + "@rollup/rollup-android-arm64": 4.50.1 + "@rollup/rollup-darwin-arm64": 4.50.1 + "@rollup/rollup-darwin-x64": 4.50.1 + "@rollup/rollup-freebsd-arm64": 4.50.1 + "@rollup/rollup-freebsd-x64": 4.50.1 + "@rollup/rollup-linux-arm-gnueabihf": 4.50.1 + "@rollup/rollup-linux-arm-musleabihf": 4.50.1 + "@rollup/rollup-linux-arm64-gnu": 4.50.1 + "@rollup/rollup-linux-arm64-musl": 4.50.1 + "@rollup/rollup-linux-loongarch64-gnu": 4.50.1 + "@rollup/rollup-linux-ppc64-gnu": 4.50.1 + "@rollup/rollup-linux-riscv64-gnu": 4.50.1 + "@rollup/rollup-linux-riscv64-musl": 4.50.1 + "@rollup/rollup-linux-s390x-gnu": 4.50.1 + "@rollup/rollup-linux-x64-gnu": 4.50.1 + "@rollup/rollup-linux-x64-musl": 4.50.1 + "@rollup/rollup-openharmony-arm64": 4.50.1 + "@rollup/rollup-win32-arm64-msvc": 4.50.1 + "@rollup/rollup-win32-ia32-msvc": 4.50.1 + "@rollup/rollup-win32-x64-msvc": 4.50.1 "@types/estree": 1.0.8 fsevents: ~2.3.2 dependenciesMeta: @@ -17799,6 +18808,8 @@ __metadata: optional: true "@rollup/rollup-linux-x64-musl": optional: true + "@rollup/rollup-openharmony-arm64": + optional: true "@rollup/rollup-win32-arm64-msvc": optional: true "@rollup/rollup-win32-ia32-msvc": @@ -17809,7 +18820,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: cba997c09d51a92bdf0475c522dafe6264891329d4d53689b7fab8a44bbf0b8ab2feb4bb27d9809a5d76831e703fddb44d5f8a95c1d3e7f2f9c9766541f65475 + checksum: 3d825ac7fa5c099b09738cb7b6288b27c242d54dfb07c8140f05dea8c33373f70968ed1b50b8b230ed694ac3404eb13739f6dbfb810fa51278200ed91893d301 languageName: node linkType: hard @@ -17835,7 +18846,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.8.1": +"rxjs@npm:7.8.2": version: 7.8.2 resolution: "rxjs@npm:7.8.2" dependencies: @@ -17932,8 +18943,8 @@ __metadata: linkType: hard "sass@npm:^1.54.0": - version: 1.90.0 - resolution: "sass@npm:1.90.0" + version: 1.92.1 + resolution: "sass@npm:1.92.1" dependencies: "@parcel/watcher": ^2.4.1 chokidar: ^4.0.0 @@ -17944,7 +18955,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: 1f2ad353eb9a4a294ba7e8f9038363c8fbf69afbf2938d53a3beff9bd9180061c3da71f139b7dedc4707f7421c4a1226164bd0276988dbc3b43b1276c0752055 + checksum: ec0d4da639874f0f849b766f51f3db1fdff703840e7066ca3dd097999179630707b357744d83dde54289c02bba2f1ef8b34bba460cf4f703874b7922a86e32df languageName: node linkType: hard @@ -18261,7 +19272,7 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:^1.7.3, shell-quote@npm:^1.8.1, shell-quote@npm:^1.8.3": +"shell-quote@npm:1.8.3, shell-quote@npm:^1.7.3, shell-quote@npm:^1.8.3": version: 1.8.3 resolution: "shell-quote@npm:1.8.3" checksum: 550dd84e677f8915eb013d43689c80bb114860649ec5298eb978f40b8f3d4bc4ccb072b82c094eb3548dc587144bb3965a8676f0d685c1cf4c40b5dc27166242 @@ -18436,12 +19447,12 @@ __metadata: linkType: hard "socks@npm:^2.8.3": - version: 2.8.6 - resolution: "socks@npm:2.8.6" + version: 2.8.7 + resolution: "socks@npm:2.8.7" dependencies: - ip-address: ^9.0.5 + ip-address: ^10.0.1 smart-buffer: ^4.2.0 - checksum: 3d2a696d42d94b05b2a7e797b9291483d6768b23300b015353f34f8046cce35f23fe59300a38a77a9f0dee4274dd6c333afbdef628cf48f3df171bfb86c2d21c + checksum: 4bbe2c88cf0eeaf49f94b7f11564a99b2571bde6fd1e714ff95b38f89e1f97858c19e0ab0e6d39eb7f6a984fa67366825895383ed563fe59962a1d57a1d55318 languageName: node linkType: hard @@ -18553,13 +19564,6 @@ __metadata: languageName: node linkType: hard -"sprintf-js@npm:^1.1.3": - version: 1.1.3 - resolution: "sprintf-js@npm:1.1.3" - checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 - languageName: node - linkType: hard - "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -18852,11 +19856,11 @@ __metadata: linkType: hard "strip-ansi@npm:^7.0.1": - version: 7.1.0 - resolution: "strip-ansi@npm:7.1.0" + version: 7.1.2 + resolution: "strip-ansi@npm:7.1.2" dependencies: ansi-regex: ^6.0.1 - checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d + checksum: db0e3f9654e519c8a33c50fc9304d07df5649388e7da06d3aabf66d29e5ad65d5e6315d8519d409c15b32fa82c1df7e11ed6f8cd50b0e4404463f0c9d77c8d0b languageName: node linkType: hard @@ -18920,6 +19924,13 @@ __metadata: languageName: node linkType: hard +"strnum@npm:^2.1.0": + version: 2.1.1 + resolution: "strnum@npm:2.1.1" + checksum: 566139b218ef13bdde2a69c744852ac41ea167588f624d46c3b3bebb5d1d1775c55bca4702a0ad2a6a66eb4b3b7de4cbbc83e8d40c5835feabebf6f9cc468993 + languageName: node + linkType: hard + "style-loader@npm:^3.3.1": version: 3.3.4 resolution: "style-loader@npm:3.3.4" @@ -19012,6 +20023,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:8.1.1, supports-color@npm:^8.0.0": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: ^4.0.0 + checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 + languageName: node + linkType: hard + "supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -19030,15 +20050,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0, supports-color@npm:^8.1.1": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: ^4.0.0 - checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 - languageName: node - linkType: hard - "supports-hyperlinks@npm:^2.0.0": version: 2.3.0 resolution: "supports-hyperlinks@npm:2.3.0" @@ -19173,9 +20184,9 @@ __metadata: linkType: hard "tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": - version: 2.2.2 - resolution: "tapable@npm:2.2.2" - checksum: 781b3666f4454eb506fd2bcd985c1994f2b93884ea88a7a2a5be956cad8337b31128a7591e771f7aab8e247993b2a0887d360a2d4f54382902ed89994c102740 + version: 2.2.3 + resolution: "tapable@npm:2.2.3" + checksum: 0bef252c4f12d3371353c4b16b38ea4fc7153598ab7f7770a4235277ed4d631925a27f42bf03caa754817e9ab017e3179fd2323a0a28409846d225e23f3bf722 languageName: node linkType: hard @@ -19270,16 +20281,16 @@ __metadata: linkType: hard "terser@npm:^5.0.0, terser@npm:^5.10.0, terser@npm:^5.31.1": - version: 5.43.1 - resolution: "terser@npm:5.43.1" + version: 5.44.0 + resolution: "terser@npm:5.44.0" dependencies: "@jridgewell/source-map": ^0.3.3 - acorn: ^8.14.0 + acorn: ^8.15.0 commander: ^2.20.0 source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: 1d51747f4540a0842139c2f2617e88d68a26da42d7571cda8955e1bd8febac6e60bc514c258781334e1724aeeccfbd511473eb9d8d831435e4e5fad1ce7f6e8b + checksum: 4e1868d9662ea280dad7b49cfe61b7693187be2b529b31b1f86782db00833c03ba05f2b82fc513d928e937260f2a5fbf42a93724e86eaf55f069288f934ccdb3 languageName: node linkType: hard @@ -19368,13 +20379,13 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14": - version: 0.2.14 - resolution: "tinyglobby@npm:0.2.14" +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": + version: 0.2.15 + resolution: "tinyglobby@npm:0.2.15" dependencies: - fdir: ^6.4.4 - picomatch: ^4.0.2 - checksum: 261e986e3f2062dec3a582303bad2ce31b4634b9348648b46828c000d464b012cf474e38f503312367d4117c3f2f18611992738fca684040758bba44c24de522 + fdir: ^6.5.0 + picomatch: ^4.0.3 + checksum: 0e33b8babff966c6ab86e9b825a350a6a98a63700fa0bb7ae6cf36a7770a508892383adc272f7f9d17aaf46a9d622b455e775b9949a3f951eaaf5dfb26331d44 languageName: node linkType: hard @@ -19413,6 +20424,24 @@ __metadata: languageName: node linkType: hard +"tldts-core@npm:^7.0.14": + version: 7.0.14 + resolution: "tldts-core@npm:7.0.14" + checksum: bc13d721605fb66dab2baaf3ae665a8a48722f5b86e2b8a9b299cdbdc34c2a3b7167a08566afe52eed3064a3a0fc08680c456aa170fa9a50d85b9421f787c6db + languageName: node + linkType: hard + +"tldts@npm:^7.0.5": + version: 7.0.14 + resolution: "tldts@npm:7.0.14" + dependencies: + tldts-core: ^7.0.14 + bin: + tldts: bin/cli.js + checksum: dfd07fe27f2d4bfb7219391dcf666e60ca5041c17e037a7eee3171d4a809e003f71abd73295ab846586c1b589f4aa727439038810e19ef86a8e74ac780deb421 + languageName: node + linkType: hard + "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -19452,7 +20481,7 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^4.0.0, tough-cookie@npm:^4.1.4": +"tough-cookie@npm:^4.0.0": version: 4.1.4 resolution: "tough-cookie@npm:4.1.4" dependencies: @@ -19464,6 +20493,15 @@ __metadata: languageName: node linkType: hard +"tough-cookie@npm:^6.0.0": + version: 6.0.0 + resolution: "tough-cookie@npm:6.0.0" + dependencies: + tldts: ^7.0.5 + checksum: 66d32ee40e1c6c61be5388e1c124674871dae0a684c30853f1628a4da2c5ad4199a825d1b0a7ba424dadfba7b5a9b37e8c761eafbf48f1b9f75a4629e73b14bc + languageName: node + linkType: hard + "tr46@npm:^1.0.1": version: 1.0.1 resolution: "tr46@npm:1.0.1" @@ -19489,7 +20527,7 @@ __metadata: languageName: node linkType: hard -"tree-kill@npm:^1.2.2": +"tree-kill@npm:1.2.2": version: 1.2.2 resolution: "tree-kill@npm:1.2.2" bin: @@ -19612,7 +20650,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.1.0": +"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.6.2": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a @@ -19943,10 +20981,10 @@ __metadata: languageName: node linkType: hard -"unicode-match-property-value-ecmascript@npm:^2.1.0": - version: 2.2.0 - resolution: "unicode-match-property-value-ecmascript@npm:2.2.0" - checksum: 9e3151e1d0bc6be35c4cef105e317c04090364173e8462005b5cde08a1e7c858b6586486cfebac39dc2c6c8c9ee24afb245de6d527604866edfa454fe2a35fae +"unicode-match-property-value-ecmascript@npm:^2.2.1": + version: 2.2.1 + resolution: "unicode-match-property-value-ecmascript@npm:2.2.1" + checksum: e6c73e07bb4dc4aa399797a14b170e84a30ed290bcf97cc4305cf67dde8744119721ce17cef03f4f9d4ff48654bfa26eadc7fe1e8dd4b71b8f3b2e9a9742f013 languageName: node linkType: hard @@ -20399,8 +21437,8 @@ __metadata: linkType: hard "vite@npm:^5.0.0": - version: 5.4.19 - resolution: "vite@npm:5.4.19" + version: 5.4.20 + resolution: "vite@npm:5.4.20" dependencies: esbuild: ^0.21.3 fsevents: ~2.3.3 @@ -20437,21 +21475,21 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: c15af65f2370b59e674c5fab22d8e05ec5c7f8f0345ed99ffec155c77feb5636b4e0680dbd096a6f06d7c386b259dc0b9c67c4f1ec08486a2f2a677c9ea6971b + checksum: 67af97e818977e92d1e55bc35d45f58d41eba6fc87f2a18435d3402adb07f4c4ec1ba838d954829f80f7784e65b65f8d147db695cfaefe45f667ee283530770d languageName: node linkType: hard "vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": - version: 7.1.1 - resolution: "vite@npm:7.1.1" + version: 7.1.5 + resolution: "vite@npm:7.1.5" dependencies: esbuild: ^0.25.0 - fdir: ^6.4.6 + fdir: ^6.5.0 fsevents: ~2.3.3 picomatch: ^4.0.3 postcss: ^8.5.6 rollup: ^4.43.0 - tinyglobby: ^0.2.14 + tinyglobby: ^0.2.15 peerDependencies: "@types/node": ^20.19.0 || >=22.12.0 jiti: ">=1.21.0" @@ -20492,7 +21530,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 608b953c9e3067f533874093b2fc7cf7bf47864904fd73dfbb3a6b36395ea710a14fbc76a2ae78661a565b7398a30110eca44837942ac585b9c9b59e6550d114 + checksum: 14922d98024a1d93ebe8f3ce38af586c83d55f037f8c5fe8664103d7aa0785d0747f3edf8cb6550dcfa071b90bfd40bce56581d9cb14a19a53d29abb9f3415f5 languageName: node linkType: hard @@ -20794,8 +21832,8 @@ __metadata: linkType: hard "webpack@npm:^5.64.4": - version: 5.101.0 - resolution: "webpack@npm:5.101.0" + version: 5.101.3 + resolution: "webpack@npm:5.101.3" dependencies: "@types/eslint-scope": ^3.7.7 "@types/estree": ^1.0.8 @@ -20807,7 +21845,7 @@ __metadata: acorn-import-phases: ^1.0.3 browserslist: ^4.24.0 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.17.2 + enhanced-resolve: ^5.17.3 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 @@ -20827,7 +21865,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: fba0a5146e94bcd3634d3f791637382dc57e746fe8010ad54636bf3e8d7d10c3027e78a85eee74702d9c146f9b858f2e3052d64bfffc4a8a0f2c778d63d0f3d6 + checksum: d23fd86b6bc9854f9b488830d9aa123a7f654ee22849bc8670d0a22add88951f6d9cab1d04087758b642fc31115e3b97e0ac56b80b2200c04c486067aa945663 languageName: node linkType: hard @@ -21407,6 +22445,21 @@ __metadata: languageName: node linkType: hard +"yargs@npm:17.7.2, yargs@npm:^17.3.1, yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + 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 + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + languageName: node + linkType: hard + "yargs@npm:^15.3.1": version: 15.4.1 resolution: "yargs@npm:15.4.1" @@ -21441,21 +22494,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.3.1, yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" - 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 - checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a - languageName: node - linkType: hard - "yn@npm:3.1.1": version: 3.1.1 resolution: "yn@npm:3.1.1" @@ -21471,9 +22509,9 @@ __metadata: linkType: hard "yoctocolors-cjs@npm:^2.1.2": - version: 2.1.2 - resolution: "yoctocolors-cjs@npm:2.1.2" - checksum: 1c474d4b30a8c130e679279c5c2c33a0d48eba9684ffa0252cc64846c121fb56c3f25457fef902edbe1e2d7a7872130073a9fc8e795299d75e13fa3f5f548f1b + version: 2.1.3 + resolution: "yoctocolors-cjs@npm:2.1.3" + checksum: 207df586996c3b604fa85903f81cc54676f1f372613a0c7247f0d24b1ca781905685075d06955211c4d5d4f629d7d5628464f8af0a42d286b7a8ff88e9dadcb8 languageName: node linkType: hard From b7287095908eebfacc0c398bc7141926abf5729a Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 15 Sep 2025 14:19:21 -0400 Subject: [PATCH 035/477] #3565 updated file/class names --- .../{machinery.controllers.ts => calendar.controllers.ts} | 4 ++-- src/backend/src/prisma/seed.ts | 2 +- src/backend/src/routes/calendar.routes.ts | 2 +- .../services/{machinery.services.ts => calendar.services.ts} | 2 +- .../tests/unit/{machinery.test.ts => calendar.test.ts} | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename src/backend/src/controllers/{machinery.controllers.ts => calendar.controllers.ts} (80%) rename src/backend/src/services/{machinery.services.ts => calendar.services.ts} (97%) rename src/backend/tests/unit/{machinery.test.ts => calendar.test.ts} (96%) diff --git a/src/backend/src/controllers/machinery.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts similarity index 80% rename from src/backend/src/controllers/machinery.controllers.ts rename to src/backend/src/controllers/calendar.controllers.ts index 4aa1c35c34..15394758fb 100644 --- a/src/backend/src/controllers/machinery.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -1,7 +1,7 @@ import { NextFunction, Request, Response } from 'express'; -import MachineryService from '../services/machinery.services'; +import MachineryService from '../services/calendar.services'; -export default class MachineryController { +export default class CalendarController { static async createMachinery(req: Request, res: Response, next: NextFunction) { try { const { name, shopId, quantity } = req.body; diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 9cd170f181..f66738e3a1 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -50,7 +50,7 @@ import AnnouncementService from '../services/announcement.services'; import OnboardingServices from '../services/onboarding.services'; import { dbSeedAllParts, dbSeedAllPartTags } from './seed-data/parts.seed'; import FinanceServices from '../services/finance.services'; -import MachineryService from '../services/machinery.services'; +import MachineryService from '../services/calendar.services'; const prisma = new PrismaClient(); diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index d233b0efea..ff0528c7c5 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,7 +1,7 @@ import express from 'express'; import { body } from 'express-validator'; import { nonEmptyString, validateInputs } from '../utils/validation.utils'; -import MachineryController from '../controllers/machinery.controllers'; +import MachineryController from '../controllers/calendar.controllers'; const calendarRouter = express.Router(); diff --git a/src/backend/src/services/machinery.services.ts b/src/backend/src/services/calendar.services.ts similarity index 97% rename from src/backend/src/services/machinery.services.ts rename to src/backend/src/services/calendar.services.ts index e8a49c2269..e94589add3 100644 --- a/src/backend/src/services/machinery.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -4,7 +4,7 @@ import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; -export default class MachineryService { +export default class CalendarService { /** * Creates a new machinery and associates it with shops. * diff --git a/src/backend/tests/unit/machinery.test.ts b/src/backend/tests/unit/calendar.test.ts similarity index 96% rename from src/backend/tests/unit/machinery.test.ts rename to src/backend/tests/unit/calendar.test.ts index 2948fcdca2..c11923eb2c 100644 --- a/src/backend/tests/unit/machinery.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,5 +1,5 @@ import { Organization } from '@prisma/client'; -import MachineryService from '../../src/services/machinery.services'; +import MachineryService from '../../src/services/calendar.services'; import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; import { batmanAppAdmin, wonderwomanGuest, supermanAdmin } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; From 3864f7e5a8685aec022ac5e27c2d52f0dcadab76 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Mon, 15 Sep 2025 17:23:20 -0400 Subject: [PATCH 036/477] #3555 everything but seed data and tests --- src/backend/index.ts | 2 + .../src/controllers/calendar.controllers.ts | 47 +++++++++++ src/backend/src/routes/calendar.routes.ts | 25 ++++++ src/backend/src/services/calendar.services.ts | 79 +++++++++++++++++++ .../src/transformers/calendar.transformer.ts | 8 ++ src/shared/index.ts | 1 + 6 files changed, 162 insertions(+) create mode 100644 src/backend/src/controllers/calendar.controllers.ts create mode 100644 src/backend/src/routes/calendar.routes.ts create mode 100644 src/backend/src/services/calendar.services.ts create mode 100644 src/backend/src/transformers/calendar.transformer.ts diff --git a/src/backend/index.ts b/src/backend/index.ts index ffe251ec65..f958e82b98 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -25,6 +25,7 @@ import statisticsRouter from './src/routes/statistics.routes'; import retrospectiveRouter from './src/routes/retrospective.routes'; import partsRouter from './src/routes/parts.routes'; import financeRouter from './src/routes/finance.routes'; +import calendarRouter from './src/routes/calendar.routes'; const app = express(); @@ -87,6 +88,7 @@ app.use('/statistics', statisticsRouter); app.use('/retrospective', retrospectiveRouter); app.use('/parts', partsRouter); app.use('/finance', financeRouter); +app.use('/calendar', calendarRouter); app.use('/', (_req, res) => { res.status(200).json('Welcome to FinishLine'); }); diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts new file mode 100644 index 0000000000..2c81d4c365 --- /dev/null +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -0,0 +1,47 @@ +import { NextFunction, Request, Response } from 'express'; +import CalendarService from '../services/calendar.services'; + +export default class CalendarController { + static async createEventType(req: Request, res: Response, next: NextFunction) { + try { + const { + name, + calendarId, + initialDateScheduled, + recurring, + allDay, + members, + location, + zoomLink, + availabilities, + shop, + machinery, + workPackage, + documents, + description + } = req.body; + + const eventType = await CalendarService.createEventType( + req.currentUser, + name, + calendarId, + req.organization, + initialDateScheduled, + recurring, + allDay, + members, + location, + zoomLink, + availabilities, + shop, + machinery, + workPackage, + documents, + description + ); + res.status(200).json(eventType); + } catch (error: unknown) { + next(error); + } + } +} diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts new file mode 100644 index 0000000000..cc17586b96 --- /dev/null +++ b/src/backend/src/routes/calendar.routes.ts @@ -0,0 +1,25 @@ +import express from 'express'; +import { body } from 'express-validator'; +import { nonEmptyString, validateInputs } from '../utils/validation.utils'; + +const calendarRouter = express.Router(); + +calendarRouter.post( + '/event-type/create', + nonEmptyString(body('name')), + body('calendarIds').isArray, + body('initialDateScheduled').isBoolean().optional, + body('allDay').isBoolean().optional, + body('recurring').isBoolean().optional, + body('members').isBoolean().optional, + body('location').isBoolean().optional, + body('zoomLink').isBoolean().optional, + body('availabilities').isBoolean().optional, + body('shop').isBoolean().optional, + body('machinery').isBoolean().optional, + body('workPackage').isBoolean().optional, + body('documents').isBoolean().optional, + body('description').isBoolean().optional +); + +export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts new file mode 100644 index 0000000000..92d6cec106 --- /dev/null +++ b/src/backend/src/services/calendar.services.ts @@ -0,0 +1,79 @@ +import { Organization, User } from '@prisma/client'; +import { isAdmin, EventType } from 'shared'; +import prisma from '../prisma/prisma'; +import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; +import { userHasPermission } from '../utils/users.utils'; +import { eventTypeTransformer } from '../transformers/calendar.transformer'; + +export default class CalendarService { + /** + * Creates a new event type. + * + * @param submitter The user submitting the request, who must be an admin. + * @param name The name of the event type. + * @param calendarIds An array of the calendars this event type is associated with. + * @param organization The organization for which the event type is being created. + * @param initialDateScheduled Determines if a date is associated with this event type. + * @param recurring Determines if this event type is recurring. + * @param allDay Determines if this event type is all day. + * @param members Determines if this event type has members. + * @param location Determines if this event type has a location. + * @param zoomLink Determines if this event type has a zoom link. + * @param availabilities Determines if this event type has availabilities. + * @param shop Determines if a shop is associated with this event type. + * @param machinery Determines if machinery is associated with this event type. + * @param workPackage Determines if a work package is associated with this event type. + * @param documents Determines if documents are associates with this event type. + * @param description Determines if a description is associated with this event type. + * + * @returns The created event type. + * + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + */ + static async createEventType( + submitter: User, + name: string, + calendarIds: string[], + organization: Organization, + initialDateScheduled?: boolean, + recurring?: boolean, + allDay?: boolean, + members?: boolean, + location?: boolean, + zoomLink?: boolean, + availabilities?: boolean, + shop?: boolean, + machinery?: boolean, + workPackage?: boolean, + documents?: boolean, + description?: boolean + ): Promise { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('create event type'); + } + + const newEventType = await prisma.eventType.create({ + data: { + name, + calendars: { + connect: calendarIds.map((calendarId) => ({ calendarId })) + }, + userCreated: { connect: { userId: submitter.userId } }, + initialDateScheduled, + recurring, + allDay, + members, + location, + zoomLink, + availabilities, + shop, + machinery, + workPackage, + documents, + description + } + }); + + return eventTypeTransformer(newEventType); + } +} diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts new file mode 100644 index 0000000000..bd2c57cc97 --- /dev/null +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -0,0 +1,8 @@ +import { Prisma } from '@prisma/client'; +import { EventType } from 'shared'; + +export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload): EventType => { + return { + name: eventType.name + }; +}; diff --git a/src/shared/index.ts b/src/shared/index.ts index 1b96e36456..170cc3b472 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -19,6 +19,7 @@ export * from './src/types/pop-up-types'; export * from './src/types/announcements.types'; export * from './src/types/part-review.types'; export * from './src/types/finance-types'; +export * from './src/types/calendar-types'; export * from './src/validate-wbs'; export * from './src/date-utils'; From 693078a602c39243747b022e86bb1d80538c8e92 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 15 Sep 2025 20:34:59 -0400 Subject: [PATCH 037/477] fixed tests maybe --- .../src/controllers/shop.controllers.ts | 22 +++++------ src/backend/src/prisma/seed.ts | 11 +----- src/backend/src/services/shop.services.ts | 38 +++++++++---------- src/backend/tests/test-utils.ts | 3 +- src/backend/tests/unit/shop.test.ts | 11 +----- 5 files changed, 30 insertions(+), 55 deletions(-) diff --git a/src/backend/src/controllers/shop.controllers.ts b/src/backend/src/controllers/shop.controllers.ts index 08abff0f1d..f7beffeb91 100644 --- a/src/backend/src/controllers/shop.controllers.ts +++ b/src/backend/src/controllers/shop.controllers.ts @@ -2,17 +2,13 @@ import { NextFunction, Request, Response } from 'express'; import ShopService from '../services/shop.services'; export default class ShopController { - static async createShop(req: Request, res: Response, next: NextFunction) { - try{ - const {name, description} = req.body; - const shop = await ShopService.createShop( - (req as any).currentUser, - name, - description, - (req as any).organization); - res.status(201).json(shop); - } catch(error) { - next(error); - } + static async createShop(req: Request, res: Response, next: NextFunction) { + try { + const { name, description } = req.body; + const shop = await ShopService.createShop((req as any).currentUser, name, description, (req as any).organization); + res.status(201).json(shop); + } catch (error) { + next(error); } -} \ No newline at end of file + } +} diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index c36d512b6b..39210e3c22 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3068,17 +3068,9 @@ const performSeed: () => Promise = async () => { ner ); - await ShopServices.createShop( - thomasEmrax, - 'Electronics Design Center', - 'Electronics testing and circuit design lab', - ner - ); - + await ShopServices.createShop(thomasEmrax, 'Electronics Design Center', 'Electronics testing and circuit design lab', ner); }; - - performSeed() .catch((e) => { console.error(e); @@ -3087,4 +3079,3 @@ performSeed() .finally(async () => { await prisma.$disconnect(); }); - diff --git a/src/backend/src/services/shop.services.ts b/src/backend/src/services/shop.services.ts index f8e3f38628..d725688c2d 100644 --- a/src/backend/src/services/shop.services.ts +++ b/src/backend/src/services/shop.services.ts @@ -5,25 +5,21 @@ import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; export default class ShopServices { - /** - * Creates a new shop - * requires the submiter to be Admin - */ - static async createShop(submitter: User, name: string, description: string, organization: Organization) { - const permission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); - if (!permission) throw new AccessDeniedAdminOnlyException('Only admins can create a shop'); - - const shop = await prisma.shop.create({ - data: { - name, - description, - userCreatedId: submitter.userId, + /** + * Creates a new shop + * requires the submiter to be Admin + */ + static async createShop(submitter: User, name: string, description: string, organization: Organization) { + const permission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); + if (!permission) throw new AccessDeniedAdminOnlyException('create a shop'); - }, - }); - return shop; - - - - } -} \ No newline at end of file + const shop = await prisma.shop.create({ + data: { + name, + description, + userCreatedId: submitter.userId + } + }); + return shop; + } +} diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index ef59ede25d..268591974d 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -167,11 +167,10 @@ export const resetUsers = async () => { await prisma.refund_Source.deleteMany(); await prisma.index_Code.deleteMany(); await prisma.organization.deleteMany(); - await prisma.user.deleteMany(); await prisma.shopMachinery.deleteMany(); await prisma.machinery.deleteMany(); await prisma.shop.deleteMany(); - + await prisma.user.deleteMany(); }; export const createFinanceTeamAndLead = async (organization?: Organization) => { diff --git a/src/backend/tests/unit/shop.test.ts b/src/backend/tests/unit/shop.test.ts index ac13f7c4ff..efc6ca95c7 100644 --- a/src/backend/tests/unit/shop.test.ts +++ b/src/backend/tests/unit/shop.test.ts @@ -20,12 +20,7 @@ describe('Shop Tests', () => { describe('create shop', () => { it('fails if user is not an admin', async () => { await expect( - ShopServices.createShop( - await createTestUser(wonderwomanGuest, orgId), - 'Non-Admin Shop', - 'desc', - organization - ) + ShopServices.createShop(await createTestUser(wonderwomanGuest, orgId), 'Non-Admin Shop', 'desc', organization) ).rejects.toThrow(new AccessDeniedAdminOnlyException('create shop')); }); @@ -42,9 +37,7 @@ describe('Shop Tests', () => { const admin = await createTestUser(batmanAppAdmin, orgId); await ShopServices.createShop(admin, 'UniqueName', 'first', organization); - await expect( - ShopServices.createShop(admin, 'UniqueName', 'second attempt', organization) - ).rejects.toBeTruthy(); + await expect(ShopServices.createShop(admin, 'UniqueName', 'second attempt', organization)).rejects.toBeTruthy(); }); }); }); From 125a0bfcb247615b8702e515e8caacd528b85f2e Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 15 Sep 2025 20:53:52 -0400 Subject: [PATCH 038/477] Hopefully reverting the yarnlock --- src/backend/src/services/shop.services.ts | 2 +- yarn.lock | 22116 +++++++++----------- 2 files changed, 10459 insertions(+), 11659 deletions(-) diff --git a/src/backend/src/services/shop.services.ts b/src/backend/src/services/shop.services.ts index d725688c2d..2d08648ee5 100644 --- a/src/backend/src/services/shop.services.ts +++ b/src/backend/src/services/shop.services.ts @@ -11,7 +11,7 @@ export default class ShopServices { */ static async createShop(submitter: User, name: string, description: string, organization: Organization) { const permission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); - if (!permission) throw new AccessDeniedAdminOnlyException('create a shop'); + if (!permission) throw new AccessDeniedAdminOnlyException('create shop'); const shop = await prisma.shop.create({ data: { diff --git a/yarn.lock b/yarn.lock index 1c0eddac84..563831aede 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,514 +5,36 @@ __metadata: version: 6 cacheKey: 8 -"@adobe/css-tools@npm:^4.4.0": - version: 4.4.4 - resolution: "@adobe/css-tools@npm:4.4.4" - checksum: 452b82cd9f42aacc57eeaf0b11e36c6864eb482e8a347054cb986503d221d1f7c1418710d2007858d8919afdbd31357149c2c16bd080ded15506f13608d16cf2 - languageName: node - linkType: hard - -"@alloc/quick-lru@npm:^5.2.0": - version: 5.2.0 - resolution: "@alloc/quick-lru@npm:5.2.0" - checksum: bdc35758b552bcf045733ac047fb7f9a07c4678b944c641adfbd41f798b4b91fffd0fdc0df2578d9b0afc7b4d636aa6e110ead5d6281a2adc1ab90efd7f057f8 - languageName: node - linkType: hard - -"@apideck/better-ajv-errors@npm:^0.3.1": - version: 0.3.6 - resolution: "@apideck/better-ajv-errors@npm:0.3.6" - dependencies: - json-schema: ^0.4.0 - jsonpointer: ^5.0.0 - leven: ^3.1.0 - peerDependencies: - ajv: ">=8" - checksum: b70ec9aae3b30ba1ac06948e585cd96aabbfe7ef6a1c27dc51e56c425f01290a58e9beb19ed95ee64da9f32df3e9276cd1ea58e78792741d74a519cb56955491 - languageName: node - linkType: hard - -"@aws-crypto/sha256-browser@npm:5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/sha256-browser@npm:5.2.0" - dependencies: - "@aws-crypto/sha256-js": ^5.2.0 - "@aws-crypto/supports-web-crypto": ^5.2.0 - "@aws-crypto/util": ^5.2.0 - "@aws-sdk/types": ^3.222.0 - "@aws-sdk/util-locate-window": ^3.0.0 - "@smithy/util-utf8": ^2.0.0 - tslib: ^2.6.2 - checksum: 773f12f2026d82a6bb4a23a8f491894a6d32525bd9b8bfbc12896526cf11882a7607a671c478c45f9cd7d6ba1caaed48a62b67c6f725244bd83a1275108f46c7 - languageName: node - linkType: hard - -"@aws-crypto/sha256-js@npm:5.2.0, @aws-crypto/sha256-js@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/sha256-js@npm:5.2.0" - dependencies: - "@aws-crypto/util": ^5.2.0 - "@aws-sdk/types": ^3.222.0 - tslib: ^2.6.2 - checksum: 007fbe0436d714d0d0d282e2b61c90e45adcb9ad75eac9ac7ba03d32b56624afd09b2a9ceb4d659661cf17c51d74d1900ab6b00eacafc002da1101664955ca53 - languageName: node - linkType: hard - -"@aws-crypto/supports-web-crypto@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/supports-web-crypto@npm:5.2.0" - dependencies: - tslib: ^2.6.2 - checksum: 6ffc21de48b2b2c3e918193101d7e8fe949d47b37688892e1c39eaedaa938be80c0f404fe1c874c30cce16781026777a53bf47d5d90143ca91d0feb7c4a6f830 - languageName: node - linkType: hard - -"@aws-crypto/util@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/util@npm:5.2.0" - dependencies: - "@aws-sdk/types": ^3.222.0 - "@smithy/util-utf8": ^2.0.0 - tslib: ^2.6.2 - checksum: f0f81d9d2771c59946cfec48b86cb23d39f78a966c4a1f89d4753abdc3cb38de06f907d1e6450059b121d48ac65d612ab88bdb70014553a077fc3dabddfbf8d6 - languageName: node - linkType: hard - -"@aws-sdk/client-ses@npm:^3.731.1": - version: 3.888.0 - resolution: "@aws-sdk/client-ses@npm:3.888.0" - dependencies: - "@aws-crypto/sha256-browser": 5.2.0 - "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.888.0 - "@aws-sdk/credential-provider-node": 3.888.0 - "@aws-sdk/middleware-host-header": 3.887.0 - "@aws-sdk/middleware-logger": 3.887.0 - "@aws-sdk/middleware-recursion-detection": 3.887.0 - "@aws-sdk/middleware-user-agent": 3.888.0 - "@aws-sdk/region-config-resolver": 3.887.0 - "@aws-sdk/types": 3.887.0 - "@aws-sdk/util-endpoints": 3.887.0 - "@aws-sdk/util-user-agent-browser": 3.887.0 - "@aws-sdk/util-user-agent-node": 3.888.0 - "@smithy/config-resolver": ^4.2.1 - "@smithy/core": ^3.11.0 - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/hash-node": ^4.1.1 - "@smithy/invalid-dependency": ^4.1.1 - "@smithy/middleware-content-length": ^4.1.1 - "@smithy/middleware-endpoint": ^4.2.1 - "@smithy/middleware-retry": ^4.2.1 - "@smithy/middleware-serde": ^4.1.1 - "@smithy/middleware-stack": ^4.1.1 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-body-length-node": ^4.1.0 - "@smithy/util-defaults-mode-browser": ^4.1.1 - "@smithy/util-defaults-mode-node": ^4.1.1 - "@smithy/util-endpoints": ^3.1.1 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-retry": ^4.1.1 - "@smithy/util-utf8": ^4.1.0 - "@smithy/util-waiter": ^4.1.1 - tslib: ^2.6.2 - checksum: 818bd91245081edb2e16d3e8c05f0c9a74868dd46b9f3fa1b4d57496636961a3a09ce7837471abaebe0e2697c7732366d5af3b8d9b9ece65c4d3c0a7e1419619 - languageName: node - linkType: hard - -"@aws-sdk/client-sso@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/client-sso@npm:3.888.0" - dependencies: - "@aws-crypto/sha256-browser": 5.2.0 - "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.888.0 - "@aws-sdk/middleware-host-header": 3.887.0 - "@aws-sdk/middleware-logger": 3.887.0 - "@aws-sdk/middleware-recursion-detection": 3.887.0 - "@aws-sdk/middleware-user-agent": 3.888.0 - "@aws-sdk/region-config-resolver": 3.887.0 - "@aws-sdk/types": 3.887.0 - "@aws-sdk/util-endpoints": 3.887.0 - "@aws-sdk/util-user-agent-browser": 3.887.0 - "@aws-sdk/util-user-agent-node": 3.888.0 - "@smithy/config-resolver": ^4.2.1 - "@smithy/core": ^3.11.0 - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/hash-node": ^4.1.1 - "@smithy/invalid-dependency": ^4.1.1 - "@smithy/middleware-content-length": ^4.1.1 - "@smithy/middleware-endpoint": ^4.2.1 - "@smithy/middleware-retry": ^4.2.1 - "@smithy/middleware-serde": ^4.1.1 - "@smithy/middleware-stack": ^4.1.1 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-body-length-node": ^4.1.0 - "@smithy/util-defaults-mode-browser": ^4.1.1 - "@smithy/util-defaults-mode-node": ^4.1.1 - "@smithy/util-endpoints": ^3.1.1 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-retry": ^4.1.1 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: 0aa68ee0144cf56c31034c520c39fd8c53b73083bd6ce1ad0ac32ecbefd497e280b5638a00b8078c26e4687b4a083161468b94f4d79d0e51132c98044d2628ab - languageName: node - linkType: hard - -"@aws-sdk/core@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/core@npm:3.888.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@aws-sdk/xml-builder": 3.887.0 - "@smithy/core": ^3.11.0 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/property-provider": ^4.0.5 - "@smithy/protocol-http": ^5.2.1 - "@smithy/signature-v4": ^5.1.3 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-utf8": ^4.1.0 - fast-xml-parser: 5.2.5 - tslib: ^2.6.2 - checksum: baf26845beaf66f796130337365e2992751e37fd632ea75ad0bfc8f955aea704c69112fc107a0c13a5af7e932707c3a40fc490c9634cdda4acf6050f5ca63deb - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-env@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 4c5012bcb95966db2a72ad7700fc3b5bbb4f7e4dea43f215b972b2d868ed40c8b7c7d1cec4fe53b0bda9b5f6c142480716561707609022f0fd91f033c2450a9c - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-http@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/property-provider": ^4.0.5 - "@smithy/protocol-http": ^5.2.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/util-stream": ^4.3.1 - tslib: ^2.6.2 - checksum: cd83cae0e01c65bc91ff922670d5c1933463726bbb44a68c6ee726f6b0799dc8d596ca7ef15e1abfb7fb9c88322f337e2bd303f65d66dfd5859055be35061d86 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-ini@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/credential-provider-env": 3.888.0 - "@aws-sdk/credential-provider-http": 3.888.0 - "@aws-sdk/credential-provider-process": 3.888.0 - "@aws-sdk/credential-provider-sso": 3.888.0 - "@aws-sdk/credential-provider-web-identity": 3.888.0 - "@aws-sdk/nested-clients": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/credential-provider-imds": ^4.0.7 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: aa551d529f378ef9558a16ea01e043f742646f38347469e2b1cbe3e2e094ca30cd272911750c62dd56908c9ff704c459014f6fbf3a25fd61e8f0e7e61f3a41bb - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-node@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.888.0" - dependencies: - "@aws-sdk/credential-provider-env": 3.888.0 - "@aws-sdk/credential-provider-http": 3.888.0 - "@aws-sdk/credential-provider-ini": 3.888.0 - "@aws-sdk/credential-provider-process": 3.888.0 - "@aws-sdk/credential-provider-sso": 3.888.0 - "@aws-sdk/credential-provider-web-identity": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/credential-provider-imds": ^4.0.7 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: cac63c05516ebf645068f8f68f1932db4691b1368ceced7260cd6ad6b10e4bf6be30962c150e3db69aab86e31609576610b85e62293fc4b4c71b4c96991e9ada - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-process@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 51290738eb782230758767994c677bec5a7da72756b7a780e5eaff04ed2812d7612e74df90892eac89c1f06ad164f2c657da0d999a786158e7e4af972a9dc7e0 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-sso@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.888.0" - dependencies: - "@aws-sdk/client-sso": 3.888.0 - "@aws-sdk/core": 3.888.0 - "@aws-sdk/token-providers": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 69e040bd12cea21134669ce8635741a754c940e5c9b053bf208d498b7878ca35ed047405eddf8264c8e44f09258166c8701b75776aa9002f8fc28e6b9a498580 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-web-identity@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/nested-clients": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: f4a6855190f47b00c5150d8e89c588e2beb65232829a4e2cef398aab2fddd775124541cead84c4ae5b59f1cabd4e566127ae23cb909841ce8e34a2d8f4fbc623 - languageName: node - linkType: hard - -"@aws-sdk/middleware-host-header@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: f07a901c5165d8eaf831bc0968f12c77c2b74cde53c7a6f61caadc87578172be162e4e0df6fdf7df0a182d282716603f01b4d818b2f2ba2856ad0ecb82de7816 - languageName: node - linkType: hard - -"@aws-sdk/middleware-logger@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/middleware-logger@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 6f4a95ed164378d6104207ec6b0da8d61452a74a67c95156e42be33d00f29daa53badc7a0461f269223eaeb0d5eff520d8fc4e25cc615657c0d5a897dbd7546f - languageName: node - linkType: hard - -"@aws-sdk/middleware-recursion-detection@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@aws/lambda-invoke-store": ^0.0.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: c8cdef1bcbe1228b918c6fa8fd7f149fb46c0004ee661b04138d95f167eeae9abfac68ca5597b70fa501efc292024ce7369161459cdcb2f6615587c428c6baac - languageName: node - linkType: hard - -"@aws-sdk/middleware-user-agent@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@aws-sdk/util-endpoints": 3.887.0 - "@smithy/core": ^3.11.0 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 17eeaa35c7a9b4e0505e7d5feb705c41dbdcdf4809ef39562fa8bd6e964ef5b9d3669eb6f307e535ce3f7a00c466b4080948a822ee9d7e14fa2c4257dc0c5eb3 - languageName: node - linkType: hard - -"@aws-sdk/nested-clients@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/nested-clients@npm:3.888.0" - dependencies: - "@aws-crypto/sha256-browser": 5.2.0 - "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.888.0 - "@aws-sdk/middleware-host-header": 3.887.0 - "@aws-sdk/middleware-logger": 3.887.0 - "@aws-sdk/middleware-recursion-detection": 3.887.0 - "@aws-sdk/middleware-user-agent": 3.888.0 - "@aws-sdk/region-config-resolver": 3.887.0 - "@aws-sdk/types": 3.887.0 - "@aws-sdk/util-endpoints": 3.887.0 - "@aws-sdk/util-user-agent-browser": 3.887.0 - "@aws-sdk/util-user-agent-node": 3.888.0 - "@smithy/config-resolver": ^4.2.1 - "@smithy/core": ^3.11.0 - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/hash-node": ^4.1.1 - "@smithy/invalid-dependency": ^4.1.1 - "@smithy/middleware-content-length": ^4.1.1 - "@smithy/middleware-endpoint": ^4.2.1 - "@smithy/middleware-retry": ^4.2.1 - "@smithy/middleware-serde": ^4.1.1 - "@smithy/middleware-stack": ^4.1.1 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-body-length-node": ^4.1.0 - "@smithy/util-defaults-mode-browser": ^4.1.1 - "@smithy/util-defaults-mode-node": ^4.1.1 - "@smithy/util-endpoints": ^3.1.1 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-retry": ^4.1.1 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: 699aaea06f8d0fe720470003ec70ede15e8781d50dbf28ed827ed7dd85318b3684995996859c1c5e0350ba9829f39f6721f1229b2c0e06f2a0e4cf77fee89f4b - languageName: node - linkType: hard - -"@aws-sdk/region-config-resolver@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-config-provider": ^4.0.0 - "@smithy/util-middleware": ^4.1.1 - tslib: ^2.6.2 - checksum: aced1bf4e3dce92fa76337a774551cf88e72a25e44f7582a9897ce52e73d309791fab22ba4900f364715afc73190c9e5a1d8934077aa04a63d8ef9cd9bf3f4ad - languageName: node - linkType: hard - -"@aws-sdk/token-providers@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/token-providers@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/nested-clients": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 8e2e6ac2fc480f6d1b38a3563f274d2096bc7aad1ea46e875ce08955c7bb37b8c3f2ce7c457f414af94b5d7053499589909f15ceb5de8c28bd9a596c24b6fa6c - languageName: node - linkType: hard - -"@aws-sdk/types@npm:3.887.0, @aws-sdk/types@npm:^3.222.0": - version: 3.887.0 - resolution: "@aws-sdk/types@npm:3.887.0" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 141d3fcd3bf5b95e13df81b8cf1554f2cc2f4783922265ea344ab60105ea4453a9b4fae7df5da8652f9ede9e83fba8b06bc1c95566329d0541810d711ff1dad9 - languageName: node - linkType: hard - -"@aws-sdk/util-endpoints@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/util-endpoints@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-endpoints": ^3.1.1 - tslib: ^2.6.2 - checksum: aced26165e63871ac44e0cd9393729cb437d8b2f277c34cc45d51c9964e43c5bea4762c948ee04e9a93c5d98b037923de23d0b69973f256480f533285d0db45d +"@aashutoshrathi/word-wrap@npm:^1.2.3": + version: 1.2.6 + resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" + checksum: ada901b9e7c680d190f1d012c84217ce0063d8f5c5a7725bb91ec3c5ed99bb7572680eb2d2938a531ccbaec39a95422fcd8a6b4a13110c7d98dd75402f66a0cd languageName: node linkType: hard -"@aws-sdk/util-locate-window@npm:^3.0.0": - version: 3.873.0 - resolution: "@aws-sdk/util-locate-window@npm:3.873.0" - dependencies: - tslib: ^2.6.2 - checksum: ff98e8fa00504ae62bf25605e708ac77693b11b628e0234b0a5bd03e6021e0ca12677ea494b1463c2ef70b483b5b30b2a08dfe5806788a570b3d7becae15591e - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-browser@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/types": ^4.5.0 - bowser: ^2.11.0 - tslib: ^2.6.2 - checksum: 18c5f77fd5e60129c7944c7f2d8b5b6c61783c12d59492193b25dcb6631d1c48896d5ffdec4ffd579ed75ae781c8fb91747e25cf4e7927b6f37b41b059e3035c +"@adobe/css-tools@npm:^4.0.1": + version: 4.3.3 + resolution: "@adobe/css-tools@npm:4.3.3" + checksum: d21f3786b84911fee59c995a146644a85c98692979097b26484ffa9e442fb1a92ccd68ce984e3e7cf8d5933c3560fbc0ad3e3cd1de50b9a723d1c012e793bbcb languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.888.0" +"@ampproject/remapping@npm:^2.2.0": + version: 2.3.0 + resolution: "@ampproject/remapping@npm:2.3.0" dependencies: - "@aws-sdk/middleware-user-agent": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - peerDependencies: - aws-crt: ">=1.0.0" - peerDependenciesMeta: - aws-crt: - optional: true - checksum: f2e273f44e078aeeaad678a592a69c315e0307a557f48759cba5d78f2ae501faed18c2497ea27e35796a11642ea6f9eeff2629947db07621b3a553e7fc81884c + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: d3ad7b89d973df059c4e8e6d7c972cbeb1bb2f18f002a3bd04ae0707da214cb06cc06929b65aa2313b9347463df2914772298bae8b1d7973f246bb3f2ab3e8f0 languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/xml-builder@npm:3.887.0" +"@babel/code-frame@npm:7.10.4": + version: 7.10.4 + resolution: "@babel/code-frame@npm:7.10.4" dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: c2937d705a6ba6e3635279532eb984548117086520e9569df97ce400c6d7b9d1a74b47e720089857e2e5bd2a68f2b8273e746a79938ece0b875cca5b7ddbd844 - languageName: node - linkType: hard - -"@aws/lambda-invoke-store@npm:^0.0.1": - version: 0.0.1 - resolution: "@aws/lambda-invoke-store@npm:0.0.1" - checksum: af732ba2cd343daa49d4933827b4bdc80449641fbdf465ad4a97a818adf6f355454942a2b59a6a297c261c1b3fff11ea69c93b9564ed5e33fcdcf30f993c722d + "@babel/highlight": ^7.10.4 + checksum: feb4543c8a509fe30f0f6e8d7aa84f82b41148b963b826cd330e34986f649a85cb63b2f13dd4effdf434ac555d16f14940b8ea5f4433297c2f5ff85486ded019 languageName: node linkType: hard @@ -525,354 +47,397 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.8.3": - version: 7.27.1 - resolution: "@babel/code-frame@npm:7.27.1" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.1, @babel/code-frame@npm:^7.24.2, @babel/code-frame@npm:^7.5.5": + version: 7.24.2 + resolution: "@babel/code-frame@npm:7.24.2" dependencies: - "@babel/helper-validator-identifier": ^7.27.1 - js-tokens: ^4.0.0 - picocolors: ^1.1.1 - checksum: 5874edc5d37406c4a0bb14cf79c8e51ad412fb0423d176775ac14fc0259831be1bf95bdda9c2aa651126990505e09a9f0ed85deaa99893bc316d2682c5115bdc + "@babel/highlight": ^7.24.2 + picocolors: ^1.0.0 + checksum: 70e867340cfe09ca5488b2f36372c45cabf43c79a5b6426e6df5ef0611ff5dfa75a57dda841895693de6008f32c21a7c97027a8c7bcabd63a7d17416cbead6f8 languageName: node linkType: hard -"@babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7, @babel/compat-data@npm:^7.28.0": - version: 7.28.4 - resolution: "@babel/compat-data@npm:7.28.4" - checksum: 9f6f5289bbe5a29e3f9c737577a797205a91f19371b50af8942257d9cb590d44eb950154e4f2a3d5de4105f97a49d6fbc8daebe0db1e6eee04f5a4bf73536bfc +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.23.5, @babel/compat-data@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/compat-data@npm:7.24.4" + checksum: 52ce371658dc7796c9447c9cb3b9c0659370d141b76997f21c5e0028cca4d026ca546b84bc8d157ce7ca30bd353d89f9238504eb8b7aefa9b1f178b4c100c2d4 languageName: node linkType: hard -"@babel/core@npm:^7.1.0, @babel/core@npm:^7.11.1, @babel/core@npm:^7.12.3, @babel/core@npm:^7.16.0, @babel/core@npm:^7.20.5, @babel/core@npm:^7.28.0, @babel/core@npm:^7.7.2, @babel/core@npm:^7.8.0": - version: 7.28.4 - resolution: "@babel/core@npm:7.28.4" +"@babel/core@npm:7.12.3": + version: 7.12.3 + resolution: "@babel/core@npm:7.12.3" dependencies: - "@babel/code-frame": ^7.27.1 - "@babel/generator": ^7.28.3 - "@babel/helper-compilation-targets": ^7.27.2 - "@babel/helper-module-transforms": ^7.28.3 - "@babel/helpers": ^7.28.4 - "@babel/parser": ^7.28.4 - "@babel/template": ^7.27.2 - "@babel/traverse": ^7.28.4 - "@babel/types": ^7.28.4 - "@jridgewell/remapping": ^2.3.5 + "@babel/code-frame": ^7.10.4 + "@babel/generator": ^7.12.1 + "@babel/helper-module-transforms": ^7.12.1 + "@babel/helpers": ^7.12.1 + "@babel/parser": ^7.12.3 + "@babel/template": ^7.10.4 + "@babel/traverse": ^7.12.1 + "@babel/types": ^7.12.1 + convert-source-map: ^1.7.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.1 + json5: ^2.1.2 + lodash: ^4.17.19 + resolve: ^1.3.2 + semver: ^5.4.1 + source-map: ^0.5.0 + checksum: 29ee14dd7ae66c1af84d1b2864e1e9e1bec23b89f41e414917b10151ae1fcb6d3b6a8a25d028a7e22dba3bb7b69eb1f7f0d844797341357e36fa71ff967fb4a5 + languageName: node + linkType: hard + +"@babel/core@npm:^7.1.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.16.0, @babel/core@npm:^7.20.5, @babel/core@npm:^7.23.5, @babel/core@npm:^7.7.5, @babel/core@npm:^7.8.4": + version: 7.24.4 + resolution: "@babel/core@npm:7.24.4" + dependencies: + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.24.2 + "@babel/generator": ^7.24.4 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helpers": ^7.24.4 + "@babel/parser": ^7.24.4 + "@babel/template": ^7.24.0 + "@babel/traverse": ^7.24.1 + "@babel/types": ^7.24.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 - checksum: f55b90b2c61a6461f5c0ccab74d32af9c67448c43c629529ba7ec3c61d87fa8c408cc9305bfb1f5b09e671d25436d44eaf75c48dee5dc0a5c5e21c01290f5134 + checksum: 15ecad7581f3329995956ba461961b1af7bed48901f14fe962ccd3217edca60049e9e6ad4ce48134618397e6c90230168c842e2c28e47ef1f16c97dbbf663c61 languageName: node linkType: hard -"@babel/eslint-parser@npm:^7.16.3": - version: 7.28.4 - resolution: "@babel/eslint-parser@npm:7.28.4" +"@babel/generator@npm:^7.12.1, @babel/generator@npm:^7.24.1, @babel/generator@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/generator@npm:7.24.4" dependencies: - "@nicolo-ribaudo/eslint-scope-5-internals": 5.1.1-v1 - eslint-visitor-keys: ^2.1.0 - semver: ^6.3.1 - peerDependencies: - "@babel/core": ^7.11.0 - eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - checksum: 32fb41c8648e169bc8570e25b4657475e165e1a49b8c6610f9bf86f311bbcc8dfa73f004977015688763aa6af17f48c690720bbc7b7b99695557adb267a9a7ff + "@babel/types": ^7.24.0 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + jsesc: ^2.5.1 + checksum: 1b6146c31386c9df3eb594a2c36b5c98da4f67f7c06edb3d68a442b92516b21bb5ba3ad7dbe0058fe76625ed24d66923e15c95b0df75ef1907d4068921a699b8 languageName: node linkType: hard -"@babel/generator@npm:^7.28.3, @babel/generator@npm:^7.7.2": - version: 7.28.3 - resolution: "@babel/generator@npm:7.28.3" +"@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" dependencies: - "@babel/parser": ^7.28.3 - "@babel/types": ^7.28.2 - "@jridgewell/gen-mapping": ^0.3.12 - "@jridgewell/trace-mapping": ^0.3.28 - jsesc: ^3.0.2 - checksum: e2202bf2b9c8a94f7e7a0a049fda0ee037d055c46922e85afa3bbc53309113f859b8193894f991045d7865226028b8f4f06152ed315ab414451932016dba5e42 + "@babel/types": ^7.22.5 + checksum: 53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": - version: 7.27.3 - resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" +"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15" dependencies: - "@babel/types": ^7.27.3 - checksum: 63863a5c936ef82b546ca289c9d1b18fabfc24da5c4ee382830b124e2e79b68d626207febc8d4bffc720f50b2ee65691d7d12cc0308679dee2cd6bdc926b7190 + "@babel/types": ^7.22.15 + checksum: 639c697a1c729f9fafa2dd4c9af2e18568190299b5907bd4c2d0bc818fcbd1e83ffeecc2af24327a7faa7ac4c34edd9d7940510a5e66296c19bad17001cf5c7a languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2": - version: 7.27.2 - resolution: "@babel/helper-compilation-targets@npm:7.27.2" +"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/helper-compilation-targets@npm:7.23.6" dependencies: - "@babel/compat-data": ^7.27.2 - "@babel/helper-validator-option": ^7.27.1 - browserslist: ^4.24.0 + "@babel/compat-data": ^7.23.5 + "@babel/helper-validator-option": ^7.23.5 + browserslist: ^4.22.2 lru-cache: ^5.1.1 semver: ^6.3.1 - checksum: 7b95328237de85d7af1dea010a4daa28e79f961dda48b652860d5893ce9b136fc8b9ea1f126d8e0a24963b09ba5c6631dcb907b4ce109b04452d34a6ae979807 + checksum: c630b98d4527ac8fe2c58d9a06e785dfb2b73ec71b7c4f2ddf90f814b5f75b547f3c015f110a010fd31f76e3864daaf09f3adcd2f6acdbfb18a8de3a48717590 languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.27.1, @babel/helper-create-class-features-plugin@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/helper-create-class-features-plugin@npm:7.28.3" +"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.24.1, @babel/helper-create-class-features-plugin@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/helper-create-class-features-plugin@npm:7.24.4" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.3 - "@babel/helper-member-expression-to-functions": ^7.27.1 - "@babel/helper-optimise-call-expression": ^7.27.1 - "@babel/helper-replace-supers": ^7.27.1 - "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 - "@babel/traverse": ^7.28.3 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-member-expression-to-functions": ^7.23.0 + "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-replace-supers": ^7.24.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 6d918e5e9c88ad1a262ab7b1a3caede1bbf95f8276c96846d8b0c1af251c85a0c868a9f1bbbaebdeb199e44dfd0e10fbe22935e56bedd1aa41ba4a7162bfa86c + checksum: 75b0a51ae1f7232932559779b78711c271404d02d069156d1bd9a7982c165c5134058d2ec2d8b5f2e42026ee4f52ba2a30c86a7aa3bce6b5fd0991eb721abc8c languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.27.1" +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.15, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": + version: 7.22.15 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.1 - regexpu-core: ^6.2.0 + "@babel/helper-annotate-as-pure": ^7.22.5 + regexpu-core: ^5.3.1 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 2ede6bbad0016a9262fd281ce8f1a5d69e6179dcec4ea282830e924c29a29b66b0544ecb92e4ef4acdaf2c4c990931d7dc442dbcd6a8bcec4bad73923ef70934 + checksum: 0243b8d4854f1dc8861b1029a46d3f6393ad72f366a5a08e36a4648aa682044f06da4c6e87a456260e1e1b33c999f898ba591a0760842c1387bcc93fbf2151a6 languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@npm:^0.6.5": - version: 0.6.5 - resolution: "@babel/helper-define-polyfill-provider@npm:0.6.5" +"@babel/helper-define-polyfill-provider@npm:^0.6.1, @babel/helper-define-polyfill-provider@npm:^0.6.2": + version: 0.6.2 + resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2" dependencies: - "@babel/helper-compilation-targets": ^7.27.2 - "@babel/helper-plugin-utils": ^7.27.1 - debug: ^4.4.1 + "@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.22.10 + resolve: ^1.14.2 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 9fd3b09b209c8ed0d3d8bc1f494f1368b9e1f6e46195af4ce948630fe97d7dafde4882eedace270b319bf6555ddf35e220c77505f6d634f621766cdccbba0aae + checksum: 2bba965ea9a4887ddf9c11d51d740ab473bd7597b787d042c325f6a45912dfe908c2d6bb1d837bf82f7e9fa51e6ad5150563c58131d2bb85515e63d971414a9c + languageName: node + linkType: hard + +"@babel/helper-environment-visitor@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-environment-visitor@npm:7.22.20" + checksum: d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69 languageName: node linkType: hard -"@babel/helper-globals@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/helper-globals@npm:7.28.0" - checksum: d8d7b91c12dad1ee747968af0cb73baf91053b2bcf78634da2c2c4991fb45ede9bd0c8f9b5f3254881242bc0921218fcb7c28ae885477c25177147e978ce4397 +"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/helper-function-name@npm:7.23.0" + dependencies: + "@babel/template": ^7.22.15 + "@babel/types": ^7.23.0 + checksum: e44542257b2d4634a1f979244eb2a4ad8e6d75eb6761b4cfceb56b562f7db150d134bc538c8e6adca3783e3bc31be949071527aa8e3aab7867d1ad2d84a26e10 + languageName: node + linkType: hard + +"@babel/helper-hoist-variables@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-hoist-variables@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: 394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-member-expression-to-functions@npm:7.27.1" +"@babel/helper-member-expression-to-functions@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/helper-member-expression-to-functions@npm:7.23.0" dependencies: - "@babel/traverse": ^7.27.1 - "@babel/types": ^7.27.1 - checksum: b13a3d120015a6fd2f6e6c2ff789cd12498745ef028710cba612cfb751b91ace700c3f96c1689228d1dcb41e9d4cf83d6dff8627dcb0c8da12d79440e783c6b8 + "@babel/types": ^7.23.0 + checksum: 494659361370c979ada711ca685e2efe9460683c36db1b283b446122596602c901e291e09f2f980ecedfe6e0f2bd5386cb59768285446530df10c14df1024e75 languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-module-imports@npm:7.27.1" +"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.24.1, @babel/helper-module-imports@npm:^7.24.3": + version: 7.24.3 + resolution: "@babel/helper-module-imports@npm:7.24.3" dependencies: - "@babel/traverse": ^7.27.1 - "@babel/types": ^7.27.1 - checksum: 92d01c71c0e4aacdc2babce418a9a1a27a8f7d770a210ffa0f3933f321befab18b655bc1241bebc40767516731de0b85639140c42e45a8210abe1e792f115b28 + "@babel/types": ^7.24.0 + checksum: c23492189ba97a1ec7d37012336a5661174e8b88194836b6bbf90d13c3b72c1db4626263c654454986f924c6da8be7ba7f9447876d709cd00bd6ffde6ec00796 languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/helper-module-transforms@npm:7.28.3" +"@babel/helper-module-transforms@npm:^7.12.1, @babel/helper-module-transforms@npm:^7.23.3": + version: 7.23.3 + resolution: "@babel/helper-module-transforms@npm:7.23.3" dependencies: - "@babel/helper-module-imports": ^7.27.1 - "@babel/helper-validator-identifier": ^7.27.1 - "@babel/traverse": ^7.28.3 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-module-imports": ^7.22.15 + "@babel/helper-simple-access": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/helper-validator-identifier": ^7.22.20 peerDependencies: "@babel/core": ^7.0.0 - checksum: 7cf7b79da0fa626d6c84bfc7b35c079a2559caecaa2ff645b0f1db0d741507aa4df6b5b98a3283e8ac4e89094af271d805bf5701e5c4f916e622797b7c8cbb18 + checksum: 5d0895cfba0e16ae16f3aa92fee108517023ad89a855289c4eb1d46f7aef4519adf8e6f971e1d55ac20c5461610e17213f1144097a8f932e768a9132e2278d71 languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" +"@babel/helper-optimise-call-expression@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" dependencies: - "@babel/types": ^7.27.1 - checksum: 0fb7ee824a384529d6b74f8a58279f9b56bfe3cce332168067dddeab2552d8eeb56dc8eaf86c04a3a09166a316cb92dfc79c4c623cd034ad4c563952c98b464f + "@babel/types": ^7.22.5 + checksum: c70ef6cc6b6ed32eeeec4482127e8be5451d0e5282d5495d5d569d39eb04d7f1d66ec99b327f45d1d5842a9ad8c22d48567e93fc502003a47de78d122e355f7c languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0": - version: 7.27.1 - resolution: "@babel/helper-plugin-utils@npm:7.27.1" - checksum: 5d715055301badab62bdb2336075a77f8dc8bd290cad2bc1b37ea3bf1b3efc40594d308082229f239deb4d6b5b80b0a73bce000e595ea74416e0339c11037047 +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": + version: 7.24.0 + resolution: "@babel/helper-plugin-utils@npm:7.24.0" + checksum: e2baa0eede34d2fa2265947042aa84d444aa48dc51e9feedea55b67fc1bc3ab051387e18b33ca7748285a6061390831ab82f8a2c767d08470b93500ec727e9b9 languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" +"@babel/helper-remap-async-to-generator@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.1 - "@babel/helper-wrap-function": ^7.27.1 - "@babel/traverse": ^7.27.1 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-wrap-function": ^7.22.20 peerDependencies: "@babel/core": ^7.0.0 - checksum: 0747397ba013f87dbf575454a76c18210d61c7c9af0f697546b4bcac670b54ddc156330234407b397f0c948738c304c228e0223039bc45eab4fbf46966a5e8cc + checksum: 2fe6300a6f1b58211dffa0aed1b45d4958506d096543663dba83bd9251fe8d670fa909143a65b45e72acb49e7e20fbdb73eae315d9ddaced467948c3329986e7 languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-replace-supers@npm:7.27.1" +"@babel/helper-replace-supers@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/helper-replace-supers@npm:7.24.1" dependencies: - "@babel/helper-member-expression-to-functions": ^7.27.1 - "@babel/helper-optimise-call-expression": ^7.27.1 - "@babel/traverse": ^7.27.1 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-member-expression-to-functions": ^7.23.0 + "@babel/helper-optimise-call-expression": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0 - checksum: 3690266c304f21008690ba68062f889a363583cabc13c3d033b94513953147af3e0a3fdb48fa1bb9fa3734b64e221fc65e5222ab70837f02321b7225f487c6ef + checksum: c04182c34a3195c6396de2f2945f86cb60daa94ca7392db09bd8b0d4e7a15b02fbe1947c70f6062c87eadaea6d7135207129efa35cf458ea0987bab8c0f02d5a + languageName: node + linkType: hard + +"@babel/helper-simple-access@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-simple-access@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: fe9686714caf7d70aedb46c3cce090f8b915b206e09225f1e4dbc416786c2fdbbee40b38b23c268b7ccef749dd2db35f255338fb4f2444429874d900dede5ad2 + languageName: node + linkType: hard + +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0, @babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: 1012ef2295eb12dc073f2b9edf3425661e9b8432a3387e62a8bc27c42963f1f216ab3124228015c748770b2257b4f1fda882ca8fa34c0bf485e929ae5bc45244 languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0, @babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" +"@babel/helper-split-export-declaration@npm:^7.22.6": + version: 7.22.6 + resolution: "@babel/helper-split-export-declaration@npm:7.22.6" dependencies: - "@babel/traverse": ^7.27.1 - "@babel/types": ^7.27.1 - checksum: 4f380c5d0e0769fa6942a468b0c2d7c8f0c438f941aaa88f785f8752c103631d0904c7b4e76207a3b0e6588b2dec376595370d92ca8f8f1b422c14a69aa146d4 + "@babel/types": ^7.22.5 + checksum: e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921 languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-string-parser@npm:7.27.1" - checksum: 0a8464adc4b39b138aedcb443b09f4005d86207d7126e5e079177e05c3116107d856ec08282b365e9a79a9872f40f4092a6127f8d74c8a01c1ef789dacfc25d6 +"@babel/helper-string-parser@npm:^7.23.4": + version: 7.24.1 + resolution: "@babel/helper-string-parser@npm:7.24.1" + checksum: 8404e865b06013979a12406aab4c0e8d2e377199deec09dfe9f57b833b0c9ce7b6e8c1c553f2da8d0bcd240c5005bd7a269f4fef0d628aeb7d5fe035c436fb67 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.25.9, @babel/helper-validator-identifier@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-validator-identifier@npm:7.27.1" - checksum: 3c7e8391e59d6c85baeefe9afb86432f2ab821c6232b00ea9082a51d3e7e95a2f3fb083d74dc1f49ac82cf238e1d2295dafcb001f7b0fab479f3f56af5eaaa47 +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-validator-option@npm:7.27.1" - checksum: db73e6a308092531c629ee5de7f0d04390835b21a263be2644276cb27da2384b64676cab9f22cd8d8dbd854c92b1d7d56fc8517cf0070c35d1c14a8c828b0903 +"@babel/helper-validator-option@npm:^7.23.5": + version: 7.23.5 + resolution: "@babel/helper-validator-option@npm:7.23.5" + checksum: 537cde2330a8aede223552510e8a13e9c1c8798afee3757995a7d4acae564124fe2bf7e7c3d90d62d3657434a74340a274b3b3b1c6f17e9a2be1f48af29cb09e languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.27.1": - version: 7.28.3 - resolution: "@babel/helper-wrap-function@npm:7.28.3" +"@babel/helper-wrap-function@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-wrap-function@npm:7.22.20" dependencies: - "@babel/template": ^7.27.2 - "@babel/traverse": ^7.28.3 - "@babel/types": ^7.28.2 - checksum: 0ebdfdc918fdd0c1cf6ff15ba4c664974d0cdf21a017af560d58b00c379df3bf2e55f13a44fe3225668bca169da174f6cb97a96c4e987fb728fdb8f9a39db302 + "@babel/helper-function-name": ^7.22.5 + "@babel/template": ^7.22.15 + "@babel/types": ^7.22.19 + checksum: 221ed9b5572612aeb571e4ce6a256f2dee85b3c9536f1dd5e611b0255e5f59a3d0ec392d8d46d4152149156a8109f92f20379b1d6d36abb613176e0e33f05fca languageName: node linkType: hard -"@babel/helpers@npm:^7.28.4": - version: 7.28.4 - resolution: "@babel/helpers@npm:7.28.4" +"@babel/helpers@npm:^7.12.1, @babel/helpers@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/helpers@npm:7.24.4" dependencies: - "@babel/template": ^7.27.2 - "@babel/types": ^7.28.4 - checksum: a8706219e0bd60c18bbb8e010aa122e9b14e7e7e67c21cc101e6f1b5e79dcb9a18d674f655997f85daaf421aa138cf284710bb04371a2255a0a3137f097430b4 + "@babel/template": ^7.24.0 + "@babel/traverse": ^7.24.1 + "@babel/types": ^7.24.0 + checksum: ecd2dc0b3b32e24b97fa3bcda432dd3235b77c2be1e16eafc35b8ef8f6c461faa99796a8bc2431a408c98b4aabfd572c160e2b67ecea4c5c9dd3a8314a97994a languageName: node linkType: hard -"@babel/highlight@npm:^7.10.4": - version: 7.25.9 - resolution: "@babel/highlight@npm:7.25.9" +"@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.24.2": + version: 7.24.2 + resolution: "@babel/highlight@npm:7.24.2" dependencies: - "@babel/helper-validator-identifier": ^7.25.9 + "@babel/helper-validator-identifier": ^7.22.20 chalk: ^2.4.2 js-tokens: ^4.0.0 picocolors: ^1.0.0 - checksum: a6e0ac0a1c4bef7401915ca3442ab2b7ae4adf360262ca96b91396bfb9578abb28c316abf5e34460b780696db833b550238d9256bdaca60fade4ba7a67645064 + checksum: 5f17b131cc3ebf3ab285a62cf98a404aef1bd71a6be045e748f8d5bf66d6a6e1aefd62f5972c84369472e8d9f22a614c58a89cd331eb60b7ba965b31b1bbeaf5 languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": - version: 7.28.4 - resolution: "@babel/parser@npm:7.28.4" - dependencies: - "@babel/types": ^7.28.4 +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.3, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.7.0": + version: 7.24.4 + resolution: "@babel/parser@npm:7.24.4" bin: parser: ./bin/babel-parser.js - checksum: d95e283fe1153039b396926ef567ca1ab114afb5c732a23bbcbbd0465ac59971aeb6a63f37593ce7671a52d34ec52b23008c999d68241b42d26928c540464063 - languageName: node - linkType: hard - -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.27.1" - dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/traverse": ^7.27.1 - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 72f24b9487e445fa61cf8be552aad394a648c2bb445c38d39d1df003186d9685b87dd8d388c950f438ea0ca44c82099d9c49252fb681c719cc72edf02bbe0304 + checksum: 94c9e3e592894cd6fc57c519f4e06b65463df9be5f01739bb0d0bfce7ffcf99b3c2fdadd44dc59cc858ba2739ce6e469813a941c2f2dfacf333a3b2c9c5c8465 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.27.1" +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.24.4" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: eb7f4146dc01f1198ce559a90b077e58b951a07521ec414e3c7d4593bf6c4ab5c2af22242a7e9fec085e20299e0ba6ea97f44a45e84ab148141bf9eb959ad25e + checksum: 0be3f41b1b865d7a4ed1a432337be48de67989d0b4e47def34a05097a804b6fc193115f97c954fd757339e0b80030ecf1d0a3d3fd6e7e91718644de0a5aae3d3 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.27.1" +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 621cfddfcc99a81e74f8b6f9101fd260b27500cb1a568e3ceae9cc8afe9aee45ac3bca3900a2b66c612b1a2366d29ef67d4df5a1c975be727eaad6906f98c2c6 + checksum: ec5fddc8db6de0e0082a883f21141d6f4f9f9f0bc190d662a732b5e9a506aae5d7d2337049a1bf055d7cb7add6f128036db6d4f47de5e9ac1be29e043c8b7ca8 languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.27.1" +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 - "@babel/plugin-transform-optional-chaining": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/plugin-transform-optional-chaining": ^7.24.1 peerDependencies: "@babel/core": ^7.13.0 - checksum: f07aa80272bd7a46b7ba11a4644da6c9b6a5a64e848dfaffdad6f02663adefd512e1aaebe664c4dd95f7ed4f80c872c7f8db8d8e34b47aae0930b412a28711a0 + checksum: e18235463e716ac2443938aaec3c18b40c417a1746fba0fa4c26cf4d71326b76ef26c002081ab1b445abfae98e063d561519aa55672dddc1ef80b3940211ffbb languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.28.3" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/traverse": ^7.28.3 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: c810e5d36030df6861ced35f0adbda7b4b41ac3e984422b32bee906564fd49374435f0a7a1a42eb0a9e6a5170c255f0ab31c163d5fc51fa5a816aa0420311029 + checksum: b5e5889ce5ef51e813e3063cd548f55eb3c88e925c3c08913f334e15d62496861e538ae52a3974e0c56a3044ed8fd5033faea67a64814324af56edc9865b7359 languageName: node linkType: hard @@ -889,15 +454,15 @@ __metadata: linkType: hard "@babel/plugin-proposal-decorators@npm:^7.16.4": - version: 7.28.0 - resolution: "@babel/plugin-proposal-decorators@npm:7.28.0" + version: 7.24.1 + resolution: "@babel/plugin-proposal-decorators@npm:7.24.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/plugin-syntax-decorators": ^7.27.1 + "@babel/helper-create-class-features-plugin": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-decorators": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b134907b09ba58f202c219de4eb6246a560441f9166f67b154c1dac32e8a6233e0f59ae9b4909dbd413e0c7dd0afb803a90a7a2fabc194e1b7543211a159eb87 + checksum: b9375c64656bf9ae6d2eeb965c40823e6447f0f4594979d037231884c0f3a92af97172087f35a05e90b8ca0ccb47551b013998e85853c1c634d47b341f4deece languageName: node linkType: hard @@ -959,7 +524,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-private-property-in-object@npm:^7.16.7": +"@babel/plugin-proposal-private-property-in-object@npm:^7.16.0": version: 7.21.11 resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.11" dependencies: @@ -995,7 +560,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-class-properties@npm:^7.12.13": +"@babel/plugin-syntax-class-properties@npm:^7.12.13, @babel/plugin-syntax-class-properties@npm:^7.8.3": version: 7.12.13 resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" dependencies: @@ -1017,51 +582,73 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-decorators@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-syntax-decorators@npm:7.27.1" +"@babel/plugin-syntax-decorators@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-decorators@npm:7.24.1" + dependencies: + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 5933fdb1d8d2c0b4b80621ad65dacd4e1ccd836041557c2ddc4cb4c1f46a347fa72977fc519695a801c9cca8b9aaf90d7895ddd52cb4e510fbef5b9f03cb9568 + languageName: node + linkType: hard + +"@babel/plugin-syntax-dynamic-import@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": ^7.8.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: ce307af83cf433d4ec42932329fad25fa73138ab39c7436882ea28742e1c0066626d224e0ad2988724c82644e41601cef607b36194f695cb78a1fcdc959637bd + languageName: node + linkType: hard + +"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c085b6083d9ce71f47563e05dddfff18a7611e376297b5a9eb35ef70e5919822f87bfba5b25276dfa55bdb6465943ba5d8d9a00f870611d63eaa1a148adc275e + checksum: 85740478be5b0de185228e7814451d74ab8ce0a26fcca7613955262a26e99e8e15e9da58f60c754b84515d4c679b590dbd3f2148f0f58025f4ae706f1c5a5d4a languageName: node linkType: hard -"@babel/plugin-syntax-flow@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-syntax-flow@npm:7.27.1" +"@babel/plugin-syntax-flow@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-flow@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7baca3171ed595d04c865b0ce46fca7f21900686df9d7fcd1017036ce78bb5483e33803de810831e68d39cf478953db69f49ae3f3de2e3207bc4ba49a96b6739 + checksum: 87dfe32f3a3ea77941034fb2a39fdfc9ea18a994b8df40c3659a11c8787b2bc5adea029259c4eafc03cd35f11628f6533aa2a06381db7fcbe3b2cc3c2a2bb54f languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.27.1" +"@babel/plugin-syntax-import-assertions@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: fb661d630808d67ecb85eabad25aac4e9696a20464bad4c4a6a0d3d40e4dc22557d47e9be3d591ec06429cf048cfe169b8891c373606344d51c4f3ac0f91d6d0 + checksum: 2a463928a63b62052e9fb8f8b0018aa11a926e94f32c168260ae012afe864875c6176c6eb361e13f300542c31316dad791b08a5b8ed92436a3095c7a0e4fce65 languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.24.7, @babel/plugin-syntax-import-attributes@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.27.1" +"@babel/plugin-syntax-import-attributes@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 97973982fff1bbf86b3d1df13380567042887c50e2ae13a400d02a8ff2c9742a60a75e279bfb73019e1cd9710f04be5e6ab81f896e6678dcfcec8b135e8896cf + checksum: 87c8aa4a5ef931313f956871b27f2c051556f627b97ed21e9a5890ca4906b222d89062a956cde459816f5e0dec185ff128d7243d3fdc389504522acb88f0464e languageName: node linkType: hard -"@babel/plugin-syntax-import-meta@npm:^7.10.4": +"@babel/plugin-syntax-import-meta@npm:^7.10.4, @babel/plugin-syntax-import-meta@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" dependencies: @@ -1083,18 +670,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-syntax-jsx@npm:7.27.1" +"@babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c6d1324cff286a369aa95d99b8abd21dd07821b5d3affd5fe7d6058c84cff9190743287826463ee57a7beecd10fa1e4bc99061df532ee14e188c1c8937b13e3a + checksum: 712f7e7918cb679f106769f57cfab0bc99b311032665c428b98f4c3e2e6d567601d45386a4f246df6a80d741e1f94192b3f008800d66c4f1daae3ad825c243f0 languageName: node linkType: hard -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" dependencies: @@ -1116,7 +703,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-numeric-separator@npm:^7.10.4": +"@babel/plugin-syntax-numeric-separator@npm:^7.10.4, @babel/plugin-syntax-numeric-separator@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" dependencies: @@ -1171,7 +758,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-top-level-await@npm:^7.14.5": +"@babel/plugin-syntax-top-level-await@npm:^7.14.5, @babel/plugin-syntax-top-level-await@npm:^7.8.3": version: 7.14.5 resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" dependencies: @@ -1182,14 +769,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.27.1, @babel/plugin-syntax-typescript@npm:^7.7.2": - version: 7.27.1 - resolution: "@babel/plugin-syntax-typescript@npm:7.27.1" +"@babel/plugin-syntax-typescript@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-typescript@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 87836f7e32af624c2914c73cd6b9803cf324e07d43f61dbb973c6a86f75df725e12540d91fac7141c14b697aa9268fd064220998daced156e96ac3062d7afb41 + checksum: bf4bd70788d5456b5f75572e47a2e31435c7c4e43609bd4dffd2cc0c7a6cf90aabcf6cd389e351854de9a64412a07d30effef5373251fe8f6a4c9db0c0163bda languageName: node linkType: hard @@ -1205,820 +792,808 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" +"@babel/plugin-transform-arrow-functions@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 62c2cc0ae2093336b1aa1376741c5ed245c0987d9e4b4c5313da4a38155509a7098b5acce582b6781cc0699381420010da2e3086353344abe0a6a0ec38961eb7 + checksum: 58f9aa9b0de8382f8cfa3f1f1d40b69d98cd2f52340e2391733d0af745fdddda650ba392e509bc056157c880a2f52834a38ab2c5aa5569af8c61bb6ecbf45f34 languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.28.0" +"@babel/plugin-transform-async-generator-functions@npm:^7.24.3": + version: 7.24.3 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.24.3" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-remap-async-to-generator": ^7.27.1 - "@babel/traverse": ^7.28.0 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-remap-async-to-generator": ^7.22.20 + "@babel/plugin-syntax-async-generators": ^7.8.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 174aaccd7a8386fd7f32240c3f65a93cf60dcc5f6a2123cfbff44c0d22b424cd41de3a0c6d136b6a2fa60a8ca01550c261677284cb18a0daeab70730b2265f1d + checksum: 309af02610be65d937664435adb432a32d9b6eb42bb3d3232c377d27fbc57014774d931665a5bfdaff3d1841b72659e0ad7adcef84b709f251cb0b8444f19214 languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.27.1" +"@babel/plugin-transform-async-to-generator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.1" dependencies: - "@babel/helper-module-imports": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-remap-async-to-generator": ^7.27.1 + "@babel/helper-module-imports": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-remap-async-to-generator": ^7.22.20 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d79d7a7ae7d416f6a48200017d027a6ba94c09c7617eea8b4e9c803630f00094c1a4fc32bf20ce3282567824ce3fcbda51653aac4003c71ea4e681b331338979 + checksum: 429004a6596aa5c9e707b604156f49a146f8d029e31a3152b1649c0b56425264fda5fd38e5db1ddaeb33c3fe45c97dc8078d7abfafe3542a979b49f229801135 languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1" +"@babel/plugin-transform-block-scoped-functions@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7fb4988ca80cf1fc8345310d5edfe38e86b3a72a302675cdd09404d5064fe1d1fe1283ebe658ad2b71445ecef857bfb29a748064306b5f6c628e0084759c2201 + checksum: d8e18bd57b156da1cd4d3c1780ab9ea03afed56c6824ca8e6e74f67959d7989a0e953ec370fe9b417759314f2eef30c8c437395ce63ada2e26c2f469e4704f82 languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.28.0": - version: 7.28.4 - resolution: "@babel/plugin-transform-block-scoping@npm:7.28.4" +"@babel/plugin-transform-block-scoping@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/plugin-transform-block-scoping@npm:7.24.4" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7f62eae907c0b4f85b9cc024da949697e57d17f2107ca4a240011174762d4c546b856ccbd5ba83ecb4bc9eb50150ea46558d551a5b05d3f25aace88a65fa4e04 + checksum: 5229ffe1c55744b96f791521e2876b01ed05c81df67488a7453ce66c2faceb9d1d653089ce6f0abf512752e15e9acac0e75a797a860f24e05b4d36497c7c3183 languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-class-properties@npm:7.27.1" +"@babel/plugin-transform-class-properties@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-class-properties@npm:7.24.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-create-class-features-plugin": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 475a6e5a9454912fe1bdc171941976ca10ea4e707675d671cdb5ce6b6761d84d1791ac61b6bca81a2e5f6430cb7b9d8e4b2392404110e69c28207a754e196294 + checksum: 95779e9eef0c0638b9631c297d48aee53ffdbb2b1b5221bf40d7eccd566a8e34f859ff3571f8f20b9159b67f1bff7d7dc81da191c15d69fbae5a645197eae7e0 languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/plugin-transform-class-static-block@npm:7.28.3" +"@babel/plugin-transform-class-static-block@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/plugin-transform-class-static-block@npm:7.24.4" dependencies: - "@babel/helper-create-class-features-plugin": ^7.28.3 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-create-class-features-plugin": ^7.24.4 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-class-static-block": ^7.14.5 peerDependencies: "@babel/core": ^7.12.0 - checksum: 9b2feaacbf29637ab35a3aae1df35a1129adec5400a1767443739557fb0d3bf8278bf0ec90aacf43dec9a7dd91428d01375020b70528713e1bc36a72776a104c - languageName: node - linkType: hard - -"@babel/plugin-transform-classes@npm:^7.28.3": - version: 7.28.4 - resolution: "@babel/plugin-transform-classes@npm:7.28.4" - dependencies: - "@babel/helper-annotate-as-pure": ^7.27.3 - "@babel/helper-compilation-targets": ^7.27.2 - "@babel/helper-globals": ^7.28.0 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-replace-supers": ^7.27.1 - "@babel/traverse": ^7.28.4 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: f412e00c86584a9094cc0a2f3dd181b8108a4dced477d609c5406beddd5bf79d05a7ea74db508dc4dcb37172f042d5ef98d3d6311ade61c7ea6fbbbb70f5ec29 + checksum: 3b1db3308b57ba21d47772a9f183804234c23fd64c9ca40915d2d65c5dc7a48b49a6de16b8b90b7a354eacbb51232a862f0fca3dbd23e27d34641f511decddab languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" +"@babel/plugin-transform-classes@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-classes@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/template": ^7.27.1 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-replace-supers": ^7.24.1 + "@babel/helper-split-export-declaration": ^7.22.6 + globals: ^11.1.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 48bd20f7d631b08c51155751bf75b698d4a22cca36f41c22921ab92e53039c9ec5c3544e5282e18692325ef85d2e4a18c27e12c62b5e20c26fb0c92447e35224 + checksum: e5337e707d731c9f4dcc107d09c9a99b90786bc0da6a250165919587ed818818f6cae2bbcceea880abef975c0411715c0c7f3f361ecd1526bf2eaca5ad26bb00 languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/plugin-transform-destructuring@npm:7.28.0" +"@babel/plugin-transform-computed-properties@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-computed-properties@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/traverse": ^7.28.0 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/template": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5b464d6a03c6eaa1327b60ffc1630ca977db0256938b34e281e65c81c965680e930a6bac043272942d6d4bbd7d1eddded0b7231779429ba51275e092e7367859 + checksum: f2832bcf100a70f348facbb395873318ef5b9ee4b0fb4104a420d9daaeb6003cc2ecc12fd8083dd2e4a7c2da873272ad73ff94de4497125a0cf473294ef9664e languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.27.1" +"@babel/plugin-transform-destructuring@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-destructuring@npm:7.24.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2173e5b13f403538ffc6bd57b190cedf4caf320abc13a99e5b2721864e7148dbd3bd7c82d92377136af80432818f665fdd9a1fd33bc5549a4c91e24e5ce2413c + checksum: 994fd3c513e40b8f1bdfdd7104ebdcef7c6a11a4e380086074496f586db3ac04cba0ae70babb820df6363b6700747b0556f6860783e046ace7c741a22f49ec5b languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.27.1" +"@babel/plugin-transform-dotall-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-create-regexp-features-plugin": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ef2112d658338e3ff0827f39a53c0cfa211f1cbbe60363bca833a5269df389598ec965e7283600b46533c39cdca82307d0d69c0f518290ec5b00bb713044715b - languageName: node - linkType: hard - -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.27.1" - dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 2a109613535e6ac79240dced71429e988affd6a5b3d0cd0f563c8d6c208c51ce7bf2c300bc1150502376b26a51f279119b3358f1c0f2d2f8abca3bcd62e1ae46 + checksum: 7f623d25b6f213b94ebc1754e9e31c1077c8e288626d8b7bfa76a97b067ce80ddcd0ede402a546706c65002c0ccf45cd5ec621511c2668eed31ebcabe8391d35 languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.27.1" +"@babel/plugin-transform-duplicate-keys@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7a9fbc8d17148b7f11a1d1ca3990d2c2cd44bd08a45dcaf14f20a017721235b9044b20e6168b6940282bb1b48fb78e6afbdfb9dd9d82fde614e15baa7d579932 + checksum: a3b07c07cee441e185858a9bb9739bb72643173c18bf5f9f949dd2d4784ca124e56b01d0a270790fb1ff0cf75d436075db0a2b643fb4285ff9a21df9e8dc6284 languageName: node linkType: hard -"@babel/plugin-transform-explicit-resource-management@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/plugin-transform-explicit-resource-management@npm:7.28.0" +"@babel/plugin-transform-dynamic-import@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/plugin-transform-destructuring": ^7.28.0 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-dynamic-import": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a44140097ed4854883c426613f4e8763237cd0fdab1c780514f4315f6c148d6b528d7a57fe6fdec4dbce28a21b70393ef3507b72dfec2e30bfc8d7db1ff19474 + checksum: 59fc561ee40b1a69f969c12c6c5fac206226d6642213985a569dd0f99f8e41c0f4eaedebd36936c255444a8335079842274c42a975a433beadb436d4c5abb79b languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.27.1" +"@babel/plugin-transform-exponentiation-operator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-builder-binary-assignment-operator-visitor": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4ff4a0f30babc457a5ae8564deda209599627c2ce647284a0e8e66f65b44f6d968cf77761a4cc31b45b61693f0810479248c79e681681d8ccb39d0c52944c1fd + checksum: f90841fe1a1e9f680b4209121d3e2992f923e85efcd322b26e5901c180ef44ff727fb89790803a23fac49af34c1ce2e480018027c22b4573b615512ac5b6fc50 languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.27.1" +"@babel/plugin-transform-export-namespace-from@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-export-namespace-from": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 85082923eca317094f08f4953d8ea2a6558b3117826c0b740676983902b7236df1f4213ad844cb38c2dae104753dbe8f1cc51f01567835d476d32f5f544a4385 + checksum: bc710ac231919df9555331885748385c11c5e695d7271824fe56fba51dd637d48d3e5cd52e1c69f2b1a384fbbb41552572bc1ca3a2285ee29571f002e9bb2421 languageName: node linkType: hard "@babel/plugin-transform-flow-strip-types@npm:^7.16.0": - version: 7.27.1 - resolution: "@babel/plugin-transform-flow-strip-types@npm:7.27.1" + version: 7.24.1 + resolution: "@babel/plugin-transform-flow-strip-types@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/plugin-syntax-flow": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-flow": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0885028866fadefef35292d5a27f878d6a12b6f83778f8731481d4503b49c258507882a7de2aafda9b62d5f6350042f1a06355b998d5ed5e85d693bfcb77b939 + checksum: 83faac90c934e15a8fe813d90cbfdf8aa2cb2cc9108f55e4a1ecda1c3097735af6a0b6623057f059153b572bc1dd088aeb2ff24217e9de82ad2390ab1210d01b languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-for-of@npm:7.27.1" +"@babel/plugin-transform-for-of@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-for-of@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c9224e08de5d80b2c834383d4359aa9e519db434291711434dd996a4f86b7b664ad67b45d65459b7ec11fa582e3e11a3c769b8a8ca71594bdd4e2f0503f84126 + checksum: 990adde96ea1766ed6008c006c7040127bef59066533bb2977b246ea4a596fe450a528d1881a0db5f894deaf1b81654dfb494b19ad405b369be942738aa9c364 languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-function-name@npm:7.27.1" +"@babel/plugin-transform-function-name@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-function-name@npm:7.24.1" dependencies: - "@babel/helper-compilation-targets": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/traverse": ^7.27.1 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 26a2a183c3c52a96495967420a64afc5a09f743a230272a131668abf23001e393afa6371e6f8e6c60f4182bea210ed31d1caf866452d91009c1daac345a52f23 + checksum: 31eb3c75297dda7265f78eba627c446f2324e30ec0124a645ccc3e9f341254aaa40d6787bd62b2280d77c0a5c9fbfce1da2c200ef7c7f8e0a1b16a8eb3644c6f languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-json-strings@npm:7.27.1" +"@babel/plugin-transform-json-strings@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-json-strings@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-json-strings": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2c05a02f63b49f47069271b3405a66c3c8038de5b995b0700b1bd9a5e2bb3e67abd01e4604629302a521f4d8122a4233944aefa16559fd4373d256cc5d3da57f + checksum: f42302d42fc81ac00d14e9e5d80405eb80477d7f9039d7208e712d6bcd486a4e3b32fdfa07b5f027d6c773723d8168193ee880f93b0e430c828e45f104fb82a4 languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-literals@npm:7.27.1" +"@babel/plugin-transform-literals@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-literals@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0a76d12ab19f32dd139964aea7da48cecdb7de0b75e207e576f0f700121fe92367d788f328bf4fb44b8261a0f605c97b44e62ae61cddbb67b14e94c88b411f95 + checksum: 2df94e9478571852483aca7588419e574d76bde97583e78551c286f498e01321e7dbb1d0ef67bee16e8f950688f79688809cfde370c5c4b84c14d841a3ef217a languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.27.1" +"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2757955d81d65cc4701c17b83720745f6858f7a1d1d58117e379c204f47adbeb066b778596b6168bdbf4a22c229aab595d79a9abc261d0c6bfd62d4419466e73 + checksum: 895f2290adf457cbf327428bdb4fb90882a38a22f729bcf0629e8ad66b9b616d2721fbef488ac00411b647489d1dda1d20171bb3772d0796bb7ef5ecf057808a languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1" +"@babel/plugin-transform-member-expression-literals@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 804121430a6dcd431e6ffe99c6d1fbbc44b43478113b79c677629e7f877b4f78a06b69c6bfb2747fd84ee91879fe2eb32e4620b53124603086cf5b727593ebe8 + checksum: 4ea641cc14a615f9084e45ad2319f95e2fee01c77ec9789685e7e11a6c286238a426a98f9c1ed91568a047d8ac834393e06e8c82d1ff01764b7aa61bee8e9023 languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-modules-amd@npm:7.27.1" +"@babel/plugin-transform-modules-amd@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-amd@npm:7.24.1" dependencies: - "@babel/helper-module-transforms": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8bb36d448e438d5d30f4faf19120e8c18aa87730269e65d805bf6032824d175ed738057cc392c2c8a650028f1ae0f346cad8d6b723f31a037b586e2092a7be18 + checksum: 3d777c262f257e93f0405b13e178f9c4a0f31855b409f0191a76bb562a28c541326a027bfe6467fcb74752f3488c0333b5ff2de64feec1b3c4c6ace1747afa03 languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.27.1" +"@babel/plugin-transform-modules-commonjs@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.1" dependencies: - "@babel/helper-module-transforms": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-simple-access": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: bc45c1beff9b145c982bd6a614af338893d38bce18a9df7d658c9084e0d8114b286dcd0e015132ae7b15dd966153cb13321e4800df9766d0ddd892d22bf09d2a + checksum: 11402b34c49f76aa921b43c2d76f3f129a32544a1dc4f0d1e48b310f9036ab75269a6d8684ed0198b7a0b07bd7898b12f0cacceb26fbb167999fd2a819aa0802 languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.27.1" +"@babel/plugin-transform-modules-systemjs@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.24.1" dependencies: - "@babel/helper-module-transforms": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-validator-identifier": ^7.27.1 - "@babel/traverse": ^7.27.1 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-validator-identifier": ^7.22.20 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7c17a8973676c18525d87f277944616596f1b154cc2b9263bfd78ecdbf5f4288ec46c7f58017321ca3e3d6dfeb96875467b95311a39719b475d42a157525d87f + checksum: 903766f6808f04278e887e4adec9b1efa741726279652dad255eaad0f5701df8f8ff0af25eb8541a00eb3c9eae2dccf337b085cfa011426ca33ed1f95d70bf75 languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-modules-umd@npm:7.27.1" +"@babel/plugin-transform-modules-umd@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-umd@npm:7.24.1" dependencies: - "@babel/helper-module-transforms": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b007dd89231f2eeccf1c71a85629bcb692573303977a4b1c5f19a835ea6b5142c18ef07849bc6d752b874a11bc0ddf3c67468b77c8ee8310290b688a4f01ef31 + checksum: 4922f5056d34de6fd59a1ab1c85bc3472afa706c776aceeb886289c9ac9117e6eb8e22d06c537eb5bc0ede6c30f6bd85210bdcc150dc0ae2d2373f8252df9364 languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.27.1" +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-create-regexp-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0 - checksum: a711c92d9753df26cefc1792481e5cbff4fe4f32b383d76b25e36fa865d8023b1b9aa6338cf18f5c0e864c71a7fbe8115e840872ccd61a914d9953849c68de7d + checksum: 3ee564ddee620c035b928fdc942c5d17e9c4b98329b76f9cefac65c111135d925eb94ed324064cd7556d4f5123beec79abea1d4b97d1c8a2a5c748887a2eb623 languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-new-target@npm:7.27.1" +"@babel/plugin-transform-new-target@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-new-target@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 32c8078d843bda001244509442d68fd3af088d7348ba883f45c262b2c817a27ffc553b0d78e7f7a763271b2ece7fac56151baad7a91fb21f5bb1d2f38e5acad7 + checksum: f56159ba56e8824840b8073f65073434e4bc4ef20e366bc03aa6cae9a4389365574fa72390e48aed76049edbc6eba1181eb810e58fae22c25946c62f9da13db4 languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.27.1" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 1c6b3730748782d2178cc30f5cc37be7d7666148260f3f2dfc43999908bdd319bdfebaaf19cf04ac1f9dee0f7081093d3fa730cda5ae1b34bcd73ce406a78be7 + checksum: 74025e191ceb7cefc619c15d33753aab81300a03d81b96ae249d9b599bc65878f962d608f452462d3aad5d6e334b7ab2b09a6bdcfe8d101fe77ac7aacca4261e languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" +"@babel/plugin-transform-numeric-separator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-numeric-separator": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 049b958911de86d32408cd78017940a207e49c054ae9534ab53a32a57122cc592c0aae3c166d6f29bd1a7d75cc779d71883582dd76cb28b2fbb493e842d8ffca + checksum: 3247bd7d409574fc06c59e0eb573ae7470d6d61ecf780df40b550102bb4406747d8f39dcbec57eb59406df6c565a86edd3b429e396ad02e4ce201ad92050832e languageName: node linkType: hard "@babel/plugin-transform-object-assign@npm:^7.18.6": - version: 7.27.1 - resolution: "@babel/plugin-transform-object-assign@npm:7.27.1" + version: 7.24.1 + resolution: "@babel/plugin-transform-object-assign@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5541818d80f7f8cf30b1c701a3b3c8b2112b51d894ba6c7ad1012c8d0477a3a3445f66a7d5539238d4df3c17ee23b20b82e33f3a8e66fb0e3d8467f4901d65e0 + checksum: 88f56168f621501dc1aa796d569c76042367c2c3cb2c24f1419ed0783055a393f5722216a87abd9793365a0bd29b42a4e8055e93432c4b3657e6b5a22fe61c6f languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.28.0": - version: 7.28.4 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.4" +"@babel/plugin-transform-object-rest-spread@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.1" dependencies: - "@babel/helper-compilation-targets": ^7.27.2 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/plugin-transform-destructuring": ^7.28.0 - "@babel/plugin-transform-parameters": ^7.27.7 - "@babel/traverse": ^7.28.4 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-object-rest-spread": ^7.8.3 + "@babel/plugin-transform-parameters": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2063672ba4ac457a64b5c0c982439c7b08b4c70f0e743792b98240db5a05f1c063918d8366c92d4d6b2572e2e3452b300a23980b6668e4f54ff349f60d47ec48 + checksum: d5d28b1f33c279a38299d34011421a4915e24b3846aa23a1aba947f1366ce673ddf8df09dd915e0f2c90c5327f798bf126dca013f8adff1fc8f09e18878b675a languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-object-super@npm:7.27.1" +"@babel/plugin-transform-object-super@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-object-super@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-replace-supers": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-replace-supers": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 46b819cb9a6cd3cfefe42d07875fee414f18d5e66040366ae856116db560ad4e16f3899a0a7fddd6773e0d1458444f94b208b67c0e3b6977a27ea17a5c13dbf6 + checksum: d34d437456a54e2a5dcb26e9cf09ed4c55528f2a327c5edca92c93e9483c37176e228d00d6e0cf767f3d6fdbef45ae3a5d034a7c59337a009e20ae541c8220fa languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.27.1" +"@babel/plugin-transform-optional-catch-binding@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f4356b04cf21a98480f9788ea50f1f13ee88e89bb6393ba4b84d1f39a4a84c7928c9a4328e8f4c5b6deb218da68a8fd17bf4f46faec7653ddc20ffaaa5ba49f4 + checksum: ff7c02449d32a6de41e003abb38537b4a1ad90b1eaa4c0b578cb1b55548201a677588a8c47f3e161c72738400ae811a6673ea7b8a734344755016ca0ac445dac languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.27.1" +"@babel/plugin-transform-optional-chaining@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c4428d31f182d724db6f10575669aad3dbccceb0dea26aa9071fa89f11b3456278da3097fcc78937639a13c105a82cd452dc0218ce51abdbcf7626a013b928a5 + checksum: 0eb5f4abdeb1a101c0f67ef25eba4cce0978a74d8722f6222cdb179a28e60d21ab545eda231855f50169cd63d604ec8268cff44ae9370fd3a499a507c56c2bbd languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.27.7": - version: 7.27.7 - resolution: "@babel/plugin-transform-parameters@npm:7.27.7" +"@babel/plugin-transform-parameters@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-parameters@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d51f195e1d6ac5d9fce583e9a70a5bfe403e62386e5eb06db9fbc6533f895a98ff7e7c3dcaa311a8e6fa7a9794466e81cdabcba6af9f59d787fb767bfe7868b4 + checksum: d183008e67b1a13b86c92fb64327a75cd8e13c13eb80d0b6952e15806f1b0c4c456d18360e451c6af73485b2c8f543608b0a29e5126c64eb625a31e970b65f80 languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-private-methods@npm:7.27.1" +"@babel/plugin-transform-private-methods@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-private-methods@npm:7.24.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-create-class-features-plugin": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c76f8f6056946466116e67eb9d8014a2d748ade2062636ab82045c1dac9c233aff10e597777bc5af6f26428beb845ceb41b95007abef7d0484da95789da56662 + checksum: 7208c30bb3f3fbc73fb3a88bdcb78cd5cddaf6d523eb9d67c0c04e78f6fc6319ece89f4a5abc41777ceab16df55b3a13a4120e0efc9275ca6d2d89beaba80aa0 languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.27.1" +"@babel/plugin-transform-private-property-in-object@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.24.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.1 - "@babel/helper-create-class-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-private-property-in-object": ^7.14.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: af539af1bd423aa46b9da83d649be716494ca80783841f47094b6741fa24e11141446027fd152ddff791dede9d4a76d0d5eb467402a2e584d7f5ea90e2673c7e + checksum: 47c123ca9975f7f6b20e6fe8fe89f621cd04b622539faf5ec037e2be7c3d53ce2506f7c785b1930dcdea11994eff79094a02715795218c7d6a0bdc11f2fb3ac2 languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-property-literals@npm:7.27.1" +"@babel/plugin-transform-property-literals@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-property-literals@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7caec27d5ed8870895c9faf4f71def72745d69da0d8e77903146a4e135fd7bed5778f5f9cebb36c5fba86338e6194dd67a08c033fc84b4299b7eceab6d9630cb + checksum: a73646d7ecd95b3931a3ead82c7d5efeb46e68ba362de63eb437d33531f294ec18bd31b6d24238cd3b6a3b919a6310c4a0ba4a2629927721d4d10b0518eb7715 languageName: node linkType: hard "@babel/plugin-transform-react-constant-elements@npm:^7.12.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-react-constant-elements@npm:7.27.1" + version: 7.24.1 + resolution: "@babel/plugin-transform-react-constant-elements@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8372cf17ed551cd2e3da4f32a211881265692a17ad4c4fd40a8adcb89316d147db54f023630022ad7ec7474c4108647f67e3a62db43e515246a7574dcb5eeefe + checksum: 37fd10113b786a2462cf15366aa3a11a2a5bdba9bf8881b2544941f5ad6175ebc31116be5a53549c9fce56a08ded6e0b57adb45d6e42efb55d3bc0ff7afdd433 languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.16.0, @babel/plugin-transform-react-display-name@npm:^7.27.1": - version: 7.28.0 - resolution: "@babel/plugin-transform-react-display-name@npm:7.28.0" +"@babel/plugin-transform-react-display-name@npm:^7.16.0, @babel/plugin-transform-react-display-name@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-react-display-name@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 268b1a9192974439d17949e170b01cac2a2aa003c844e2fe3b8361146f42f66487178cffdfa8ce862aa9e6c814bc37f879a70300cb3f067815d15fa6aad04e6d + checksum: d87ac36073f923a25de0ed3cffac067ec5abc4cde63f7f4366881388fbea6dcbced0e4fefd3b7e99edfe58a4ce32ea4d4c523a577d2b9f0515b872ed02b3d8c3 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-development@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.27.1" +"@babel/plugin-transform-react-jsx-development@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5" dependencies: - "@babel/plugin-transform-react-jsx": ^7.27.1 + "@babel/plugin-transform-react-jsx": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b88865d5b8c018992f2332da939faa15c4d4a864c9435a5937beaff3fe43781432cc42e0a5d5631098e0bd4066fc33f5fa72203b388b074c3545fe7aaa21e474 + checksum: 36bc3ff0b96bb0ef4723070a50cfdf2e72cfd903a59eba448f9fe92fea47574d6f22efd99364413719e1f3fb3c51b6c9b2990b87af088f8486a84b2a5f9e4560 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-self@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-react-jsx-self@npm:7.27.1" +"@babel/plugin-transform-react-jsx-self@npm:^7.23.3": + version: 7.24.1 + resolution: "@babel/plugin-transform-react-jsx-self@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 72cbae66a58c6c36f7e12e8ed79f292192d858dd4bb00e9e89d8b695e4c5cb6ef48eec84bffff421a5db93fd10412c581f1cccdb00264065df76f121995bdb68 + checksum: a0ff893b946bb0e501ad5aab43ce4b321ed9e74b94c0bc7191e2ee6409014fc96ee1a47dcb1ecdf445c44868564667ae16507ed4516dcacf6aa9c37a0ad28382 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-source@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-react-jsx-source@npm:7.27.1" +"@babel/plugin-transform-react-jsx-source@npm:^7.23.3": + version: 7.24.1 + resolution: "@babel/plugin-transform-react-jsx-source@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e2843362adb53692be5ee9fa07a386d2d8883daad2063a3575b3c373fc14cdf4ea7978c67a183cb631b4c9c8d77b2f48c24c088f8e65cc3600cb8e97d72a7161 + checksum: 396ce878dc588e74113d38c5a1773e0850bb878a073238a74f8cdf62d968d56a644f5485bf4032dc095fe8863fe2bd9fbbbab6abc3adf69542e038ac5c689d4c languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-react-jsx@npm:7.27.1" +"@babel/plugin-transform-react-jsx@npm:^7.22.5, @babel/plugin-transform-react-jsx@npm:^7.23.4": + version: 7.23.4 + resolution: "@babel/plugin-transform-react-jsx@npm:7.23.4" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.1 - "@babel/helper-module-imports": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/plugin-syntax-jsx": ^7.27.1 - "@babel/types": ^7.27.1 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-module-imports": ^7.22.15 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/plugin-syntax-jsx": ^7.23.3 + "@babel/types": ^7.23.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 960d36e5d11ba68e4fbf1e2b935c153cb6ea7b0004f838aaee8baf7de30462b8f0562743a39ce3c370cc70b8f79d3c549104a415a615b2b0055b71fd025df0f3 + checksum: d8b8c52e8e22e833bf77c8d1a53b0a57d1fd52ba9596a319d572de79446a8ed9d95521035bc1175c1589d1a6a34600d2e678fa81d81bac8fac121137097f1f0a languageName: node linkType: hard -"@babel/plugin-transform-react-pure-annotations@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.27.1" +"@babel/plugin-transform-react-pure-annotations@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.24.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a6f591c5e85a1ab0685d4a25afe591fe8d11dc0b73c677cf9560ff8d540d036a1cce9efcb729fc9092def4d854dc304ffdc063a89a9247900b69c516bf971a4c + checksum: 06a6bfe80f1f36408d07dd80c48cf9f61177c8e5d814e80ddbe88cfad81a8b86b3110e1fe9d1ac943db77e74497daa7f874b5490c788707106ad26ecfbe44813 languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.28.3": - version: 7.28.4 - resolution: "@babel/plugin-transform-regenerator@npm:7.28.4" +"@babel/plugin-transform-regenerator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-regenerator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + regenerator-transform: ^0.15.2 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2aa99b3a7b254a109e913fabbe1fb320ff40723988fde0e225212b7ef20f523a399a6e45077258b176c29715493b2a853cf7c130811692215adf33e5af99782b - languageName: node - linkType: hard - -"@babel/plugin-transform-regexp-modifiers@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.27.1" - dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - peerDependencies: - "@babel/core": ^7.0.0 - checksum: f6cb385fe0e798bff7e9b20cf5912bf40e180895ff3610b1ccdce260f3c20daaebb3a99dc087c8168a99151cd3e16b94f4689fd5a4b01cf1834b45c133e620b2 + checksum: a04319388a0a7931c3f8e15715d01444c32519692178b70deccc86d53304e74c0f589a4268f6c68578d86f75e934dd1fe6e6ed9071f54ee8379f356f88ef6e42 languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-reserved-words@npm:7.27.1" +"@babel/plugin-transform-reserved-words@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-reserved-words@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: dea0b66742d2863b369c06c053e11e15ba785892ea19cccf7aef3c1bdaa38b6ab082e19984c5ea7810d275d9445c5400fcc385ad71ce707ed9256fadb102af3b + checksum: 132c6040c65aabae2d98a39289efb5c51a8632546dc50d2ad032c8660aec307fbed74ef499856ea4f881fc8505905f49b48e0270585da2ea3d50b75e962afd89 languageName: node linkType: hard "@babel/plugin-transform-runtime@npm:^7.16.4": - version: 7.28.3 - resolution: "@babel/plugin-transform-runtime@npm:7.28.3" - dependencies: - "@babel/helper-module-imports": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - babel-plugin-polyfill-corejs2: ^0.4.14 - babel-plugin-polyfill-corejs3: ^0.13.0 - babel-plugin-polyfill-regenerator: ^0.6.5 + version: 7.24.3 + resolution: "@babel/plugin-transform-runtime@npm:7.24.3" + dependencies: + "@babel/helper-module-imports": ^7.24.3 + "@babel/helper-plugin-utils": ^7.24.0 + babel-plugin-polyfill-corejs2: ^0.4.10 + babel-plugin-polyfill-corejs3: ^0.10.1 + babel-plugin-polyfill-regenerator: ^0.6.1 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 63d2fc05d5bfcb96f31be54b095d72a89f0a03c8de10f5d742b18b174e2731bcdc27292e8deec66c2e88cebf8298393123d5e767526f6fffbc75cb8144ef66c6 + checksum: 719112524e6fe3e665385ad4425530dadb2ddee839023381ed9d77edf5ce2748f32cc0e38dacda1990c56a7ae0af4de6cdca2413ffaf307e9f75f8d2200d09a2 languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1" +"@babel/plugin-transform-shorthand-properties@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: fbba6e2aef0b69681acb68202aa249c0598e470cc0853d7ff5bd0171fd6a7ec31d77cfabcce9df6360fc8349eded7e4a65218c32551bd3fc0caaa1ac899ac6d4 + checksum: 006a2032d1c57dca76579ce6598c679c2f20525afef0a36e9d42affe3c8cf33c1427581ad696b519cc75dfee46c5e8ecdf0c6a29ffb14250caa3e16dd68cb424 languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-spread@npm:7.27.1" +"@babel/plugin-transform-spread@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-spread@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 58b08085ee9c29955ac3b68d61c1a79728d44d19a69cb5eb669794aeaf54c57c6647af7b979c1297e81ede3d08b3ddcb1936ef39a533f28ff3e399a9be54dab1 + checksum: 622ef507e2b5120a9010b25d3df5186c06102ecad8751724a38ec924df8d3527688198fa490c47064eabba14ef2f961b3069855bd22a8c0a1e51a23eed348d02 languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" +"@babel/plugin-transform-sticky-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e1414a502efba92c7974681767e365a8cda6c5e9e5f33472a9eaa0ce2e75cea0a9bef881ff8dda37c7810ad902f98d3c00ead92a3ac3b73a79d011df85b5a189 + checksum: e326e96a9eeb6bb01dbc4d3362f989411490671b97f62edf378b8fb102c463a018b777f28da65344d41b22aa6efcdfa01ed43d2b11fdcf202046d3174be137c5 languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-template-literals@npm:7.27.1" +"@babel/plugin-transform-template-literals@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-template-literals@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 93aad782503b691faef7c0893372d5243df3219b07f1f22cfc32c104af6a2e7acd6102c128439eab15336d048f1b214ca134b87b0630d8cd568bf447f78b25ce + checksum: 4c9009c72321caf20e3b6328bbe9d7057006c5ae57b794cf247a37ca34d87dfec5e27284169a16df5a6235a083bf0f3ab9e1bfcb005d1c8b75b04aed75652621 languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.27.1" +"@babel/plugin-transform-typeof-symbol@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ed8048c8de72c60969a64cf2273cc6d9275d8fa8db9bd25a1268273a00fb9cbd79931140311411bda1443aa56cb3961fb911d1795abacde7f0482f1d8fdf0356 + checksum: 90251c02986aebe50937522a6e404cb83db1b1feda17c0244e97d6429ded1634340c8411536487d14c54495607e1b7c9dc4db4aed969d519f1ff1e363f9c2229 languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.27.1": - version: 7.28.0 - resolution: "@babel/plugin-transform-typescript@npm:7.28.0" +"@babel/plugin-transform-typescript@npm:^7.24.1": + version: 7.24.4 + resolution: "@babel/plugin-transform-typescript@npm:7.24.4" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.3 - "@babel/helper-create-class-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 - "@babel/plugin-syntax-typescript": ^7.27.1 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.24.4 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-typescript": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 14c1024bcd57fcd469d90cf0c15c3cd4e771e2eb2cd9afee3aa79b59c8ed103654f7c5c71cdb3bfe31c1d0cb08bfad8c80f5aa1d24b4b454bd21301d5925533d + checksum: 57a9a776b1910c706d28972e4b056ced3af8fc59c29b2a6205c2bb2a408141ddb59a8f2f6041f8467a7b260942818767f4ecabb9f63adf7fddf2afa25e774dfc languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" +"@babel/plugin-transform-unicode-escapes@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d817154bc10758ddd85b716e0bc1af1a1091e088400289ab6b78a1a4d609907ce3d2f1fd51a6fd0e0c8ecbb5f8e3aab4957e0747776d132d2379e85c3ef0520a + checksum: d4d7cfea91af7be2768fb6bed902e00d6e3190bda738b5149c3a788d570e6cf48b974ec9548442850308ecd8fc9a67681f4ea8403129e7867bcb85adaf6ec238 languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.27.1" +"@babel/plugin-transform-unicode-property-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.24.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-create-regexp-features-plugin": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5d99c89537d1ebaac3f526c04b162cf95a47d363d4829f78c6701a2c06ab78a48da66a94f853f85f44a3d72153410ba923e072bed4b7166fa097f503eb14131d + checksum: 276099b4483e707f80b054e2d29bc519158bfe52461ef5ff76f70727d592df17e30b1597ef4d8a0f04d810f6cb5a8dd887bdc1d0540af3744751710ef280090f languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" +"@babel/plugin-transform-unicode-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.24.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-create-regexp-features-plugin": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a34d89a2b75fb78e66d97c3dc90d4877f7e31f43316b52176f95a5dee20e9bb56ecf158eafc42a001676ddf7b393d9e67650bad6b32f5405780f25fb83cd68e3 + checksum: 400a0927bdb1425b4c0dc68a61b5b2d7d17c7d9f0e07317a1a6a373c080ef94be1dd65fdc4ac9a78fcdb58f89fd128450c7bc0d5b8ca0ae7eca3fbd98e50acba languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.27.1" +"@babel/plugin-transform-unicode-sets-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.24.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.27.1 - "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-create-regexp-features-plugin": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 295126074c7388ab05c82ef3ed0907a1ee4666bbdd763477ead9aba6eb2c74bdf65669416861ac93d337a4a27640963bb214acadc2697275ce95aab14868d57f + checksum: 364342fb8e382dfaa23628b88e6484dc1097e53fb7199f4d338f1e2cd71d839bb0a35a9b1380074f6a10adb2e98b79d53ca3ec78c0b8c557ca895ffff42180df languageName: node linkType: hard -"@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.16.4": - version: 7.28.3 - resolution: "@babel/preset-env@npm:7.28.3" +"@babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.16.4, @babel/preset-env@npm:^7.8.4": + version: 7.24.4 + resolution: "@babel/preset-env@npm:7.24.4" dependencies: - "@babel/compat-data": ^7.28.0 - "@babel/helper-compilation-targets": ^7.27.2 - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-validator-option": ^7.27.1 - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ^7.27.1 - "@babel/plugin-bugfix-safari-class-field-initializer-scope": ^7.27.1 - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.27.1 - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.27.1 - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.28.3 + "@babel/compat-data": ^7.24.4 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-validator-option": ^7.23.5 + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ^7.24.4 + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.24.1 + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.24.1 + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.24.1 "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 - "@babel/plugin-syntax-import-assertions": ^7.27.1 - "@babel/plugin-syntax-import-attributes": ^7.27.1 + "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/plugin-syntax-class-properties": ^7.12.13 + "@babel/plugin-syntax-class-static-block": ^7.14.5 + "@babel/plugin-syntax-dynamic-import": ^7.8.3 + "@babel/plugin-syntax-export-namespace-from": ^7.8.3 + "@babel/plugin-syntax-import-assertions": ^7.24.1 + "@babel/plugin-syntax-import-attributes": ^7.24.1 + "@babel/plugin-syntax-import-meta": ^7.10.4 + "@babel/plugin-syntax-json-strings": ^7.8.3 + "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 + "@babel/plugin-syntax-numeric-separator": ^7.10.4 + "@babel/plugin-syntax-object-rest-spread": ^7.8.3 + "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 + "@babel/plugin-syntax-private-property-in-object": ^7.14.5 + "@babel/plugin-syntax-top-level-await": ^7.14.5 "@babel/plugin-syntax-unicode-sets-regex": ^7.18.6 - "@babel/plugin-transform-arrow-functions": ^7.27.1 - "@babel/plugin-transform-async-generator-functions": ^7.28.0 - "@babel/plugin-transform-async-to-generator": ^7.27.1 - "@babel/plugin-transform-block-scoped-functions": ^7.27.1 - "@babel/plugin-transform-block-scoping": ^7.28.0 - "@babel/plugin-transform-class-properties": ^7.27.1 - "@babel/plugin-transform-class-static-block": ^7.28.3 - "@babel/plugin-transform-classes": ^7.28.3 - "@babel/plugin-transform-computed-properties": ^7.27.1 - "@babel/plugin-transform-destructuring": ^7.28.0 - "@babel/plugin-transform-dotall-regex": ^7.27.1 - "@babel/plugin-transform-duplicate-keys": ^7.27.1 - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ^7.27.1 - "@babel/plugin-transform-dynamic-import": ^7.27.1 - "@babel/plugin-transform-explicit-resource-management": ^7.28.0 - "@babel/plugin-transform-exponentiation-operator": ^7.27.1 - "@babel/plugin-transform-export-namespace-from": ^7.27.1 - "@babel/plugin-transform-for-of": ^7.27.1 - "@babel/plugin-transform-function-name": ^7.27.1 - "@babel/plugin-transform-json-strings": ^7.27.1 - "@babel/plugin-transform-literals": ^7.27.1 - "@babel/plugin-transform-logical-assignment-operators": ^7.27.1 - "@babel/plugin-transform-member-expression-literals": ^7.27.1 - "@babel/plugin-transform-modules-amd": ^7.27.1 - "@babel/plugin-transform-modules-commonjs": ^7.27.1 - "@babel/plugin-transform-modules-systemjs": ^7.27.1 - "@babel/plugin-transform-modules-umd": ^7.27.1 - "@babel/plugin-transform-named-capturing-groups-regex": ^7.27.1 - "@babel/plugin-transform-new-target": ^7.27.1 - "@babel/plugin-transform-nullish-coalescing-operator": ^7.27.1 - "@babel/plugin-transform-numeric-separator": ^7.27.1 - "@babel/plugin-transform-object-rest-spread": ^7.28.0 - "@babel/plugin-transform-object-super": ^7.27.1 - "@babel/plugin-transform-optional-catch-binding": ^7.27.1 - "@babel/plugin-transform-optional-chaining": ^7.27.1 - "@babel/plugin-transform-parameters": ^7.27.7 - "@babel/plugin-transform-private-methods": ^7.27.1 - "@babel/plugin-transform-private-property-in-object": ^7.27.1 - "@babel/plugin-transform-property-literals": ^7.27.1 - "@babel/plugin-transform-regenerator": ^7.28.3 - "@babel/plugin-transform-regexp-modifiers": ^7.27.1 - "@babel/plugin-transform-reserved-words": ^7.27.1 - "@babel/plugin-transform-shorthand-properties": ^7.27.1 - "@babel/plugin-transform-spread": ^7.27.1 - "@babel/plugin-transform-sticky-regex": ^7.27.1 - "@babel/plugin-transform-template-literals": ^7.27.1 - "@babel/plugin-transform-typeof-symbol": ^7.27.1 - "@babel/plugin-transform-unicode-escapes": ^7.27.1 - "@babel/plugin-transform-unicode-property-regex": ^7.27.1 - "@babel/plugin-transform-unicode-regex": ^7.27.1 - "@babel/plugin-transform-unicode-sets-regex": ^7.27.1 + "@babel/plugin-transform-arrow-functions": ^7.24.1 + "@babel/plugin-transform-async-generator-functions": ^7.24.3 + "@babel/plugin-transform-async-to-generator": ^7.24.1 + "@babel/plugin-transform-block-scoped-functions": ^7.24.1 + "@babel/plugin-transform-block-scoping": ^7.24.4 + "@babel/plugin-transform-class-properties": ^7.24.1 + "@babel/plugin-transform-class-static-block": ^7.24.4 + "@babel/plugin-transform-classes": ^7.24.1 + "@babel/plugin-transform-computed-properties": ^7.24.1 + "@babel/plugin-transform-destructuring": ^7.24.1 + "@babel/plugin-transform-dotall-regex": ^7.24.1 + "@babel/plugin-transform-duplicate-keys": ^7.24.1 + "@babel/plugin-transform-dynamic-import": ^7.24.1 + "@babel/plugin-transform-exponentiation-operator": ^7.24.1 + "@babel/plugin-transform-export-namespace-from": ^7.24.1 + "@babel/plugin-transform-for-of": ^7.24.1 + "@babel/plugin-transform-function-name": ^7.24.1 + "@babel/plugin-transform-json-strings": ^7.24.1 + "@babel/plugin-transform-literals": ^7.24.1 + "@babel/plugin-transform-logical-assignment-operators": ^7.24.1 + "@babel/plugin-transform-member-expression-literals": ^7.24.1 + "@babel/plugin-transform-modules-amd": ^7.24.1 + "@babel/plugin-transform-modules-commonjs": ^7.24.1 + "@babel/plugin-transform-modules-systemjs": ^7.24.1 + "@babel/plugin-transform-modules-umd": ^7.24.1 + "@babel/plugin-transform-named-capturing-groups-regex": ^7.22.5 + "@babel/plugin-transform-new-target": ^7.24.1 + "@babel/plugin-transform-nullish-coalescing-operator": ^7.24.1 + "@babel/plugin-transform-numeric-separator": ^7.24.1 + "@babel/plugin-transform-object-rest-spread": ^7.24.1 + "@babel/plugin-transform-object-super": ^7.24.1 + "@babel/plugin-transform-optional-catch-binding": ^7.24.1 + "@babel/plugin-transform-optional-chaining": ^7.24.1 + "@babel/plugin-transform-parameters": ^7.24.1 + "@babel/plugin-transform-private-methods": ^7.24.1 + "@babel/plugin-transform-private-property-in-object": ^7.24.1 + "@babel/plugin-transform-property-literals": ^7.24.1 + "@babel/plugin-transform-regenerator": ^7.24.1 + "@babel/plugin-transform-reserved-words": ^7.24.1 + "@babel/plugin-transform-shorthand-properties": ^7.24.1 + "@babel/plugin-transform-spread": ^7.24.1 + "@babel/plugin-transform-sticky-regex": ^7.24.1 + "@babel/plugin-transform-template-literals": ^7.24.1 + "@babel/plugin-transform-typeof-symbol": ^7.24.1 + "@babel/plugin-transform-unicode-escapes": ^7.24.1 + "@babel/plugin-transform-unicode-property-regex": ^7.24.1 + "@babel/plugin-transform-unicode-regex": ^7.24.1 + "@babel/plugin-transform-unicode-sets-regex": ^7.24.1 "@babel/preset-modules": 0.1.6-no-external-plugins - babel-plugin-polyfill-corejs2: ^0.4.14 - babel-plugin-polyfill-corejs3: ^0.13.0 - babel-plugin-polyfill-regenerator: ^0.6.5 - core-js-compat: ^3.43.0 + babel-plugin-polyfill-corejs2: ^0.4.10 + babel-plugin-polyfill-corejs3: ^0.10.4 + babel-plugin-polyfill-regenerator: ^0.6.1 + core-js-compat: ^3.31.0 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c4e70f69b727d21eedd4de201ac082e951482f2d28a388e401e7937fd6f15bc1a49a63c12f59e87a18d237ac037a5b29d983f3bb82f1196d6444ae5b605ac6e2 + checksum: 5a057a6463f92b02bfe66257d3f2c76878815bc7847f2a716b0539d9f547eae2a9d1f0fc62a5c0eff6ab0504bb52e815829ef893e4586b641f8dd6a609d114f3 languageName: node linkType: hard @@ -2036,76 +1611,99 @@ __metadata: linkType: hard "@babel/preset-react@npm:^7.12.5, @babel/preset-react@npm:^7.16.0, @babel/preset-react@npm:^7.18.6": - version: 7.27.1 - resolution: "@babel/preset-react@npm:7.27.1" - dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-validator-option": ^7.27.1 - "@babel/plugin-transform-react-display-name": ^7.27.1 - "@babel/plugin-transform-react-jsx": ^7.27.1 - "@babel/plugin-transform-react-jsx-development": ^7.27.1 - "@babel/plugin-transform-react-pure-annotations": ^7.27.1 + version: 7.24.1 + resolution: "@babel/preset-react@npm:7.24.1" + dependencies: + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-validator-option": ^7.23.5 + "@babel/plugin-transform-react-display-name": ^7.24.1 + "@babel/plugin-transform-react-jsx": ^7.23.4 + "@babel/plugin-transform-react-jsx-development": ^7.22.5 + "@babel/plugin-transform-react-pure-annotations": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 00bc146f9c742eed804c598d3f31b7d889c1baf8c768989b7f84a93ca527dd1518d3b86781e89ca45cae6dbee136510d3a121658e01416c5578aecf751517bb5 + checksum: 70e146a6de480cb4b6c5eb197003960a2d148d513e1f5b5d04ee954f255d68c935c2800da13e550267f47b894bd0214b2548181467b52a4bdc0a85020061b68c languageName: node linkType: hard "@babel/preset-typescript@npm:^7.16.0, @babel/preset-typescript@npm:^7.18.6": - version: 7.27.1 - resolution: "@babel/preset-typescript@npm:7.27.1" - dependencies: - "@babel/helper-plugin-utils": ^7.27.1 - "@babel/helper-validator-option": ^7.27.1 - "@babel/plugin-syntax-jsx": ^7.27.1 - "@babel/plugin-transform-modules-commonjs": ^7.27.1 - "@babel/plugin-transform-typescript": ^7.27.1 + version: 7.24.1 + resolution: "@babel/preset-typescript@npm:7.24.1" + dependencies: + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-validator-option": ^7.23.5 + "@babel/plugin-syntax-jsx": ^7.24.1 + "@babel/plugin-transform-modules-commonjs": ^7.24.1 + "@babel/plugin-transform-typescript": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 38020f1b23e88ec4fbffd5737da455d8939244bddfb48a2516aef93fb5947bd9163fb807ce6eff3e43fa5ffe9113aa131305fef0fb5053998410bbfcfe6ce0ec + checksum: f3e0ff8c20dd5abc82614df2d7953f1549a98282b60809478f7dfb41c29be63720f2d1d7a51ef1f0d939b65e8666cb7d36e32bc4f8ac2b74c20664efd41e8bdd + languageName: node + linkType: hard + +"@babel/regjsgen@npm:^0.8.0": + version: 0.8.0 + resolution: "@babel/regjsgen@npm:0.8.0" + checksum: 89c338fee774770e5a487382170711014d49a68eb281e74f2b5eac88f38300a4ad545516a7786a8dd5702e9cf009c94c2f582d200f077ac5decd74c56b973730 + languageName: node + linkType: hard + +"@babel/runtime-corejs3@npm:^7.10.2": + version: 7.24.4 + resolution: "@babel/runtime-corejs3@npm:7.24.4" + dependencies: + core-js-pure: ^3.30.2 + regenerator-runtime: ^0.14.0 + checksum: 0c2e7c477de3dbf5cc6f2434cee3d78a34d87e8f1e2ea65840eb948d00f7d6968e0ef055449adf372a39d6214f8b9b2532506149b9d0e7ea3d09b1b84678ae6c languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.28.3, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.7": - version: 7.28.4 - resolution: "@babel/runtime@npm:7.28.4" - checksum: 934b0a0460f7d06637d93fcd1a44ac49adc33518d17253b5a0b55ff4cb90a45d8fe78bf034b448911dbec7aff2a90b918697559f78d21c99ff8dbadae9565b55 +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": + version: 7.24.4 + resolution: "@babel/runtime@npm:7.24.4" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: 2f27d4c0ffac7ae7999ac0385e1106f2a06992a8bdcbf3da06adcac7413863cd08c198c2e4e970041bbea849e17f02e1df18875539b6afba76c781b6b59a07c3 languageName: node linkType: hard -"@babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": - version: 7.27.2 - resolution: "@babel/template@npm:7.27.2" +"@babel/template@npm:^7.10.4, @babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0, @babel/template@npm:^7.3.3": + version: 7.24.0 + resolution: "@babel/template@npm:7.24.0" dependencies: - "@babel/code-frame": ^7.27.1 - "@babel/parser": ^7.27.2 - "@babel/types": ^7.27.1 - checksum: ff5628bc066060624afd970616090e5bba91c6240c2e4b458d13267a523572cbfcbf549391eec8217b94b064cf96571c6273f0c04b28a8567b96edc675c28e27 + "@babel/code-frame": ^7.23.5 + "@babel/parser": ^7.24.0 + "@babel/types": ^7.24.0 + checksum: f257b003c071a0cecdbfceca74185f18fe62c055469ab5c1d481aab12abeebed328e67e0a19fd978a2a8de97b28953fa4bc3da6d038a7345fdf37923b9fcdec8 languageName: node linkType: hard -"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.7.2": - version: 7.28.4 - resolution: "@babel/traverse@npm:7.28.4" +"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.12.1, @babel/traverse@npm:^7.24.1, @babel/traverse@npm:^7.7.0": + version: 7.24.1 + resolution: "@babel/traverse@npm:7.24.1" dependencies: - "@babel/code-frame": ^7.27.1 - "@babel/generator": ^7.28.3 - "@babel/helper-globals": ^7.28.0 - "@babel/parser": ^7.28.4 - "@babel/template": ^7.27.2 - "@babel/types": ^7.28.4 + "@babel/code-frame": ^7.24.1 + "@babel/generator": ^7.24.1 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/parser": ^7.24.1 + "@babel/types": ^7.24.0 debug: ^4.3.1 - checksum: d603b8ce4e55ba4fc7b28d3362cc2b1b20bc887e471c8a59fe87b2578c26803c9ef8fcd118081dd8283ea78e0e9a6df9d88c8520033c6aaf81eec30d2a669151 + globals: ^11.1.0 + checksum: 92a5ca906abfba9df17666d2001ab23f18600035f706a687055a0e392a690ae48d6fec67c8bd4ef19ba18699a77a5b7f85727e36b83f7d110141608fe0c24fe9 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": - version: 7.28.4 - resolution: "@babel/types@npm:7.28.4" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.1, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0, @babel/types@npm:^7.8.3": + version: 7.24.0 + resolution: "@babel/types@npm:7.24.0" dependencies: - "@babel/helper-string-parser": ^7.27.1 - "@babel/helper-validator-identifier": ^7.27.1 - checksum: a369b4fb73415a2ed902a15576b49696ae9777ddee394a7a904c62e6fbb31f43906b0147ae0b8f03ac17f20c248eac093df349e33c65c94617b12e524b759694 + "@babel/helper-string-parser": ^7.23.4 + "@babel/helper-validator-identifier": ^7.22.20 + to-fast-properties: ^2.0.0 + checksum: 4b574a37d490f621470ff36a5afaac6deca5546edcb9b5e316d39acbb20998e9c2be42f3fc0bf2b55906fc49ff2a5a6a097e8f5a726ee3f708a0b0ca93aed807 languageName: node linkType: hard @@ -2116,21 +1714,15 @@ __metadata: languageName: node linkType: hard -"@bundled-es-modules/cookie@npm:^2.0.1": - version: 2.0.1 - resolution: "@bundled-es-modules/cookie@npm:2.0.1" - dependencies: - cookie: ^0.7.2 - checksum: 4f210f9316a612f03a46c58f0e3de14b2598f36905433b5ac91e305a4185bd3cb0b141622fa54cff2fce18adbac0b5a8df67dca1874aabd81b7a631fc826e116 - languageName: node - linkType: hard - -"@bundled-es-modules/statuses@npm:^1.0.1": - version: 1.0.1 - resolution: "@bundled-es-modules/statuses@npm:1.0.1" +"@cnakazawa/watch@npm:^1.0.3": + version: 1.0.4 + resolution: "@cnakazawa/watch@npm:1.0.4" dependencies: - statuses: ^2.0.1 - checksum: bcaa7de192e73056950b5fd20e75140d8d09074b1adc4437924b2051bb02b4dbf568c96e67d53b220fb7d735c3446e2ba746599cb1793ab2d23dd2ef230a8622 + exec-sh: ^0.3.2 + minimist: ^1.2.0 + bin: + watch: cli.js + checksum: 88f395ca0af2f3c0665b8ce7bb29e83647ec5d141e8735712aeeee4117081555436712966b6957aa1c461f6f826a4d23b0034e379c443a10e919f81c8748bf29 languageName: node linkType: hard @@ -2143,3223 +1735,1405 @@ __metadata: languageName: node linkType: hard -"@csstools/normalize.css@npm:*": - version: 12.1.1 - resolution: "@csstools/normalize.css@npm:12.1.1" - checksum: a356ee0fcb922f3e0bc23df4468bb4f27fc26c767e25359c079455fe30301d253d8a60c443859b04350c8174393edbb11bad2a9ef2f8cce0e371f6abf6c7ef36 +"@csstools/convert-colors@npm:^1.4.0": + version: 1.4.0 + resolution: "@csstools/convert-colors@npm:1.4.0" + checksum: 26069eeb845a506934c821c203feb97f5de634c5fbeb9978505a2271d6cfdb0ce400240fca9620a4ef2e68953928ea25aab92ea8454e0edf5cd074066d9ad57b languageName: node linkType: hard -"@csstools/postcss-cascade-layers@npm:^1.1.1": - version: 1.1.1 - resolution: "@csstools/postcss-cascade-layers@npm:1.1.1" - dependencies: - "@csstools/selector-specificity": ^2.0.2 - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.2 - checksum: 8ecd6a929e8ddee3ad0834ab5017f50a569817ba8490d152b11c705c13cf3d9701f74792f375cbd72d8f33a4eeaabb3f984f1514adf8c5a530eb91be70c14cf4 +"@csstools/normalize.css@npm:^10.1.0": + version: 10.1.0 + resolution: "@csstools/normalize.css@npm:10.1.0" + checksum: c0adedd58e16b73b6588377ca505bfbc3f6273ab1ba1b55dd343aa5e4c0bf81bd74f051a1317a0d383bdcd59af665ba34db00b0c51c7dbc176c1a536175c2b03 languageName: node linkType: hard -"@csstools/postcss-color-function@npm:^1.1.1": - version: 1.1.1 - resolution: "@csstools/postcss-color-function@npm:1.1.1" +"@emotion/babel-plugin@npm:^11.11.0": + version: 11.11.0 + resolution: "@emotion/babel-plugin@npm:11.11.0" dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 087595985ebcc2fc42013d6305185d4cdc842d87fb261185db905dc31eaa24fc23a7cc068fa3da814b3c8b98164107ddaf1b4ab24f4ff5b2a7b5fbcd4c6ceec9 + "@babel/helper-module-imports": ^7.16.7 + "@babel/runtime": ^7.18.3 + "@emotion/hash": ^0.9.1 + "@emotion/memoize": ^0.8.1 + "@emotion/serialize": ^1.1.2 + babel-plugin-macros: ^3.1.0 + convert-source-map: ^1.5.0 + escape-string-regexp: ^4.0.0 + find-root: ^1.1.0 + source-map: ^0.5.7 + stylis: 4.2.0 + checksum: 6b363edccc10290f7a23242c06f88e451b5feb2ab94152b18bb8883033db5934fb0e421e2d67d09907c13837c21218a3ac28c51707778a54d6cd3706c0c2f3f9 languageName: node linkType: hard -"@csstools/postcss-font-format-keywords@npm:^1.0.1": - version: 1.0.1 - resolution: "@csstools/postcss-font-format-keywords@npm:1.0.1" +"@emotion/cache@npm:^11.11.0": + version: 11.11.0 + resolution: "@emotion/cache@npm:11.11.0" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: ed8d9eab9793f0184e000709bcb155d4eb96c49a312e3ea9e549e006b74fd4aafac63cb9f9f01bec5b717a833539ff085c3f1ef7d273b97d587769ef637d50c1 + "@emotion/memoize": ^0.8.1 + "@emotion/sheet": ^1.2.2 + "@emotion/utils": ^1.2.1 + "@emotion/weak-memoize": ^0.3.1 + stylis: 4.2.0 + checksum: 8eb1dc22beaa20c21a2e04c284d5a2630a018a9d51fb190e52de348c8d27f4e8ca4bbab003d68b4f6cd9cc1c569ca747a997797e0f76d6c734a660dc29decf08 languageName: node linkType: hard -"@csstools/postcss-hwb-function@npm:^1.0.2": - version: 1.0.2 - resolution: "@csstools/postcss-hwb-function@npm:1.0.2" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 352ead754a692f7ed33a712c491012cab5c2f2946136a669a354237cfe8e6faca90c7389ee793cb329b9b0ddec984faa06d47e2f875933aaca417afff74ce6aa +"@emotion/hash@npm:^0.9.1": + version: 0.9.1 + resolution: "@emotion/hash@npm:0.9.1" + checksum: 716e17e48bf9047bf9383982c071de49f2615310fb4e986738931776f5a823bc1f29c84501abe0d3df91a3803c80122d24e28b57351bca9e01356ebb33d89876 languageName: node linkType: hard -"@csstools/postcss-ic-unit@npm:^1.0.1": - version: 1.0.1 - resolution: "@csstools/postcss-ic-unit@npm:1.0.1" +"@emotion/is-prop-valid@npm:^1.2.2": + version: 1.2.2 + resolution: "@emotion/is-prop-valid@npm:1.2.2" dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 09c414c9b7762b5fbe837ff451d7a11e4890f1ed3c92edc3573f02f3d89747f6ac3f2270799b68a332bd7f5de05bb0dfffddb6323fc4020c2bea33ff58314533 + "@emotion/memoize": ^0.8.1 + checksum: 61f6b128ea62b9f76b47955057d5d86fcbe2a6989d2cd1e583daac592901a950475a37d049b9f7a7c6aa8758a33b408735db759fdedfd1f629df0f85ab60ea25 languageName: node linkType: hard -"@csstools/postcss-is-pseudo-class@npm:^2.0.7": - version: 2.0.7 - resolution: "@csstools/postcss-is-pseudo-class@npm:2.0.7" - dependencies: - "@csstools/selector-specificity": ^2.0.0 - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.2 - checksum: a4494bb8e9a34826944ba6872c91c1e88268caab6d06968897f1a0cc75ca5cfc4989435961fc668a9c6842a6d17f4cda0055fa256d23e598b8bbc6f022956125 +"@emotion/memoize@npm:^0.8.1": + version: 0.8.1 + resolution: "@emotion/memoize@npm:0.8.1" + checksum: a19cc01a29fcc97514948eaab4dc34d8272e934466ed87c07f157887406bc318000c69ae6f813a9001c6a225364df04249842a50e692ef7a9873335fbcc141b0 languageName: node linkType: hard -"@csstools/postcss-nested-calc@npm:^1.0.0": - version: 1.0.0 - resolution: "@csstools/postcss-nested-calc@npm:1.0.0" +"@emotion/react@npm:^11.10.4": + version: 11.11.4 + resolution: "@emotion/react@npm:11.11.4" dependencies: - postcss-value-parser: ^4.2.0 + "@babel/runtime": ^7.18.3 + "@emotion/babel-plugin": ^11.11.0 + "@emotion/cache": ^11.11.0 + "@emotion/serialize": ^1.1.3 + "@emotion/use-insertion-effect-with-fallbacks": ^1.0.1 + "@emotion/utils": ^1.2.1 + "@emotion/weak-memoize": ^0.3.1 + hoist-non-react-statics: ^3.3.1 peerDependencies: - postcss: ^8.2 - checksum: 53bb783dd61621c11c1e6e352f079577e2eb908de67947ceef31a178e070c06c223baae87acd5c3bd51c664515d2adc16166a129159168626111aff548583790 + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 6abaa7a05c5e1db31bffca7ac79169f5456990022cbb3794e6903221536609a60420f2b4888dd3f84e9634a304e394130cb88dc32c243a1dedc263e50da329f8 languageName: node linkType: hard -"@csstools/postcss-normalize-display-values@npm:^1.0.1": - version: 1.0.1 - resolution: "@csstools/postcss-normalize-display-values@npm:1.0.1" +"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.1.4": + version: 1.1.4 + resolution: "@emotion/serialize@npm:1.1.4" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 75901daec3869ba15e0adfd50d8e2e754ec06d55ac44fbd540748476388d223d53710fb3a3cbfe6695a2bab015a489fb47d9e3914ff211736923f8deb818dc0b + "@emotion/hash": ^0.9.1 + "@emotion/memoize": ^0.8.1 + "@emotion/unitless": ^0.8.1 + "@emotion/utils": ^1.2.1 + csstype: ^3.0.2 + checksum: 71b99f816a9c1d61a87c62cf4928da3894bb62213f3aff38b1ea9790b3368f084af98a3e5453b5055c2f36a7d70318d2fa9955b7b5676c2065b868062375df39 languageName: node linkType: hard -"@csstools/postcss-oklab-function@npm:^1.1.1": - version: 1.1.1 - resolution: "@csstools/postcss-oklab-function@npm:1.1.1" - dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: d66b789060b37ed810450d9a7d8319a0ae14e913c091f3e0ee482b3471538762e801d5eae3d62fda2f1eb1e88c76786d2c2b06c1172166eba1cca5e2a0dc95f2 +"@emotion/sheet@npm:^1.2.2": + version: 1.2.2 + resolution: "@emotion/sheet@npm:1.2.2" + checksum: d973273c9c15f1c291ca2269728bf044bd3e92a67bca87943fa9ec6c3cd2b034f9a6bfe95ef1b5d983351d128c75b547b43ff196a00a3875f7e1d269793cecfe languageName: node linkType: hard -"@csstools/postcss-progressive-custom-properties@npm:^1.1.0, @csstools/postcss-progressive-custom-properties@npm:^1.3.0": - version: 1.3.0 - resolution: "@csstools/postcss-progressive-custom-properties@npm:1.3.0" +"@emotion/styled@npm:^11.10.4": + version: 11.11.5 + resolution: "@emotion/styled@npm:11.11.5" dependencies: - postcss-value-parser: ^4.2.0 + "@babel/runtime": ^7.18.3 + "@emotion/babel-plugin": ^11.11.0 + "@emotion/is-prop-valid": ^1.2.2 + "@emotion/serialize": ^1.1.4 + "@emotion/use-insertion-effect-with-fallbacks": ^1.0.1 + "@emotion/utils": ^1.2.1 peerDependencies: - postcss: ^8.3 - checksum: e281845fde5b8a80d06ec20147bd74e96a9351bebbec5e5c3a6fb37ea30a597ff84172601786a8a270662f58f708b4a3bf8d822d6318023def9773d2f6589962 + "@emotion/react": ^11.0.0-rc.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: ad5fc42d00e8aa9597f6d9665986036d5ebe0e8f8155af6d95831c5e8fb2319fb837724e6c5cd59e5346f14c3263711b7ce7271d34688e974d1f32ffeecb37ba languageName: node linkType: hard -"@csstools/postcss-stepped-value-functions@npm:^1.0.1": - version: 1.0.1 - resolution: "@csstools/postcss-stepped-value-functions@npm:1.0.1" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 2fc88713a0d49d142010652be8139b00719e407df1173e46047284f1befd0647e1fff67f259f9f55ac3b46bba6462b21f0aa192bd10a2989c51a8ce0d25fc495 +"@emotion/unitless@npm:^0.8.1": + version: 0.8.1 + resolution: "@emotion/unitless@npm:0.8.1" + checksum: 385e21d184d27853bb350999471f00e1429fa4e83182f46cd2c164985999d9b46d558dc8b9cc89975cb337831ce50c31ac2f33b15502e85c299892e67e7b4a88 languageName: node linkType: hard -"@csstools/postcss-text-decoration-shorthand@npm:^1.0.0": - version: 1.0.0 - resolution: "@csstools/postcss-text-decoration-shorthand@npm:1.0.0" - dependencies: - postcss-value-parser: ^4.2.0 +"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.1": + version: 1.0.1 + resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1" peerDependencies: - postcss: ^8.2 - checksum: d27aaf97872c42bec9f6fde4d8bf924e89f7886f0aca8e4fc5aaf2f9083b09bb43dbbfa29124fa36fcdeb2d4d3e0459a095acf62188260cd1577e9811bb1276e + react: ">=16.8.0" + checksum: 700b6e5bbb37a9231f203bb3af11295eed01d73b2293abece0bc2a2237015e944d7b5114d4887ad9a79776504aa51ed2a8b0ddbc117c54495dd01a6b22f93786 languageName: node linkType: hard -"@csstools/postcss-trigonometric-functions@npm:^1.0.2": - version: 1.0.2 - resolution: "@csstools/postcss-trigonometric-functions@npm:1.0.2" - dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: f7f5b5f2492606b79a56f09e814ae8f10a2ae9e9c5fb8019f0e347a4a6c07953b2cc663fd4fa43a60e6994dfd958958f39df8ec760e2a646cfe71fe2bb119382 +"@emotion/utils@npm:^1.2.1": + version: 1.2.1 + resolution: "@emotion/utils@npm:1.2.1" + checksum: e0b44be0705b56b079c55faff93952150be69e79b660ae70ddd5b6e09fc40eb1319654315a9f34bb479d7f4ec94be6068c061abbb9e18b9778ae180ad5d97c73 languageName: node linkType: hard -"@csstools/postcss-unset-value@npm:^1.0.2": - version: 1.0.2 - resolution: "@csstools/postcss-unset-value@npm:1.0.2" - peerDependencies: - postcss: ^8.2 - checksum: 3facdae154d6516ffd964f7582696f406465f11cf8dead503e0afdfecc99ebc25638ab2830affce4516131aa2db004458a235e439f575b04e9ef72ad82f55835 +"@emotion/weak-memoize@npm:^0.3.1": + version: 0.3.1 + resolution: "@emotion/weak-memoize@npm:0.3.1" + checksum: b2be47caa24a8122622ea18cd2d650dbb4f8ad37b636dc41ed420c2e082f7f1e564ecdea68122b546df7f305b159bf5ab9ffee872abd0f052e687428459af594 languageName: node linkType: hard -"@csstools/selector-specificity@npm:^2.0.0, @csstools/selector-specificity@npm:^2.0.2": - version: 2.2.0 - resolution: "@csstools/selector-specificity@npm:2.2.0" - peerDependencies: - postcss-selector-parser: ^6.0.10 - checksum: 97c89f23b3b527d7bd51ed299969ed2b9fbb219a367948b44aefec228b8eda6ae0ad74fe8a82f9aac8ff32cfd00bb6d0c98d1daeab2e8fc6d5c4af25e5be5673 +"@esbuild/android-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/android-arm64@npm:0.18.20" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@emotion/babel-plugin@npm:^11.13.5": - version: 11.13.5 - resolution: "@emotion/babel-plugin@npm:11.13.5" - dependencies: - "@babel/helper-module-imports": ^7.16.7 - "@babel/runtime": ^7.18.3 - "@emotion/hash": ^0.9.2 - "@emotion/memoize": ^0.9.0 - "@emotion/serialize": ^1.3.3 - babel-plugin-macros: ^3.1.0 - convert-source-map: ^1.5.0 - escape-string-regexp: ^4.0.0 - find-root: ^1.1.0 - source-map: ^0.5.7 - stylis: 4.2.0 - checksum: c41df7e6c19520e76d1939f884be878bf88b5ba00bd3de9d05c5b6c5baa5051686ab124d7317a0645de1b017b574d8139ae1d6390ec267fbe8e85a5252afb542 +"@esbuild/android-arm@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/android-arm@npm:0.18.20" + conditions: os=android & cpu=arm languageName: node linkType: hard -"@emotion/cache@npm:^11.13.5, @emotion/cache@npm:^11.14.0": - version: 11.14.0 - resolution: "@emotion/cache@npm:11.14.0" - dependencies: - "@emotion/memoize": ^0.9.0 - "@emotion/sheet": ^1.4.0 - "@emotion/utils": ^1.4.2 - "@emotion/weak-memoize": ^0.4.0 - stylis: 4.2.0 - checksum: 0a81591541ea43bc7851742e6444b7800d72e98006f94e775ae6ea0806662d14e0a86ff940f5f19d33b4bb2c427c882aa65d417e7322a6e0d5f20fe65ed920c9 +"@esbuild/android-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/android-x64@npm:0.18.20" + conditions: os=android & cpu=x64 languageName: node linkType: hard -"@emotion/hash@npm:^0.9.2": - version: 0.9.2 - resolution: "@emotion/hash@npm:0.9.2" - checksum: 379bde2830ccb0328c2617ec009642321c0e009a46aa383dfbe75b679c6aea977ca698c832d225a893901f29d7b3eef0e38cf341f560f6b2b56f1ff23c172387 +"@esbuild/darwin-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/darwin-arm64@npm:0.18.20" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@emotion/is-prop-valid@npm:^1.3.0": - version: 1.4.0 - resolution: "@emotion/is-prop-valid@npm:1.4.0" - dependencies: - "@emotion/memoize": ^0.9.0 - checksum: 6b003cdc62106c2d5d12207c2d1352d674339252a2d7ac8d96974781d7c639833f35d22e7e331411795daaafa62f126c2824a4983584292b431e08b42877d51e +"@esbuild/darwin-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/darwin-x64@npm:0.18.20" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@emotion/memoize@npm:^0.9.0": - version: 0.9.0 - resolution: "@emotion/memoize@npm:0.9.0" - checksum: 038132359397348e378c593a773b1148cd0cf0a2285ffd067a0f63447b945f5278860d9de718f906a74c7c940ba1783ac2ca18f1c06a307b01cc0e3944e783b1 +"@esbuild/freebsd-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/freebsd-arm64@npm:0.18.20" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@emotion/react@npm:^11.10.4": - version: 11.14.0 - resolution: "@emotion/react@npm:11.14.0" - dependencies: - "@babel/runtime": ^7.18.3 - "@emotion/babel-plugin": ^11.13.5 - "@emotion/cache": ^11.14.0 - "@emotion/serialize": ^1.3.3 - "@emotion/use-insertion-effect-with-fallbacks": ^1.2.0 - "@emotion/utils": ^1.4.2 - "@emotion/weak-memoize": ^0.4.0 - hoist-non-react-statics: ^3.3.1 - peerDependencies: - react: ">=16.8.0" - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 3cf023b11d132b56168713764d6fced8e5a1f0687dfe0caa2782dfd428c8f9e30f9826a919965a311d87b523cd196722aaf75919cd0f6bd0fd57f8a6a0281500 - languageName: node - linkType: hard - -"@emotion/serialize@npm:^1.3.3": - version: 1.3.3 - resolution: "@emotion/serialize@npm:1.3.3" - dependencies: - "@emotion/hash": ^0.9.2 - "@emotion/memoize": ^0.9.0 - "@emotion/unitless": ^0.10.0 - "@emotion/utils": ^1.4.2 - csstype: ^3.0.2 - checksum: 510331233767ae4e09e925287ca2c7269b320fa1d737ea86db5b3c861a734483ea832394c0c1fe5b21468fe335624a75e72818831d303ba38125f54f44ba02e7 +"@esbuild/freebsd-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/freebsd-x64@npm:0.18.20" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@emotion/sheet@npm:^1.4.0": - version: 1.4.0 - resolution: "@emotion/sheet@npm:1.4.0" - checksum: eeb1212e3289db8e083e72e7e401cd6d1a84deece87e9ce184f7b96b9b5dbd6f070a89057255a6ff14d9865c3ce31f27c39248a053e4cdd875540359042586b4 +"@esbuild/linux-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-arm64@npm:0.18.20" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@emotion/styled@npm:^11.10.4": - version: 11.14.1 - resolution: "@emotion/styled@npm:11.14.1" - dependencies: - "@babel/runtime": ^7.18.3 - "@emotion/babel-plugin": ^11.13.5 - "@emotion/is-prop-valid": ^1.3.0 - "@emotion/serialize": ^1.3.3 - "@emotion/use-insertion-effect-with-fallbacks": ^1.2.0 - "@emotion/utils": ^1.4.2 - peerDependencies: - "@emotion/react": ^11.0.0-rc.0 - react: ">=16.8.0" - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 86238d9f5c41232a73499e441fa9112e855545519d6772f489fa885634bb8f31b422a9ba9d1e8bc0b4ad66132f9d398b1c309d92c19c5ee21356b41671ec984a +"@esbuild/linux-arm@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-arm@npm:0.18.20" + conditions: os=linux & cpu=arm languageName: node linkType: hard -"@emotion/unitless@npm:^0.10.0": - version: 0.10.0 - resolution: "@emotion/unitless@npm:0.10.0" - checksum: d79346df31a933e6d33518e92636afeb603ce043f3857d0a39a2ac78a09ef0be8bedff40130930cb25df1beeee12d96ee38613963886fa377c681a89970b787c +"@esbuild/linux-ia32@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-ia32@npm:0.18.20" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@emotion/use-insertion-effect-with-fallbacks@npm:^1.2.0": - version: 1.2.0 - resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.2.0" - peerDependencies: - react: ">=16.8.0" - checksum: 8ff6aec7f2924526ff8c8f8f93d4b8236376e2e12c435314a18c9a373016e24dfdf984e82bbc83712b8e90ff4783cd765eb39fc7050d1a43245e5728740ddd71 +"@esbuild/linux-loong64@npm:0.14.54": + version: 0.14.54 + resolution: "@esbuild/linux-loong64@npm:0.14.54" + conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@emotion/utils@npm:^1.4.2": - version: 1.4.2 - resolution: "@emotion/utils@npm:1.4.2" - checksum: 04cf76849c6401205c058b82689fd0ec5bf501aed6974880fe9681a1d61543efb97e848f4c38664ac4a9068c7ad2d1cb84f73bde6cf95f1208aa3c28e0190321 +"@esbuild/linux-loong64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-loong64@npm:0.18.20" + conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@emotion/weak-memoize@npm:^0.4.0": - version: 0.4.0 - resolution: "@emotion/weak-memoize@npm:0.4.0" - checksum: db5da0e89bd752c78b6bd65a1e56231f0abebe2f71c0bd8fc47dff96408f7065b02e214080f99924f6a3bfe7ee15afc48dad999d76df86b39b16e513f7a94f52 +"@esbuild/linux-mips64el@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-mips64el@npm:0.18.20" + conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/aix-ppc64@npm:0.21.5" - conditions: os=aix & cpu=ppc64 +"@esbuild/linux-ppc64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-ppc64@npm:0.18.20" + conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/aix-ppc64@npm:0.24.2" - conditions: os=aix & cpu=ppc64 +"@esbuild/linux-riscv64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-riscv64@npm:0.18.20" + conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/aix-ppc64@npm:0.25.9" - conditions: os=aix & cpu=ppc64 +"@esbuild/linux-s390x@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-s390x@npm:0.18.20" + conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/android-arm64@npm:0.17.19" - conditions: os=android & cpu=arm64 +"@esbuild/linux-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-x64@npm:0.18.20" + conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/android-arm64@npm:0.21.5" - conditions: os=android & cpu=arm64 +"@esbuild/netbsd-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/netbsd-x64@npm:0.18.20" + conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/android-arm64@npm:0.24.2" - conditions: os=android & cpu=arm64 +"@esbuild/openbsd-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/openbsd-x64@npm:0.18.20" + conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/android-arm64@npm:0.25.9" - conditions: os=android & cpu=arm64 +"@esbuild/sunos-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/sunos-x64@npm:0.18.20" + conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/android-arm@npm:0.17.19" - conditions: os=android & cpu=arm +"@esbuild/win32-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/win32-arm64@npm:0.18.20" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/android-arm@npm:0.21.5" - conditions: os=android & cpu=arm +"@esbuild/win32-ia32@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/win32-ia32@npm:0.18.20" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/android-arm@npm:0.24.2" - conditions: os=android & cpu=arm +"@esbuild/win32-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/win32-x64@npm:0.18.20" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/android-arm@npm:0.25.9" - conditions: os=android & cpu=arm +"@eslint/eslintrc@npm:^0.4.3": + version: 0.4.3 + resolution: "@eslint/eslintrc@npm:0.4.3" + dependencies: + ajv: ^6.12.4 + debug: ^4.1.1 + espree: ^7.3.0 + globals: ^13.9.0 + ignore: ^4.0.6 + import-fresh: ^3.2.1 + js-yaml: ^3.13.1 + minimatch: ^3.0.4 + strip-json-comments: ^3.1.1 + checksum: 03a7704150b868c318aab6a94d87a33d30dc2ec579d27374575014f06237ba1370ae11178db772f985ef680d469dc237e7b16a1c5d8edaaeb8c3733e7a95a6d3 languageName: node linkType: hard -"@esbuild/android-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/android-x64@npm:0.17.19" - conditions: os=android & cpu=x64 +"@floating-ui/core@npm:^1.0.0": + version: 1.6.0 + resolution: "@floating-ui/core@npm:1.6.0" + dependencies: + "@floating-ui/utils": ^0.2.1 + checksum: 2e25c53b0c124c5c9577972f8ae21d081f2f7895e6695836a53074463e8c65b47722744d6d2b5a993164936da006a268bcfe87fe68fd24dc235b1cb86bed3127 languageName: node linkType: hard -"@esbuild/android-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/android-x64@npm:0.21.5" - conditions: os=android & cpu=x64 +"@floating-ui/dom@npm:^1.6.1": + version: 1.6.3 + resolution: "@floating-ui/dom@npm:1.6.3" + dependencies: + "@floating-ui/core": ^1.0.0 + "@floating-ui/utils": ^0.2.0 + checksum: 81cbb18ece3afc37992f436e469e7fabab2e433248e46fff4302d12493a175b0c64310f8a971e6e1eda7218df28ace6b70237b0f3c22fe12a21bba05b5579555 languageName: node linkType: hard -"@esbuild/android-x64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/android-x64@npm:0.24.2" - conditions: os=android & cpu=x64 +"@floating-ui/react-dom@npm:^2.0.8": + version: 2.0.8 + resolution: "@floating-ui/react-dom@npm:2.0.8" + dependencies: + "@floating-ui/dom": ^1.6.1 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 5da7f13a69281e38859a3203a608fe9de1d850b332b355c10c0c2427c7b7209a0374c10f6295b6577c1a70237af8b678340bd4cc0a4b1c66436a94755d81e526 languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/android-x64@npm:0.25.9" - conditions: os=android & cpu=x64 +"@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.1": + version: 0.2.1 + resolution: "@floating-ui/utils@npm:0.2.1" + checksum: 9ed4380653c7c217cd6f66ae51f20fdce433730dbc77f95b5abfb5a808f5fdb029c6ae249b4e0490a816f2453aa6e586d9a873cd157fdba4690f65628efc6e06 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/darwin-arm64@npm:0.17.19" - conditions: os=darwin & cpu=arm64 +"@gar/promisify@npm:^1.0.1": + version: 1.1.3 + resolution: "@gar/promisify@npm:1.1.3" + checksum: 4059f790e2d07bf3c3ff3e0fec0daa8144fe35c1f6e0111c9921bd32106adaa97a4ab096ad7dab1e28ee6a9060083c4d1a4ada42a7f5f3f7a96b8812e2b757c1 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/darwin-arm64@npm:0.21.5" - conditions: os=darwin & cpu=arm64 +"@hapi/address@npm:2.x.x": + version: 2.1.4 + resolution: "@hapi/address@npm:2.1.4" + checksum: 10341c3b650746c79ac2c57118efb05d45d850b33aef82a6f2ba89419fdbf1b6d337c8b085cc9bc1af7a5fb18379c07edaf3be7584426f40bd370ed6de29e965 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/darwin-arm64@npm:0.24.2" - conditions: os=darwin & cpu=arm64 +"@hapi/bourne@npm:1.x.x": + version: 1.3.2 + resolution: "@hapi/bourne@npm:1.3.2" + checksum: 8403a2e8297fbb49a0e4fca30e874590d96ecaf7165740804037ff30625f3fdea6353d9f7f4422607eb069a3f471900a3037df34285a95135d15c6a8b10094b0 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/darwin-arm64@npm:0.25.9" - conditions: os=darwin & cpu=arm64 +"@hapi/hoek@npm:8.x.x, @hapi/hoek@npm:^8.3.0": + version: 8.5.1 + resolution: "@hapi/hoek@npm:8.5.1" + checksum: 8f8ce36be4f5e5d7a712072d4a028a4a95beec7a7da3a7a6e9a0c07d697f04c19b37d93751db352c314ea831f7e2120569a035dc6a351ed8c0444f1d3b275621 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/darwin-x64@npm:0.17.19" - conditions: os=darwin & cpu=x64 +"@hapi/joi@npm:^15.1.0": + version: 15.1.1 + resolution: "@hapi/joi@npm:15.1.1" + dependencies: + "@hapi/address": 2.x.x + "@hapi/bourne": 1.x.x + "@hapi/hoek": 8.x.x + "@hapi/topo": 3.x.x + checksum: 5bc3df9d43d4a53c41fd172d2958a4a846dbacbe2a2abe16830059109c436776d7be98144f14af9d328ebd107dbebafe55e00a9032a905aef45aadff988b54bf languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/darwin-x64@npm:0.21.5" - conditions: os=darwin & cpu=x64 +"@hapi/topo@npm:3.x.x": + version: 3.1.6 + resolution: "@hapi/topo@npm:3.1.6" + dependencies: + "@hapi/hoek": ^8.3.0 + checksum: 34278bc13b4023d6d0d7c913605a254b2d728dc6489cd465269eebaa7d8d2d81cda3f2157398dca87d3cb9e1a8aa8a1158ce2564c71a8e289b807c144e3b4c1e languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/darwin-x64@npm:0.24.2" - conditions: os=darwin & cpu=x64 +"@hookform/resolvers@npm:^2.9.7": + version: 2.9.11 + resolution: "@hookform/resolvers@npm:2.9.11" + peerDependencies: + react-hook-form: ^7.0.0 + checksum: 977ea038bb94457ac9f6c7ca65438ce8fcd0cf7643b9925d8bc4d66df6faa0f49ad642bee7362f86a4d3ff7ff53d18b7aea0597085993971cae00e86bf6eda73 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/darwin-x64@npm:0.25.9" - conditions: os=darwin & cpu=x64 +"@humanwhocodes/config-array@npm:^0.5.0": + version: 0.5.0 + resolution: "@humanwhocodes/config-array@npm:0.5.0" + dependencies: + "@humanwhocodes/object-schema": ^1.2.0 + debug: ^4.1.1 + minimatch: ^3.0.4 + checksum: 44ee6a9f05d93dd9d5935a006b17572328ba9caff8002442f601736cbda79c580cc0f5a49ce9eb88fbacc5c3a6b62098357c2e95326cd17bb9f1a6c61d6e95e7 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/freebsd-arm64@npm:0.17.19" - conditions: os=freebsd & cpu=arm64 +"@humanwhocodes/object-schema@npm:^1.2.0": + version: 1.2.1 + resolution: "@humanwhocodes/object-schema@npm:1.2.1" + checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/freebsd-arm64@npm:0.21.5" - conditions: os=freebsd & cpu=arm64 +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + 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" + checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/freebsd-arm64@npm:0.24.2" - conditions: os=freebsd & cpu=arm64 +"@istanbuljs/load-nyc-config@npm:^1.0.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" + dependencies: + camelcase: ^5.3.1 + find-up: ^4.1.0 + get-package-type: ^0.1.0 + js-yaml: ^3.13.1 + resolve-from: ^5.0.0 + checksum: d578da5e2e804d5c93228450a1380e1a3c691de4953acc162f387b717258512a3e07b83510a936d9fab03eac90817473917e24f5d16297af3867f59328d58568 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/freebsd-arm64@npm:0.25.9" - conditions: os=freebsd & cpu=arm64 +"@istanbuljs/schema@npm:^0.1.2": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/freebsd-x64@npm:0.17.19" - conditions: os=freebsd & cpu=x64 +"@jest/console@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/console@npm:26.6.2" + dependencies: + "@jest/types": ^26.6.2 + "@types/node": "*" + chalk: ^4.0.0 + jest-message-util: ^26.6.2 + jest-util: ^26.6.2 + slash: ^3.0.0 + checksum: 69a9ca6ba357d7634fd537e3b87c64369865ffb59f57fe6661223088bd62273d0c1d660fefce3625a427f42a37d32590f6b291e1295ea6d6b7cb31ddae36a737 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/freebsd-x64@npm:0.21.5" - conditions: os=freebsd & cpu=x64 +"@jest/core@npm:^26.6.0, @jest/core@npm:^26.6.3": + version: 26.6.3 + resolution: "@jest/core@npm:26.6.3" + dependencies: + "@jest/console": ^26.6.2 + "@jest/reporters": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/transform": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + ansi-escapes: ^4.2.1 + chalk: ^4.0.0 + exit: ^0.1.2 + graceful-fs: ^4.2.4 + jest-changed-files: ^26.6.2 + jest-config: ^26.6.3 + jest-haste-map: ^26.6.2 + jest-message-util: ^26.6.2 + jest-regex-util: ^26.0.0 + jest-resolve: ^26.6.2 + jest-resolve-dependencies: ^26.6.3 + jest-runner: ^26.6.3 + jest-runtime: ^26.6.3 + jest-snapshot: ^26.6.2 + jest-util: ^26.6.2 + jest-validate: ^26.6.2 + jest-watcher: ^26.6.2 + micromatch: ^4.0.2 + p-each-series: ^2.1.0 + rimraf: ^3.0.0 + slash: ^3.0.0 + strip-ansi: ^6.0.0 + checksum: f52b26ffe9b923ed67b3ff30e170b3a434d4263990f78d96cd43acbd0aa8ad36aecad2f1822f376da3a80228714fd6b7f7acd51744133cfcd2780ba0e3da537b languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/freebsd-x64@npm:0.24.2" - conditions: os=freebsd & cpu=x64 +"@jest/environment@npm:^26.6.0, @jest/environment@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/environment@npm:26.6.2" + dependencies: + "@jest/fake-timers": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + jest-mock: ^26.6.2 + checksum: 7748081b2a758161785aff161780b05084dccaff908c8ed82c04f7da5d5e5439e77b5eb667306d5c4e1422653c7a67ed2955f26704f48c65c404195e1e21780a languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/freebsd-x64@npm:0.25.9" - conditions: os=freebsd & cpu=x64 +"@jest/expect-utils@npm:^28.1.3": + version: 28.1.3 + resolution: "@jest/expect-utils@npm:28.1.3" + dependencies: + jest-get-type: ^28.0.2 + checksum: 808ea3a68292a7e0b95490fdd55605c430b4cf209ea76b5b61bfb2a1badcb41bc046810fe4e364bd5fe04663978aa2bd73d8f8465a761dd7c655aeb44cf22987 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-arm64@npm:0.17.19" - conditions: os=linux & cpu=arm64 +"@jest/expect-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect-utils@npm:29.7.0" + dependencies: + jest-get-type: ^29.6.3 + checksum: 75eb177f3d00b6331bcaa057e07c0ccb0733a1d0a1943e1d8db346779039cb7f103789f16e502f888a3096fb58c2300c38d1f3748b36a7fa762eb6f6d1b160ed languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-arm64@npm:0.21.5" - conditions: os=linux & cpu=arm64 +"@jest/fake-timers@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/fake-timers@npm:26.6.2" + dependencies: + "@jest/types": ^26.6.2 + "@sinonjs/fake-timers": ^6.0.1 + "@types/node": "*" + jest-message-util: ^26.6.2 + jest-mock: ^26.6.2 + jest-util: ^26.6.2 + checksum: c732658fac4014a424e6629495296c3b2e8697787518df34c74539ec139625e7141ad792b8a4d3c8392b47954ad01be9846b7c57cc8c631490969e7cafa84e6a languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-arm64@npm:0.24.2" - conditions: os=linux & cpu=arm64 +"@jest/globals@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/globals@npm:26.6.2" + dependencies: + "@jest/environment": ^26.6.2 + "@jest/types": ^26.6.2 + expect: ^26.6.2 + checksum: 49b28d0cc7e99898eeaf23e6899e3c9ee25a2a4831caa3eb930ec1722de2e92a0e8a6a6f649438fdd20ff0c0d5e522dd78cb719466a57f011a88d60419b903c5 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-arm64@npm:0.25.9" - conditions: os=linux & cpu=arm64 +"@jest/reporters@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/reporters@npm:26.6.2" + dependencies: + "@bcoe/v8-coverage": ^0.2.3 + "@jest/console": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/transform": ^26.6.2 + "@jest/types": ^26.6.2 + chalk: ^4.0.0 + collect-v8-coverage: ^1.0.0 + exit: ^0.1.2 + glob: ^7.1.2 + graceful-fs: ^4.2.4 + istanbul-lib-coverage: ^3.0.0 + istanbul-lib-instrument: ^4.0.3 + istanbul-lib-report: ^3.0.0 + istanbul-lib-source-maps: ^4.0.0 + istanbul-reports: ^3.0.2 + jest-haste-map: ^26.6.2 + jest-resolve: ^26.6.2 + jest-util: ^26.6.2 + jest-worker: ^26.6.2 + node-notifier: ^8.0.0 + slash: ^3.0.0 + source-map: ^0.6.0 + string-length: ^4.0.1 + terminal-link: ^2.0.0 + v8-to-istanbul: ^7.0.0 + dependenciesMeta: + node-notifier: + optional: true + checksum: 53c7a697c562becb7682a9a6248ea553013bf7048c08ddce5bf9fb53b975fc9f799ca163f7494e0be6c4d3cf181c8bc392976268da52b7de8ce4470b971ed84e languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-arm@npm:0.17.19" - conditions: os=linux & cpu=arm +"@jest/schemas@npm:^28.1.3": + version: 28.1.3 + resolution: "@jest/schemas@npm:28.1.3" + dependencies: + "@sinclair/typebox": ^0.24.1 + checksum: 3cf1d4b66c9c4ffda58b246de1ddcba8e6ad085af63dccdf07922511f13b68c0cc480a7bc620cb4f3099a6f134801c747e1df7bfc7a4ef4dceefbdea3e31e1de languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-arm@npm:0.21.5" - conditions: os=linux & cpu=arm +"@jest/schemas@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/schemas@npm:29.6.3" + dependencies: + "@sinclair/typebox": ^0.27.8 + checksum: 910040425f0fc93cd13e68c750b7885590b8839066dfa0cd78e7def07bbb708ad869381f725945d66f2284de5663bbecf63e8fdd856e2ae6e261ba30b1687e93 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-arm@npm:0.24.2" - conditions: os=linux & cpu=arm +"@jest/source-map@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/source-map@npm:26.6.2" + dependencies: + callsites: ^3.0.0 + graceful-fs: ^4.2.4 + source-map: ^0.6.0 + checksum: b171cef442738887dda85527ab78229996db5946c6435ddb56d442c2851889ba493729a9de73100f1a31b9a31a91207b55bc75656ae7df9843d65078b925385e languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-arm@npm:0.25.9" - conditions: os=linux & cpu=arm +"@jest/test-result@npm:^26.6.0, @jest/test-result@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/test-result@npm:26.6.2" + dependencies: + "@jest/console": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/istanbul-lib-coverage": ^2.0.0 + collect-v8-coverage: ^1.0.0 + checksum: dcb6175825231e9377e43546aed4edd6acc22f1788d5f099bbba36bb55b9115a92f760e88426c076bcdeff5a50d8f697327a920db0cd1fb339781fc3713fa8c7 languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-ia32@npm:0.17.19" - conditions: os=linux & cpu=ia32 +"@jest/test-sequencer@npm:^26.6.3": + version: 26.6.3 + resolution: "@jest/test-sequencer@npm:26.6.3" + dependencies: + "@jest/test-result": ^26.6.2 + graceful-fs: ^4.2.4 + jest-haste-map: ^26.6.2 + jest-runner: ^26.6.3 + jest-runtime: ^26.6.3 + checksum: a3450b3d7057f74da1828bb7b3658f228a7c049dc4082c5c49b8bafbd8f69d102a8a99007b7ed5d43464712f7823f53fe3564fda17787f178c219cccf329a461 languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-ia32@npm:0.21.5" - conditions: os=linux & cpu=ia32 +"@jest/transform@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/transform@npm:26.6.2" + dependencies: + "@babel/core": ^7.1.0 + "@jest/types": ^26.6.2 + babel-plugin-istanbul: ^6.0.0 + chalk: ^4.0.0 + convert-source-map: ^1.4.0 + fast-json-stable-stringify: ^2.0.0 + graceful-fs: ^4.2.4 + jest-haste-map: ^26.6.2 + jest-regex-util: ^26.0.0 + jest-util: ^26.6.2 + micromatch: ^4.0.2 + pirates: ^4.0.1 + slash: ^3.0.0 + source-map: ^0.6.1 + write-file-atomic: ^3.0.0 + checksum: 31667b925a2f3b310d854495da0ab67be8f5da24df76ecfc51162e75f1140aed5d18069ba190cb5e0c7e492b04272c8c79076ddf5bbcff530ee80a16a02c4545 languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-ia32@npm:0.24.2" - conditions: os=linux & cpu=ia32 +"@jest/types@npm:^26.6.0, @jest/types@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/types@npm:26.6.2" + dependencies: + "@types/istanbul-lib-coverage": ^2.0.0 + "@types/istanbul-reports": ^3.0.0 + "@types/node": "*" + "@types/yargs": ^15.0.0 + chalk: ^4.0.0 + checksum: a0bd3d2f22f26ddb23f41fddf6e6a30bf4fab2ce79ec1cb6ce6fdfaf90a72e00f4c71da91ec61e13db3b10c41de22cf49d07c57ff2b59171d64b29f909c1d8d6 languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-ia32@npm:0.25.9" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/linux-loong64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-loong64@npm:0.17.19" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - -"@esbuild/linux-loong64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-loong64@npm:0.21.5" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - -"@esbuild/linux-loong64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-loong64@npm:0.24.2" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - -"@esbuild/linux-loong64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-loong64@npm:0.25.9" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - -"@esbuild/linux-mips64el@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-mips64el@npm:0.17.19" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"@esbuild/linux-mips64el@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-mips64el@npm:0.21.5" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"@esbuild/linux-mips64el@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-mips64el@npm:0.24.2" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"@esbuild/linux-mips64el@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-mips64el@npm:0.25.9" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"@esbuild/linux-ppc64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-ppc64@npm:0.17.19" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/linux-ppc64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-ppc64@npm:0.21.5" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/linux-ppc64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-ppc64@npm:0.24.2" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/linux-ppc64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-ppc64@npm:0.25.9" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/linux-riscv64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-riscv64@npm:0.17.19" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"@esbuild/linux-riscv64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-riscv64@npm:0.21.5" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"@esbuild/linux-riscv64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-riscv64@npm:0.24.2" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"@esbuild/linux-riscv64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-riscv64@npm:0.25.9" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"@esbuild/linux-s390x@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-s390x@npm:0.17.19" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"@esbuild/linux-s390x@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-s390x@npm:0.21.5" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"@esbuild/linux-s390x@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-s390x@npm:0.24.2" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"@esbuild/linux-s390x@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-s390x@npm:0.25.9" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"@esbuild/linux-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/linux-x64@npm:0.17.19" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/linux-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/linux-x64@npm:0.21.5" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/linux-x64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/linux-x64@npm:0.24.2" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/linux-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-x64@npm:0.25.9" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/netbsd-arm64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/netbsd-arm64@npm:0.24.2" - conditions: os=netbsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/netbsd-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/netbsd-arm64@npm:0.25.9" - conditions: os=netbsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/netbsd-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/netbsd-x64@npm:0.17.19" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/netbsd-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/netbsd-x64@npm:0.21.5" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/netbsd-x64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/netbsd-x64@npm:0.24.2" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/netbsd-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/netbsd-x64@npm:0.25.9" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openbsd-arm64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/openbsd-arm64@npm:0.24.2" - conditions: os=openbsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/openbsd-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/openbsd-arm64@npm:0.25.9" - conditions: os=openbsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/openbsd-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/openbsd-x64@npm:0.17.19" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openbsd-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/openbsd-x64@npm:0.21.5" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openbsd-x64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/openbsd-x64@npm:0.24.2" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openbsd-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/openbsd-x64@npm:0.25.9" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openharmony-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/openharmony-arm64@npm:0.25.9" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/sunos-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/sunos-x64@npm:0.17.19" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/sunos-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/sunos-x64@npm:0.21.5" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/sunos-x64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/sunos-x64@npm:0.24.2" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/sunos-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/sunos-x64@npm:0.25.9" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/win32-arm64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/win32-arm64@npm:0.17.19" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/win32-arm64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/win32-arm64@npm:0.21.5" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/win32-arm64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/win32-arm64@npm:0.24.2" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/win32-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/win32-arm64@npm:0.25.9" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/win32-ia32@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/win32-ia32@npm:0.17.19" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/win32-ia32@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/win32-ia32@npm:0.21.5" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/win32-ia32@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/win32-ia32@npm:0.24.2" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/win32-ia32@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/win32-ia32@npm:0.25.9" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/win32-x64@npm:0.17.19": - version: 0.17.19 - resolution: "@esbuild/win32-x64@npm:0.17.19" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/win32-x64@npm:0.21.5": - version: 0.21.5 - resolution: "@esbuild/win32-x64@npm:0.21.5" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/win32-x64@npm:0.24.2": - version: 0.24.2 - resolution: "@esbuild/win32-x64@npm:0.24.2" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/win32-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/win32-x64@npm:0.25.9" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.9.0 - resolution: "@eslint-community/eslint-utils@npm:4.9.0" - dependencies: - eslint-visitor-keys: ^3.4.3 - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: ae9b98eea006d1354368804b0116b8b45017a4e47b486d1b9cfa048a8ed3dc69b9b074eb2b2acb14034e6897c24048fd42b6a6816d9dc8bb9daad79db7d478d2 - languageName: node - linkType: hard - -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.6.1": - version: 4.12.1 - resolution: "@eslint-community/regexpp@npm:4.12.1" - checksum: 0d628680e204bc316d545b4993d3658427ca404ae646ce541fcc65306b8c712c340e5e573e30fb9f85f4855c0c5f6dca9868931f2fcced06417fbe1a0c6cd2d6 - languageName: node - linkType: hard - -"@eslint/eslintrc@npm:^0.4.3": - version: 0.4.3 - resolution: "@eslint/eslintrc@npm:0.4.3" - dependencies: - ajv: ^6.12.4 - debug: ^4.1.1 - espree: ^7.3.0 - globals: ^13.9.0 - ignore: ^4.0.6 - import-fresh: ^3.2.1 - js-yaml: ^3.13.1 - minimatch: ^3.0.4 - strip-json-comments: ^3.1.1 - checksum: 03a7704150b868c318aab6a94d87a33d30dc2ec579d27374575014f06237ba1370ae11178db772f985ef680d469dc237e7b16a1c5d8edaaeb8c3733e7a95a6d3 - languageName: node - linkType: hard - -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" - dependencies: - ajv: ^6.12.4 - debug: ^4.3.2 - espree: ^9.6.0 - globals: ^13.19.0 - ignore: ^5.2.0 - import-fresh: ^3.2.1 - js-yaml: ^4.1.0 - minimatch: ^3.1.2 - strip-json-comments: ^3.1.1 - checksum: 10957c7592b20ca0089262d8c2a8accbad14b4f6507e35416c32ee6b4dbf9cad67dfb77096bbd405405e9ada2b107f3797fe94362e1c55e0b09d6e90dd149127 - languageName: node - linkType: hard - -"@eslint/js@npm:8.57.1": - version: 8.57.1 - resolution: "@eslint/js@npm:8.57.1" - checksum: 2afb77454c06e8316793d2e8e79a0154854d35e6782a1217da274ca60b5044d2c69d6091155234ed0551a1e408f86f09dd4ece02752c59568fa403e60611e880 - languageName: node - linkType: hard - -"@floating-ui/core@npm:^1.7.3": - version: 1.7.3 - resolution: "@floating-ui/core@npm:1.7.3" - dependencies: - "@floating-ui/utils": ^0.2.10 - checksum: 5adfb28ddfa1776ec83516439256b9026e5d62b5413f62ae51e50a870cf0df4bea9abf72aacc0610ee84bc00e85883d0d32f2a0976ee7fa89728a717a7494f27 - languageName: node - linkType: hard - -"@floating-ui/dom@npm:^1.7.4": - version: 1.7.4 - resolution: "@floating-ui/dom@npm:1.7.4" - dependencies: - "@floating-ui/core": ^1.7.3 - "@floating-ui/utils": ^0.2.10 - checksum: 806923e6f5b09e024c366070f2115a4db6e8ad28462bac29cd075170a6f7d900497da3ee542439bd0770b8e2fff12b636cc30873d1c82e9ec4a487870b080643 - languageName: node - linkType: hard - -"@floating-ui/react-dom@npm:^2.1.1": - version: 2.1.6 - resolution: "@floating-ui/react-dom@npm:2.1.6" - dependencies: - "@floating-ui/dom": ^1.7.4 - peerDependencies: - react: ">=16.8.0" - react-dom: ">=16.8.0" - checksum: 24ff266806cd4cba6ad066f0eda7b99583f68af877f41df0b2a8d10a392692e3a1c1d666ebb75571a060818ede940bae59d833aa517ed538f7dba9dddd9991ae - languageName: node - linkType: hard - -"@floating-ui/utils@npm:^0.2.10": - version: 0.2.10 - resolution: "@floating-ui/utils@npm:0.2.10" - checksum: ffc4c24a46a665cfd0337e9aaf7de8415b572f8a0f323af39175e4b575582aed13d172e7f049eedeece9eaf022bad019c140a2d192580451984ae529bdf1285c - languageName: node - linkType: hard - -"@hello-pangea/dnd@npm:^17.0.0": - version: 17.0.0 - resolution: "@hello-pangea/dnd@npm:17.0.0" - dependencies: - "@babel/runtime": ^7.25.6 - css-box-model: ^1.2.1 - memoize-one: ^6.0.0 - raf-schd: ^4.0.3 - react-redux: ^9.1.2 - redux: ^5.0.1 - use-memo-one: ^1.1.3 - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - checksum: a0da6a41b741b8c77ca6e2d6f54c3ce5a0daf92c0fd3b4ad1a63d40fd166a7d7aec0993c1d4f29e9c7f9c43a00cf74393fcb33afb7422450a974eb63f50a89da - languageName: node - linkType: hard - -"@hookform/resolvers@npm:^3.10.0": - version: 3.10.0 - resolution: "@hookform/resolvers@npm:3.10.0" - peerDependencies: - react-hook-form: ^7.0.0 - checksum: e062f10bebff696a669fe37388f64f6b7c322eb524e99008c0e157e7adf68d2cee4d86fce1a7304a80d7f6fdd6d92facc37320a539cb195235a31a680415760c - languageName: node - linkType: hard - -"@humanwhocodes/config-array@npm:^0.13.0": - version: 0.13.0 - resolution: "@humanwhocodes/config-array@npm:0.13.0" - dependencies: - "@humanwhocodes/object-schema": ^2.0.3 - debug: ^4.3.1 - minimatch: ^3.0.5 - checksum: eae69ff9134025dd2924f0b430eb324981494be26f0fddd267a33c28711c4db643242cf9fddf7dadb9d16c96b54b2d2c073e60a56477df86e0173149313bd5d6 - languageName: node - linkType: hard - -"@humanwhocodes/config-array@npm:^0.5.0": - version: 0.5.0 - resolution: "@humanwhocodes/config-array@npm:0.5.0" - dependencies: - "@humanwhocodes/object-schema": ^1.2.0 - debug: ^4.1.1 - minimatch: ^3.0.4 - checksum: 44ee6a9f05d93dd9d5935a006b17572328ba9caff8002442f601736cbda79c580cc0f5a49ce9eb88fbacc5c3a6b62098357c2e95326cd17bb9f1a6c61d6e95e7 - languageName: node - linkType: hard - -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 0fd22007db8034a2cdf2c764b140d37d9020bbfce8a49d3ec5c05290e77d4b0263b1b972b752df8c89e5eaa94073408f2b7d977aed131faf6cf396ebb5d7fb61 - languageName: node - linkType: hard - -"@humanwhocodes/object-schema@npm:^1.2.0": - version: 1.2.1 - resolution: "@humanwhocodes/object-schema@npm:1.2.1" - checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 - languageName: node - linkType: hard - -"@humanwhocodes/object-schema@npm:^2.0.3": - version: 2.0.3 - resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: d3b78f6c5831888c6ecc899df0d03bcc25d46f3ad26a11d7ea52944dc36a35ef543fad965322174238d677a43d5c694434f6607532cff7077062513ad7022631 - languageName: node - linkType: hard - -"@inquirer/confirm@npm:^5.0.0": - version: 5.1.16 - resolution: "@inquirer/confirm@npm:5.1.16" - dependencies: - "@inquirer/core": ^10.2.0 - "@inquirer/type": ^3.0.8 - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: c81a1394125a68e47a82cd819392f9ee0dcbd736b49ab1907197e032718c2f8e03e31b5fdf65ca6f9b5d512155e8df19be9eca258e9c38ed3a36628a54584a2a - languageName: node - linkType: hard - -"@inquirer/core@npm:^10.2.0": - version: 10.2.0 - resolution: "@inquirer/core@npm:10.2.0" - dependencies: - "@inquirer/figures": ^1.0.13 - "@inquirer/type": ^3.0.8 - ansi-escapes: ^4.3.2 - cli-width: ^4.1.0 - mute-stream: ^2.0.0 - signal-exit: ^4.1.0 - wrap-ansi: ^6.2.0 - yoctocolors-cjs: ^2.1.2 - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 8302712646d52e2bf210f7529143a0422cb706979d1d7f344557a2f78773457d6c9ac0aba04678b3fdf9c528dbce1c9e671636d06cf9d14da5b2e08bbf2a8356 - languageName: node - linkType: hard - -"@inquirer/figures@npm:^1.0.13": - version: 1.0.13 - resolution: "@inquirer/figures@npm:1.0.13" - checksum: 1042cbefad8c69b004396ce6be2d0b135c303317d870ddd0cee75bac429fc7c7f577bac9e3c1ec1cd3668a709f49a591edb2f714193778e7d7b140a622f2a1ef - languageName: node - linkType: hard - -"@inquirer/type@npm:^3.0.8": - version: 3.0.8 - resolution: "@inquirer/type@npm:3.0.8" - peerDependencies: - "@types/node": ">=18" - peerDependenciesMeta: - "@types/node": - optional: true - checksum: 361fa75c98f274462aaa3f2baf40ee43f284daaa64e3689a92863ed4ff63236ca3d40c6e715b3ff80c45feb6ab679792a6162e2d4521daff3929c490b0dddfcf - languageName: node - linkType: hard - -"@isaacs/balanced-match@npm:^4.0.1": - version: 4.0.1 - resolution: "@isaacs/balanced-match@npm:4.0.1" - checksum: 102fbc6d2c0d5edf8f6dbf2b3feb21695a21bc850f11bc47c4f06aa83bd8884fde3fe9d6d797d619901d96865fdcb4569ac2a54c937992c48885c5e3d9967fe8 - languageName: node - linkType: hard - -"@isaacs/brace-expansion@npm:^5.0.0": - version: 5.0.0 - resolution: "@isaacs/brace-expansion@npm:5.0.0" - dependencies: - "@isaacs/balanced-match": ^4.0.1 - checksum: d7a3b8b0ddbf0ccd8eeb1300e29dd0a0c02147e823d8138f248375a365682360620895c66d113e05ee02389318c654379b0e538b996345b83c914941786705b1 - languageName: node - linkType: hard - -"@isaacs/cliui@npm:^8.0.2": - version: 8.0.2 - resolution: "@isaacs/cliui@npm:8.0.2" - 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" - checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb - languageName: node - linkType: hard - -"@isaacs/fs-minipass@npm:^4.0.0": - version: 4.0.1 - resolution: "@isaacs/fs-minipass@npm:4.0.1" - dependencies: - minipass: ^7.0.4 - checksum: 5d36d289960e886484362d9eb6a51d1ea28baed5f5d0140bbe62b99bac52eaf06cc01c2bc0d3575977962f84f6b2c4387b043ee632216643d4787b0999465bf2 - languageName: node - linkType: hard - -"@istanbuljs/load-nyc-config@npm:^1.0.0": - version: 1.1.0 - resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" - dependencies: - camelcase: ^5.3.1 - find-up: ^4.1.0 - get-package-type: ^0.1.0 - js-yaml: ^3.13.1 - resolve-from: ^5.0.0 - checksum: d578da5e2e804d5c93228450a1380e1a3c691de4953acc162f387b717258512a3e07b83510a936d9fab03eac90817473917e24f5d16297af3867f59328d58568 - languageName: node - linkType: hard - -"@istanbuljs/schema@npm:^0.1.2": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 - languageName: node - linkType: hard - -"@jest/console@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/console@npm:27.5.1" - dependencies: - "@jest/types": ^27.5.1 - "@types/node": "*" - chalk: ^4.0.0 - jest-message-util: ^27.5.1 - jest-util: ^27.5.1 - slash: ^3.0.0 - checksum: 7cb20f06a34b09734c0342685ec53aa4c401fe3757c13a9c58fce76b971a322eb884f6de1068ef96f746e5398e067371b89515a07c268d4440a867c87748a706 - languageName: node - linkType: hard - -"@jest/console@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/console@npm:28.1.3" - dependencies: - "@jest/types": ^28.1.3 - "@types/node": "*" - chalk: ^4.0.0 - jest-message-util: ^28.1.3 - jest-util: ^28.1.3 - slash: ^3.0.0 - checksum: fe50d98d26d02ce2901c76dff4bd5429a33c13affb692c9ebf8a578ca2f38a5dd854363d40d6c394f215150791fd1f692afd8e730a4178dda24107c8dfd9750a - languageName: node - linkType: hard - -"@jest/core@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/core@npm:27.5.1" - dependencies: - "@jest/console": ^27.5.1 - "@jest/reporters": ^27.5.1 - "@jest/test-result": ^27.5.1 - "@jest/transform": ^27.5.1 - "@jest/types": ^27.5.1 - "@types/node": "*" - ansi-escapes: ^4.2.1 - chalk: ^4.0.0 - emittery: ^0.8.1 - exit: ^0.1.2 - graceful-fs: ^4.2.9 - jest-changed-files: ^27.5.1 - jest-config: ^27.5.1 - jest-haste-map: ^27.5.1 - jest-message-util: ^27.5.1 - jest-regex-util: ^27.5.1 - jest-resolve: ^27.5.1 - jest-resolve-dependencies: ^27.5.1 - jest-runner: ^27.5.1 - jest-runtime: ^27.5.1 - jest-snapshot: ^27.5.1 - jest-util: ^27.5.1 - jest-validate: ^27.5.1 - jest-watcher: ^27.5.1 - micromatch: ^4.0.4 - rimraf: ^3.0.0 - slash: ^3.0.0 - strip-ansi: ^6.0.0 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: 904a94ad8f1b43cd6b48de3b0226659bff3696150ff8cf7680fc2faffdc8a115203bb9ab6e817c1f79f9d6a81f67953053cbc64d8a4604f2e0c42a04c28cf126 - languageName: node - linkType: hard - -"@jest/environment@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/environment@npm:27.5.1" - dependencies: - "@jest/fake-timers": ^27.5.1 - "@jest/types": ^27.5.1 - "@types/node": "*" - jest-mock: ^27.5.1 - checksum: 2a9e18c35a015508dbec5b90b21c150230fa6c1c8cb8fabe029d46ee2ca4c40eb832fb636157da14c66590d0a4c8a2c053226b041f54a44507d6f6a89abefd66 - languageName: node - linkType: hard - -"@jest/expect-utils@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/expect-utils@npm:29.7.0" - dependencies: - jest-get-type: ^29.6.3 - checksum: 75eb177f3d00b6331bcaa057e07c0ccb0733a1d0a1943e1d8db346779039cb7f103789f16e502f888a3096fb58c2300c38d1f3748b36a7fa762eb6f6d1b160ed - languageName: node - linkType: hard - -"@jest/fake-timers@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/fake-timers@npm:27.5.1" - dependencies: - "@jest/types": ^27.5.1 - "@sinonjs/fake-timers": ^8.0.1 - "@types/node": "*" - jest-message-util: ^27.5.1 - jest-mock: ^27.5.1 - jest-util: ^27.5.1 - checksum: 02a0561ed2f4586093facd4ae500b74694f187ac24d4a00e949a39a1c5325bca8932b4fcb0388a2c5ed0656506fc1cf51fd3e32cdd48cea7497ad9c6e028aba8 - languageName: node - linkType: hard - -"@jest/globals@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/globals@npm:27.5.1" - dependencies: - "@jest/environment": ^27.5.1 - "@jest/types": ^27.5.1 - expect: ^27.5.1 - checksum: 087f97047e9dcf555f76fe2ce54aee681e005eaa837a0c0c2d251df6b6412c892c9df54cb871b180342114389a5ff895a4e52e6e6d3d0015bf83c02a54f64c3c - languageName: node - linkType: hard - -"@jest/reporters@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/reporters@npm:27.5.1" - dependencies: - "@bcoe/v8-coverage": ^0.2.3 - "@jest/console": ^27.5.1 - "@jest/test-result": ^27.5.1 - "@jest/transform": ^27.5.1 - "@jest/types": ^27.5.1 - "@types/node": "*" - chalk: ^4.0.0 - collect-v8-coverage: ^1.0.0 - exit: ^0.1.2 - glob: ^7.1.2 - graceful-fs: ^4.2.9 - istanbul-lib-coverage: ^3.0.0 - istanbul-lib-instrument: ^5.1.0 - istanbul-lib-report: ^3.0.0 - istanbul-lib-source-maps: ^4.0.0 - istanbul-reports: ^3.1.3 - jest-haste-map: ^27.5.1 - jest-resolve: ^27.5.1 - jest-util: ^27.5.1 - jest-worker: ^27.5.1 - slash: ^3.0.0 - source-map: ^0.6.0 - string-length: ^4.0.1 - terminal-link: ^2.0.0 - v8-to-istanbul: ^8.1.0 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: faba5eafb86e62b62e152cafc8812d56308f9d1e8b77f3a7dcae4a8803a20a60a0909cc43ed73363ef649bf558e4fb181c7a336d144c89f7998279d1882bb69e - languageName: node - linkType: hard - -"@jest/schemas@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/schemas@npm:28.1.3" - dependencies: - "@sinclair/typebox": ^0.24.1 - checksum: 3cf1d4b66c9c4ffda58b246de1ddcba8e6ad085af63dccdf07922511f13b68c0cc480a7bc620cb4f3099a6f134801c747e1df7bfc7a4ef4dceefbdea3e31e1de - languageName: node - linkType: hard - -"@jest/schemas@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/schemas@npm:29.6.3" - dependencies: - "@sinclair/typebox": ^0.27.8 - checksum: 910040425f0fc93cd13e68c750b7885590b8839066dfa0cd78e7def07bbb708ad869381f725945d66f2284de5663bbecf63e8fdd856e2ae6e261ba30b1687e93 - languageName: node - linkType: hard - -"@jest/source-map@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/source-map@npm:27.5.1" - dependencies: - callsites: ^3.0.0 - graceful-fs: ^4.2.9 - source-map: ^0.6.0 - checksum: 4fb1e743b602841babf7e22bd84eca34676cb05d4eb3b604cae57fc59e406099f5ac759ac1a0d04d901237d143f0f4f234417306e823bde732a1d19982230862 - languageName: node - linkType: hard - -"@jest/test-result@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/test-result@npm:27.5.1" - dependencies: - "@jest/console": ^27.5.1 - "@jest/types": ^27.5.1 - "@types/istanbul-lib-coverage": ^2.0.0 - collect-v8-coverage: ^1.0.0 - checksum: 338f7c509d6a3bc6d7dd7388c8f6f548b87638e171dc1fddfedcacb4e8950583288832223ba688058cbcf874b937d22bdc0fa88f79f5fc666f77957e465c06a5 - languageName: node - linkType: hard - -"@jest/test-result@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/test-result@npm:28.1.3" - dependencies: - "@jest/console": ^28.1.3 - "@jest/types": ^28.1.3 - "@types/istanbul-lib-coverage": ^2.0.0 - collect-v8-coverage: ^1.0.0 - checksum: 957a5dd2fd2e84aabe86698f93c0825e96128ccaa23abf548b159a9b08ac74e4bde7acf4bec48479243dbdb27e4ea1b68c171846d21fb64855c6b55cead9ef27 - languageName: node - linkType: hard - -"@jest/test-sequencer@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/test-sequencer@npm:27.5.1" - dependencies: - "@jest/test-result": ^27.5.1 - graceful-fs: ^4.2.9 - jest-haste-map: ^27.5.1 - jest-runtime: ^27.5.1 - checksum: f21f9c8bb746847f7f89accfd29d6046eec1446f0b54e4694444feaa4df379791f76ef0f5a4360aafcbc73b50bc979f68b8a7620de404019d3de166be6720cb0 - languageName: node - linkType: hard - -"@jest/transform@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/transform@npm:27.5.1" - dependencies: - "@babel/core": ^7.1.0 - "@jest/types": ^27.5.1 - babel-plugin-istanbul: ^6.1.1 - chalk: ^4.0.0 - convert-source-map: ^1.4.0 - fast-json-stable-stringify: ^2.0.0 - graceful-fs: ^4.2.9 - jest-haste-map: ^27.5.1 - jest-regex-util: ^27.5.1 - jest-util: ^27.5.1 - micromatch: ^4.0.4 - pirates: ^4.0.4 - slash: ^3.0.0 - source-map: ^0.6.1 - write-file-atomic: ^3.0.0 - checksum: a22079121aedea0f20a03a9c026be971f7b92adbfb4d5fd1fb67be315741deac4f056936d7c72a53b24aa5a1071bc942c003925fd453bf3f6a0ae5da6384e137 - languageName: node - linkType: hard - -"@jest/types@npm:^27.5.1": - version: 27.5.1 - resolution: "@jest/types@npm:27.5.1" - dependencies: - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^16.0.0 - chalk: ^4.0.0 - checksum: d1f43cc946d87543ddd79d49547aab2399481d34025d5c5f2025d3d99c573e1d9832fa83cef25e9d9b07a8583500229d15bbb07b8e233d127d911d133e2f14b1 - languageName: node - linkType: hard - -"@jest/types@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/types@npm:28.1.3" - dependencies: - "@jest/schemas": ^28.1.3 - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^17.0.8 - chalk: ^4.0.0 - checksum: 1e258d9c063fcf59ebc91e46d5ea5984674ac7ae6cae3e50aa780d22b4405bf2c925f40350bf30013839eb5d4b5e521d956ddf8f3b7c78debef0e75a07f57350 - languageName: node - linkType: hard - -"@jest/types@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/types@npm:29.6.3" - dependencies: - "@jest/schemas": ^29.6.3 - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^17.0.8 - chalk: ^4.0.0 - checksum: a0bcf15dbb0eca6bdd8ce61a3fb055349d40268622a7670a3b2eb3c3dbafe9eb26af59938366d520b86907b9505b0f9b29b85cec11579a9e580694b87cd90fcc - languageName: node - linkType: hard - -"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.13 - resolution: "@jridgewell/gen-mapping@npm:0.3.13" - dependencies: - "@jridgewell/sourcemap-codec": ^1.5.0 - "@jridgewell/trace-mapping": ^0.3.24 - checksum: f2105acefc433337145caa3c84bba286de954f61c0bc46279bbd85a9e6a02871089717fa060413cfb6a9d44189fe8313b2d1cabf3a2eb3284d208fd5f75c54ff - languageName: node - linkType: hard - -"@jridgewell/remapping@npm:^2.3.5": - version: 2.3.5 - resolution: "@jridgewell/remapping@npm:2.3.5" - dependencies: - "@jridgewell/gen-mapping": ^0.3.5 - "@jridgewell/trace-mapping": ^0.3.24 - checksum: 4a66a7397c3dc9c6b5c14a0024b1f98c5e1d90a0dbc1e5955b5038f2db339904df2a0ee8a66559fafb4fc23ff33700a2639fd40bbdd2e9e82b58b3bdf83738e3 - languageName: node - linkType: hard - -"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": - version: 3.1.2 - resolution: "@jridgewell/resolve-uri@npm:3.1.2" - checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 - languageName: node - linkType: hard - -"@jridgewell/source-map@npm:^0.3.3": - version: 0.3.11 - resolution: "@jridgewell/source-map@npm:0.3.11" - dependencies: - "@jridgewell/gen-mapping": ^0.3.5 - "@jridgewell/trace-mapping": ^0.3.25 - checksum: c8a0011cc67e701f270fa042e32b312f382c413bcc70ca9c03684687cbf5b64d5eed87d4afa36dddaabe60ab3da6db4935f878febd9cfc7f82724ea1a114d344 - languageName: node - linkType: hard - -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": - version: 1.5.5 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" - checksum: c2e36e67971f719a8a3a85ef5a5f580622437cc723c35d03ebd0c9c0b06418700ef006f58af742791f71f6a4fc68fcfaf1f6a74ec2f9a3332860e9373459dae7 - languageName: node - linkType: hard - -"@jridgewell/trace-mapping@npm:0.3.9": - version: 0.3.9 - resolution: "@jridgewell/trace-mapping@npm:0.3.9" - dependencies: - "@jridgewell/resolve-uri": ^3.0.3 - "@jridgewell/sourcemap-codec": ^1.4.10 - checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef - languageName: node - linkType: hard - -"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": - version: 0.3.31 - resolution: "@jridgewell/trace-mapping@npm:0.3.31" - dependencies: - "@jridgewell/resolve-uri": ^3.1.0 - "@jridgewell/sourcemap-codec": ^1.4.14 - checksum: af8fda2431348ad507fbddf8e25f5d08c79ecc94594061ce402cf41bc5aba1a7b3e59bf0fd70a619b35f33983a3f488ceeba8faf56bff784f98bb5394a8b7d47 - languageName: node - linkType: hard - -"@kurkle/color@npm:^0.3.0": - version: 0.3.4 - resolution: "@kurkle/color@npm:0.3.4" - checksum: b95c6abe0241ba1745b3c84de3b464296b95ce577110b54f46e6c6dcc9a0966491533df43812bd6c66f92cf818e385d1390b280cd5851d4afb52fc37f8a6c0b9 - languageName: node - linkType: hard - -"@leichtgewicht/ip-codec@npm:^2.0.1": - version: 2.0.5 - resolution: "@leichtgewicht/ip-codec@npm:2.0.5" - checksum: 4fcd025d0a923cb6b87b631a83436a693b255779c583158bbeacde6b4dd75b94cc1eba1c9c188de5fc36c218d160524ea08bfe4ef03a056b00ff14126d66f881 - languageName: node - linkType: hard - -"@mswjs/interceptors@npm:^0.39.1": - version: 0.39.6 - resolution: "@mswjs/interceptors@npm:0.39.6" - dependencies: - "@open-draft/deferred-promise": ^2.2.0 - "@open-draft/logger": ^0.3.0 - "@open-draft/until": ^2.0.0 - is-node-process: ^1.2.0 - outvariant: ^1.4.3 - strict-event-emitter: ^0.5.1 - checksum: 4960ad247aeabdb6465754ab4646b6441032bdc26cef8c38696240cd3968e99533363f7e71f5d3f8f170b49456c2f1294920c28031327ea7d721320e3863b546 - languageName: node - linkType: hard - -"@mui/base@npm:5.0.0-beta.58": - version: 5.0.0-beta.58 - resolution: "@mui/base@npm:5.0.0-beta.58" - dependencies: - "@babel/runtime": ^7.25.0 - "@floating-ui/react-dom": ^2.1.1 - "@mui/types": ^7.2.15 - "@mui/utils": 6.0.0-rc.0 - "@popperjs/core": ^2.11.8 - clsx: ^2.1.1 - prop-types: ^15.8.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 3603b505aee55aace9be3f4f8fd9c0fde85dfa5d33434bde7651ccd309df3d6872e56603f7739871545bff1cbfdbae0e821a9c60895fbafb049ff5072a77d768 - languageName: node - linkType: hard - -"@mui/core-downloads-tracker@npm:^6.5.0": - version: 6.5.0 - resolution: "@mui/core-downloads-tracker@npm:6.5.0" - checksum: 4354158b8a5f92dea633bb2713bcc0d04493be4038808c44329d3143a0c928914f01e67cb607d0c610bde1f541515c422f69456e50ff919546d1b1f2d349b908 - languageName: node - linkType: hard - -"@mui/icons-material@npm:^6.4.0": - version: 6.5.0 - resolution: "@mui/icons-material@npm:6.5.0" - dependencies: - "@babel/runtime": ^7.26.0 - peerDependencies: - "@mui/material": ^6.5.0 - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 2c1311684cf5bc15faf7b47adc64adbeb02bc1e1b25bb7c2440df10a9ad66c1bd4f8d87e71b75d67f70a32905bdb63e90fd2567a8142f0fa7100c96bbeb127b8 - languageName: node - linkType: hard - -"@mui/lab@npm:6.0.0-beta.10": - version: 6.0.0-beta.10 - resolution: "@mui/lab@npm:6.0.0-beta.10" - dependencies: - "@babel/runtime": ^7.25.6 - "@mui/base": 5.0.0-beta.58 - "@mui/system": ^6.1.1 - "@mui/types": ^7.2.17 - "@mui/utils": ^6.1.1 - clsx: ^2.1.1 - prop-types: ^15.8.1 - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@mui/material": ^6.1.1 - "@mui/material-pigment-css": ^6.1.1 - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@mui/material-pigment-css": - optional: true - "@types/react": - optional: true - checksum: 45f2fba7528b84cfd56b6eb1d4ed541069c962dc8ae15c86842a19ba809f6a84e8aeb47e1e33fd07ac32c722cee684cfbe43ba1a91c7b68e7b51a508ed9c2ad8 - languageName: node - linkType: hard - -"@mui/material@npm:^6.4.0": - version: 6.5.0 - resolution: "@mui/material@npm:6.5.0" - dependencies: - "@babel/runtime": ^7.26.0 - "@mui/core-downloads-tracker": ^6.5.0 - "@mui/system": ^6.5.0 - "@mui/types": ~7.2.24 - "@mui/utils": ^6.4.9 - "@popperjs/core": ^2.11.8 - "@types/react-transition-group": ^4.4.12 - clsx: ^2.1.1 - csstype: ^3.1.3 - prop-types: ^15.8.1 - react-is: ^19.0.0 - react-transition-group: ^4.4.5 - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@mui/material-pigment-css": ^6.5.0 - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@mui/material-pigment-css": - optional: true - "@types/react": - optional: true - checksum: a92876ddde82e7569d1e07baefaf84655c00b8323fbe99d1b6a18eb655ff1716fa57660a2f70cfe9381842eabcd71be203fa3efd28be5511c3bf962406217222 - languageName: node - linkType: hard - -"@mui/private-theming@npm:^6.4.9": - version: 6.4.9 - resolution: "@mui/private-theming@npm:6.4.9" - dependencies: - "@babel/runtime": ^7.26.0 - "@mui/utils": ^6.4.9 - prop-types: ^15.8.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 13ffb0b657517fc7c33eab6a19f7b63b7b23fb45fa871ccad5f3c320a49b1cc8a812a7ad03184b38b38082907196c427fcb936fda0952637f809c9ecb16925a1 - languageName: node - linkType: hard - -"@mui/styled-engine@npm:^6.5.0": - version: 6.5.0 - resolution: "@mui/styled-engine@npm:6.5.0" - dependencies: - "@babel/runtime": ^7.26.0 - "@emotion/cache": ^11.13.5 - "@emotion/serialize": ^1.3.3 - "@emotion/sheet": ^1.4.0 - csstype: ^3.1.3 - prop-types: ^15.8.1 - peerDependencies: - "@emotion/react": ^11.4.1 - "@emotion/styled": ^11.3.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - checksum: 6b1d896a694fc96099985330fb75669bb272b242583b5d8f6ae0c048649145d3cfdb0e110dc71d85e37eb480f7fd6e319f17c5a5c6484a85e149cade21789f52 - languageName: node - linkType: hard - -"@mui/system@npm:^6.1.1, @mui/system@npm:^6.4.0, @mui/system@npm:^6.5.0": - version: 6.5.0 - resolution: "@mui/system@npm:6.5.0" - dependencies: - "@babel/runtime": ^7.26.0 - "@mui/private-theming": ^6.4.9 - "@mui/styled-engine": ^6.5.0 - "@mui/types": ~7.2.24 - "@mui/utils": ^6.4.9 - clsx: ^2.1.1 - csstype: ^3.1.3 - prop-types: ^15.8.1 - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@types/react": - optional: true - checksum: d20d717d53551861f2656a367fe796c2e8b07e131ce5a84fadab6d9bd436a5cb4516ed3c0e6e9dd55e40ada8d0c1ef8d4d29a40562b628cf6bb877942aeaa7c6 - languageName: node - linkType: hard - -"@mui/types@npm:^7.2.15, @mui/types@npm:^7.2.17, @mui/types@npm:^7.4.6": - version: 7.4.6 - resolution: "@mui/types@npm:7.4.6" - dependencies: - "@babel/runtime": ^7.28.3 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 7e4b4ae06066468e8a8211376d0a08250325f4b92f6d2ea24576df37dfcd0f683602567debdf15889e0e4510eb48d677aa0d71a2ed9423c16dbd4b4ecfbccbb9 - languageName: node - linkType: hard - -"@mui/types@npm:~7.2.15, @mui/types@npm:~7.2.24": - version: 7.2.24 - resolution: "@mui/types@npm:7.2.24" - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 3a7367f9503e90fc3cce78885b57b54a00f7a04108be8af957fdc882c1bc0af68390920ea3d6aef855e704651ffd4a530e36ccbec4d0f421a176a2c3c432bb95 - languageName: node - linkType: hard - -"@mui/utils@npm:6.0.0-rc.0": - version: 6.0.0-rc.0 - resolution: "@mui/utils@npm:6.0.0-rc.0" - dependencies: - "@babel/runtime": ^7.25.0 - "@mui/types": ^7.2.15 - "@types/prop-types": ^15.7.12 - clsx: ^2.1.1 - prop-types: ^15.8.1 - react-is: ^18.3.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: c2efc89be9f4f0e13d18fd2bdd46c69ef4d7c70b22f5e2026a4a23e443be90f3314599d30f5458e0c7fc48d6c4bac975be278a14f09592315811d59c7ce74825 - languageName: node - linkType: hard - -"@mui/utils@npm:^5.10.3": - version: 5.17.1 - resolution: "@mui/utils@npm:5.17.1" - dependencies: - "@babel/runtime": ^7.23.9 - "@mui/types": ~7.2.15 - "@types/prop-types": ^15.7.12 - clsx: ^2.1.1 - prop-types: ^15.8.1 - react-is: ^19.0.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 06f9da7025b9291f1052c0af012fd0f00ff1539bc99880e15f483a85c27bff0e9c3d047511dc5c3177d546c21978227ece2e6f7a7bd91903c72b48b89c45a677 - languageName: node - linkType: hard - -"@mui/utils@npm:^5.16.6 || ^6.0.0 || ^7.0.0": - version: 7.3.2 - resolution: "@mui/utils@npm:7.3.2" - dependencies: - "@babel/runtime": ^7.28.3 - "@mui/types": ^7.4.6 - "@types/prop-types": ^15.7.15 - clsx: ^2.1.1 - prop-types: ^15.8.1 - react-is: ^19.1.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 201fb1f49434c3ee12de3a177660af04cb6411a68f8c13dc62ea828c522758b53040046daf2341b38da3b0a8a455ef4454a49cca4fa4e7b4d345d05e3ca61ecc - languageName: node - linkType: hard - -"@mui/utils@npm:^6.1.1, @mui/utils@npm:^6.4.9": - version: 6.4.9 - resolution: "@mui/utils@npm:6.4.9" - dependencies: - "@babel/runtime": ^7.26.0 - "@mui/types": ~7.2.24 - "@types/prop-types": ^15.7.14 - clsx: ^2.1.1 - prop-types: ^15.8.1 - react-is: ^19.0.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: b11d8f76d1c3a6c256a0b832b19b7640ade2d1cda52bb1d04f98ef14b1416461d98af0131399d01f3e327f32c255821e277b175d07723bfc4817eaea249419b1 - languageName: node - linkType: hard - -"@mui/x-data-grid@npm:^5.16.0": - version: 5.17.26 - resolution: "@mui/x-data-grid@npm:5.17.26" - dependencies: - "@babel/runtime": ^7.18.9 - "@mui/utils": ^5.10.3 - clsx: ^1.2.1 - prop-types: ^15.8.1 - reselect: ^4.1.6 - peerDependencies: - "@mui/material": ^5.4.1 - "@mui/system": ^5.4.1 - react: ^17.0.2 || ^18.0.0 - react-dom: ^17.0.2 || ^18.0.0 - checksum: 521d9c76c7275836dda0b7ace197553142a33de702cb172cfdfbaf505379faa7566da5340eb9bdf7980909e8034b1fe0eae2b7aca6a499667ecb76f4442dc9e7 - languageName: node - linkType: hard - -"@mui/x-date-pickers@npm:^7.24.0": - version: 7.29.4 - resolution: "@mui/x-date-pickers@npm:7.29.4" - dependencies: - "@babel/runtime": ^7.25.7 - "@mui/utils": ^5.16.6 || ^6.0.0 || ^7.0.0 - "@mui/x-internals": 7.29.0 - "@types/react-transition-group": ^4.4.11 - clsx: ^2.1.1 - prop-types: ^15.8.1 - react-transition-group: ^4.4.5 - peerDependencies: - "@emotion/react": ^11.9.0 - "@emotion/styled": ^11.8.1 - "@mui/material": ^5.15.14 || ^6.0.0 || ^7.0.0 - "@mui/system": ^5.15.14 || ^6.0.0 || ^7.0.0 - date-fns: ^2.25.0 || ^3.2.0 || ^4.0.0 - date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0 - dayjs: ^1.10.7 - luxon: ^3.0.2 - moment: ^2.29.4 - moment-hijri: ^2.1.2 || ^3.0.0 - moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - date-fns: - optional: true - date-fns-jalali: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - moment-hijri: - optional: true - moment-jalaali: - optional: true - checksum: 00424e91e91e5ae74b0dd66c56121353a625961666a8854c91326f0a85865dfd4b812bd3575b83ccfa06760f149aa94e3bef4be2eb8af708fef1275f95859585 - languageName: node - linkType: hard - -"@mui/x-internals@npm:7.29.0": - version: 7.29.0 - resolution: "@mui/x-internals@npm:7.29.0" - dependencies: - "@babel/runtime": ^7.25.7 - "@mui/utils": ^5.16.6 || ^6.0.0 || ^7.0.0 - peerDependencies: - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - checksum: 3e246226bddc03bafe2be7128ea22f9c4a44a5e94bc44f67e630e1c2288f601be3514dec034ab1f2b3bef6937715671cbcc65818338b218f50b89b34d9948290 - languageName: node - linkType: hard - -"@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1": - version: 5.1.1-v1 - resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1" - dependencies: - eslint-scope: 5.1.1 - checksum: f2e3b2d6a6e2d9f163ca22105910c9f850dc4897af0aea3ef0a5886b63d8e1ba6505b71c99cb78a3bba24a09557d601eb21c8dede3f3213753fcfef364eb0e57 - languageName: node - linkType: hard - -"@noble/hashes@npm:^1.1.5": - version: 1.8.0 - resolution: "@noble/hashes@npm:1.8.0" - checksum: c94e98b941963676feaba62475b1ccfa8341e3f572adbb3b684ee38b658df44100187fa0ef4220da580b13f8d27e87d5492623c8a02ecc61f23fb9960c7918f5 - languageName: node - linkType: hard - -"@nodelib/fs.scandir@npm:2.1.5": - version: 2.1.5 - resolution: "@nodelib/fs.scandir@npm:2.1.5" - dependencies: - "@nodelib/fs.stat": 2.0.5 - run-parallel: ^1.1.9 - checksum: a970d595bd23c66c880e0ef1817791432dbb7acbb8d44b7e7d0e7a22f4521260d4a83f7f9fd61d44fda4610105577f8f58a60718105fb38352baed612fd79e59 - languageName: node - linkType: hard - -"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": - version: 2.0.5 - resolution: "@nodelib/fs.stat@npm:2.0.5" - checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 - languageName: node - linkType: hard - -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": - version: 1.2.8 - resolution: "@nodelib/fs.walk@npm:1.2.8" - dependencies: - "@nodelib/fs.scandir": 2.1.5 - fastq: ^1.6.0 - checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53 - languageName: node - linkType: hard - -"@npmcli/agent@npm:^3.0.0": - version: 3.0.0 - resolution: "@npmcli/agent@npm:3.0.0" - 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 - checksum: e8fc25d536250ed3e669813b36e8c6d805628b472353c57afd8c4fde0fcfcf3dda4ffe22f7af8c9070812ec2e7a03fb41d7151547cef3508efe661a5a3add20f - languageName: node - linkType: hard - -"@npmcli/fs@npm:^4.0.0": - version: 4.0.0 - resolution: "@npmcli/fs@npm:4.0.0" - dependencies: - semver: ^7.3.5 - checksum: 68951c589e9a4328698a35fd82fe71909a257d6f2ede0434d236fa55634f0fbcad9bb8755553ce5849bd25ee6f019f4d435921ac715c853582c4a7f5983c8d4a - languageName: node - linkType: hard - -"@open-draft/deferred-promise@npm:^2.2.0": - version: 2.2.0 - resolution: "@open-draft/deferred-promise@npm:2.2.0" - checksum: 7f29d39725bb8ab5b62f89d88a4202ce2439ac740860979f9e3d0015dfe4bc3daddcfa5727fa4eed482fdbee770aa591b1136b98b0a0f0569a65294f35bdf56a - languageName: node - linkType: hard - -"@open-draft/logger@npm:^0.3.0": - version: 0.3.0 - resolution: "@open-draft/logger@npm:0.3.0" - dependencies: - is-node-process: ^1.2.0 - outvariant: ^1.4.0 - checksum: 7adfe3d0ed8ca32333ce2a77f9a93d561ebc89c989eaa9722f1dc8a2d2854f5de1bef6fa6894cdf58e16fa4dd9cfa99444ea1f5cac6eb1518e9247911ed042d5 - languageName: node - linkType: hard - -"@open-draft/until@npm:^2.0.0, @open-draft/until@npm:^2.1.0": - version: 2.1.0 - resolution: "@open-draft/until@npm:2.1.0" - checksum: 140ea3b16f4a3a6a729c1256050e20a93d408d7aa1e125648ce2665b3c526ed452510c6e4a6f4b15d95fb5e41203fb51510eb8fbc8812d5e5a91880293d66471 - languageName: node - linkType: hard - -"@paralleldrive/cuid2@npm:^2.2.2": - version: 2.2.2 - resolution: "@paralleldrive/cuid2@npm:2.2.2" - dependencies: - "@noble/hashes": ^1.1.5 - checksum: f7f6ac70e0268ec2c72e555719240d5c2c9a859ce541ac1c637eed3f3ee971b42881d299dedafbded53e7365b9e98176c5a31c442c1112f7e9e7306f2fd0ecbb - languageName: node - linkType: hard - -"@parcel/watcher-android-arm64@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-android-arm64@npm:2.5.1" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@parcel/watcher-darwin-arm64@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-darwin-arm64@npm:2.5.1" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@parcel/watcher-darwin-x64@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-darwin-x64@npm:2.5.1" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@parcel/watcher-freebsd-x64@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-freebsd-x64@npm:2.5.1" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@parcel/watcher-linux-arm-glibc@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-linux-arm-glibc@npm:2.5.1" - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@parcel/watcher-linux-arm-musl@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-linux-arm-musl@npm:2.5.1" - conditions: os=linux & cpu=arm & libc=musl - languageName: node - linkType: hard - -"@parcel/watcher-linux-arm64-glibc@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-linux-arm64-glibc@npm:2.5.1" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@parcel/watcher-linux-arm64-musl@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-linux-arm64-musl@npm:2.5.1" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@parcel/watcher-linux-x64-glibc@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-linux-x64-glibc@npm:2.5.1" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@parcel/watcher-linux-x64-musl@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-linux-x64-musl@npm:2.5.1" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@parcel/watcher-win32-arm64@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-win32-arm64@npm:2.5.1" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@parcel/watcher-win32-ia32@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-win32-ia32@npm:2.5.1" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@parcel/watcher-win32-x64@npm:2.5.1": - version: 2.5.1 - resolution: "@parcel/watcher-win32-x64@npm:2.5.1" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@parcel/watcher@npm:^2.4.1": - version: 2.5.1 - resolution: "@parcel/watcher@npm:2.5.1" - dependencies: - "@parcel/watcher-android-arm64": 2.5.1 - "@parcel/watcher-darwin-arm64": 2.5.1 - "@parcel/watcher-darwin-x64": 2.5.1 - "@parcel/watcher-freebsd-x64": 2.5.1 - "@parcel/watcher-linux-arm-glibc": 2.5.1 - "@parcel/watcher-linux-arm-musl": 2.5.1 - "@parcel/watcher-linux-arm64-glibc": 2.5.1 - "@parcel/watcher-linux-arm64-musl": 2.5.1 - "@parcel/watcher-linux-x64-glibc": 2.5.1 - "@parcel/watcher-linux-x64-musl": 2.5.1 - "@parcel/watcher-win32-arm64": 2.5.1 - "@parcel/watcher-win32-ia32": 2.5.1 - "@parcel/watcher-win32-x64": 2.5.1 - detect-libc: ^1.0.3 - is-glob: ^4.0.3 - micromatch: ^4.0.5 - node-addon-api: ^7.0.0 - node-gyp: latest - dependenciesMeta: - "@parcel/watcher-android-arm64": - optional: true - "@parcel/watcher-darwin-arm64": - optional: true - "@parcel/watcher-darwin-x64": - optional: true - "@parcel/watcher-freebsd-x64": - optional: true - "@parcel/watcher-linux-arm-glibc": - optional: true - "@parcel/watcher-linux-arm-musl": - optional: true - "@parcel/watcher-linux-arm64-glibc": - optional: true - "@parcel/watcher-linux-arm64-musl": - optional: true - "@parcel/watcher-linux-x64-glibc": - optional: true - "@parcel/watcher-linux-x64-musl": - optional: true - "@parcel/watcher-win32-arm64": - optional: true - "@parcel/watcher-win32-ia32": - optional: true - "@parcel/watcher-win32-x64": - optional: true - checksum: c6444cd20212929ef2296d5620c0d41343a1719232cb0c947ced51155b8afc1e470c09d238b92f6c3a589e0320048badf5b73cb41790229521be224cbf89e0f4 - languageName: node - linkType: hard - -"@pdf-lib/standard-fonts@npm:^1.0.0": - version: 1.0.0 - resolution: "@pdf-lib/standard-fonts@npm:1.0.0" - dependencies: - pako: ^1.0.6 - checksum: 7dc629b83862424a64b10c7ae34d789e0045a1a589f34a66a7f8e197f177cdb410969424e5d90f67b35c848db8b045cfa0a664941bdfb2d9b5413dbf44232981 - languageName: node - linkType: hard - -"@pdf-lib/upng@npm:^1.0.1": - version: 1.0.1 - resolution: "@pdf-lib/upng@npm:1.0.1" - dependencies: - pako: ^1.0.10 - checksum: acd8ac0974a3c2ed12c4e21d6340c4f77f8dde6727a74075b2faf69fb9dc4051b9e576479caf8e870f67d1bb37b953dfe50c4784892b466f01a29b55272d5e1f - languageName: node - linkType: hard - -"@pkgjs/parseargs@npm:^0.11.0": - version: 0.11.0 - resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f - languageName: node - linkType: hard - -"@pkgr/core@npm:^0.2.9": - version: 0.2.9 - resolution: "@pkgr/core@npm:0.2.9" - checksum: bb2fb86977d63f836f8f5b09015d74e6af6488f7a411dcd2bfdca79d76b5a681a9112f41c45bdf88a9069f049718efc6f3900d7f1de66a2ec966068308ae517f - languageName: node - linkType: hard - -"@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.3": - version: 0.5.17 - resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.17" - dependencies: - ansi-html: ^0.0.9 - core-js-pure: ^3.23.3 - error-stack-parser: ^2.0.6 - html-entities: ^2.1.0 - loader-utils: ^2.0.4 - schema-utils: ^4.2.0 - source-map: ^0.7.3 - peerDependencies: - "@types/webpack": 4.x || 5.x - react-refresh: ">=0.10.0 <1.0.0" - sockjs-client: ^1.4.0 - type-fest: ">=0.17.0 <5.0.0" - webpack: ">=4.43.0 <6.0.0" - webpack-dev-server: 3.x || 4.x || 5.x - webpack-hot-middleware: 2.x - webpack-plugin-serve: 0.x || 1.x - peerDependenciesMeta: - "@types/webpack": - optional: true - sockjs-client: - optional: true - type-fest: - optional: true - webpack-dev-server: - optional: true - webpack-hot-middleware: - optional: true - webpack-plugin-serve: - optional: true - checksum: ff80b5064f6acba52f18e240dc0a402c5f0980402fd4e5a212a69b9ad6ad76294b4e0f4a78f356cab17b53b88995c6e4dd0b54e6f07c28c2a307cb8bf61fa88f - languageName: node - linkType: hard - -"@popperjs/core@npm:^2.11.8": - version: 2.11.8 - resolution: "@popperjs/core@npm:2.11.8" - checksum: e5c69fdebf52a4012f6a1f14817ca8e9599cb1be73dd1387e1785e2ed5e5f0862ff817f420a87c7fc532add1f88a12e25aeb010ffcbdc98eace3d55ce2139cf0 - languageName: node - linkType: hard - -"@prisma/client@npm:6.2.1": - version: 6.2.1 - resolution: "@prisma/client@npm:6.2.1" - peerDependencies: - prisma: "*" - peerDependenciesMeta: - prisma: - optional: true - checksum: ef2e0989a2a1a66881da3e4284e4e0e9af2aa46961db1a8214456c3b7307afb545ac89e100948f82cb1f7957b61bb692752a777d5f7eae5b1f46528ff33a73da - languageName: node - linkType: hard - -"@prisma/debug@npm:6.2.1": - version: 6.2.1 - resolution: "@prisma/debug@npm:6.2.1" - checksum: d77a4a8db6b319d7b1a97995cb1346232315e78f05d8c92d371df8cfa24ce7ace9298224b5bd70b57b1b552133dccdec01f60f5cf4aad05a2b26b88af3e04323 - languageName: node - linkType: hard - -"@prisma/engines-version@npm:6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69": - version: 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69 - resolution: "@prisma/engines-version@npm:6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69" - checksum: 813905c757a11c2e4112e63f1b5cd3750e4cf74302bf1d6a3f981ed866eead9e1d0086a61a7fde25e684ef516ad17c052089ee62b538a5bd6142cb7955ec7005 - languageName: node - linkType: hard - -"@prisma/engines@npm:6.2.1": - version: 6.2.1 - resolution: "@prisma/engines@npm:6.2.1" - dependencies: - "@prisma/debug": 6.2.1 - "@prisma/engines-version": 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69 - "@prisma/fetch-engine": 6.2.1 - "@prisma/get-platform": 6.2.1 - checksum: 33d6d7d9565055f89de1629f03bf8e2b1c3b69cc1a162d852b0809568971fa9264a2b6356026e1d7c64a7a16043056766a76eec75cb79dd3745e63320f8a9125 - languageName: node - linkType: hard - -"@prisma/fetch-engine@npm:6.2.1": - version: 6.2.1 - resolution: "@prisma/fetch-engine@npm:6.2.1" - dependencies: - "@prisma/debug": 6.2.1 - "@prisma/engines-version": 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69 - "@prisma/get-platform": 6.2.1 - checksum: 5960e95518eb003171f9870d3bcb87a8402979983c478558b3343a6ad5519f506417418fe91aa017e7a253769fc284df9c9d7c91815500eb92cd9ac8bfbd0d70 - languageName: node - linkType: hard - -"@prisma/get-platform@npm:6.2.1": - version: 6.2.1 - resolution: "@prisma/get-platform@npm:6.2.1" - dependencies: - "@prisma/debug": 6.2.1 - checksum: cb9b5f144d4266bde5990c2c4540a527761033083d64ae9d05980ab88ee8a777f54cc1ea54b707734fc9bf3892dfd194aae896238444a519a3bc0a2a97e32469 - languageName: node - linkType: hard - -"@react-oauth/google@npm:^0.12.1": - version: 0.12.2 - resolution: "@react-oauth/google@npm:0.12.2" - peerDependencies: - react: ">=16.8.0" - react-dom: ">=16.8.0" - checksum: 0ee3394fcf2acc68c75c64a3abfb71f15fe52a1d7a446b1bed6197101ee5d63025c2e4334d8525abebe3da1f69ba808b660bf27e13ba08a646fb193f968d53d6 - languageName: node - linkType: hard - -"@rolldown/pluginutils@npm:1.0.0-beta.27": - version: 1.0.0-beta.27 - resolution: "@rolldown/pluginutils@npm:1.0.0-beta.27" - checksum: b57d8de44534bdbb92e9dda70a29c5b3cb7a13cc3a2efaaf9d27923ca23e2526e9470939fe1d7c6a96623da20aaf96a1517502e1d9a6d4f98fbb544cf502600a - languageName: node - linkType: hard - -"@rollup/plugin-babel@npm:^5.2.0": - version: 5.3.1 - resolution: "@rollup/plugin-babel@npm:5.3.1" - dependencies: - "@babel/helper-module-imports": ^7.10.4 - "@rollup/pluginutils": ^3.1.0 - peerDependencies: - "@babel/core": ^7.0.0 - "@types/babel__core": ^7.1.9 - rollup: ^1.20.0||^2.0.0 - peerDependenciesMeta: - "@types/babel__core": - optional: true - checksum: 220d71e4647330f252ef33d5f29700aef2e8284a0b61acfcceb47617a7f96208aa1ed16eae75619424bf08811ede5241e271a6d031f07026dee6b3a2bdcdc638 - languageName: node - linkType: hard - -"@rollup/plugin-node-resolve@npm:^11.2.1": - version: 11.2.1 - resolution: "@rollup/plugin-node-resolve@npm:11.2.1" - dependencies: - "@rollup/pluginutils": ^3.1.0 - "@types/resolve": 1.17.1 - builtin-modules: ^3.1.0 - deepmerge: ^4.2.2 - is-module: ^1.0.0 - resolve: ^1.19.0 - peerDependencies: - rollup: ^1.20.0||^2.0.0 - checksum: 6f3b3ecf9a0596a5db4212984bdeb13bb7612693602407e9457ada075dea5a5f2e4e124c592352cf27066a88b194de9b9a95390149b52cf335d5b5e17b4e265b - languageName: node - linkType: hard - -"@rollup/plugin-replace@npm:^2.4.1": - version: 2.4.2 - resolution: "@rollup/plugin-replace@npm:2.4.2" - dependencies: - "@rollup/pluginutils": ^3.1.0 - magic-string: ^0.25.7 - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 - checksum: b2f1618ee5526d288e2f8ae328dcb326e20e8dc8bd1f60d3e14d6708a5832e4aa44811f7d493f4aed2deeadca86e3b6b0503cd39bf50cfb4b595bb9da027fad0 - languageName: node - linkType: hard - -"@rollup/pluginutils@npm:^3.1.0": - version: 3.1.0 - resolution: "@rollup/pluginutils@npm:3.1.0" +"@jest/types@npm:^28.1.3": + version: 28.1.3 + resolution: "@jest/types@npm:28.1.3" dependencies: - "@types/estree": 0.0.39 - estree-walker: ^1.0.1 - picomatch: ^2.2.2 - peerDependencies: - rollup: ^1.20.0||^2.0.0 - checksum: 8be16e27863c219edbb25a4e6ec2fe0e1e451d9e917b6a43cf2ae5bc025a6b8faaa40f82a6e53b66d0de37b58ff472c6c3d57a83037ae635041f8df959d6d9aa - languageName: node - linkType: hard - -"@rollup/rollup-android-arm-eabi@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.50.1" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@rollup/rollup-android-arm64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-android-arm64@npm:4.50.1" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@rollup/rollup-darwin-arm64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-darwin-arm64@npm:4.50.1" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@rollup/rollup-darwin-x64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-darwin-x64@npm:4.50.1" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@rollup/rollup-freebsd-arm64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.50.1" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"@rollup/rollup-freebsd-x64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-freebsd-x64@npm:4.50.1" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@rollup/rollup-linux-arm-gnueabihf@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.1" - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-arm-musleabihf@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.50.1" - conditions: os=linux & cpu=arm & libc=musl - languageName: node - linkType: hard - -"@rollup/rollup-linux-arm64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.50.1" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-arm64-musl@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.50.1" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@rollup/rollup-linux-loongarch64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.50.1" - conditions: os=linux & cpu=loong64 & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-ppc64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.50.1" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-riscv64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.50.1" - conditions: os=linux & cpu=riscv64 & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-riscv64-musl@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.50.1" - conditions: os=linux & cpu=riscv64 & libc=musl - languageName: node - linkType: hard - -"@rollup/rollup-linux-s390x-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.50.1" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-x64-gnu@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.50.1" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-x64-musl@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.50.1" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@rollup/rollup-openharmony-arm64@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-openharmony-arm64@npm:4.50.1" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@rollup/rollup-win32-arm64-msvc@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.50.1" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@rollup/rollup-win32-ia32-msvc@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.50.1" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@rollup/rollup-win32-x64-msvc@npm:4.50.1": - version: 4.50.1 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.50.1" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@rtsao/scc@npm:^1.1.0": - version: 1.1.0 - resolution: "@rtsao/scc@npm:1.1.0" - checksum: 17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 - languageName: node - linkType: hard - -"@rushstack/eslint-patch@npm:^1.1.0": - version: 1.12.0 - resolution: "@rushstack/eslint-patch@npm:1.12.0" - checksum: 186788a93e2f141f622696091a593727fe7964d4925236a308e29754e29dcb182377f8d292ae954d227fb0574433863af055c0156593a40fd525e88b76e891ec - languageName: node - linkType: hard - -"@sinclair/typebox@npm:^0.24.1": - version: 0.24.51 - resolution: "@sinclair/typebox@npm:0.24.51" - checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0 - languageName: node - linkType: hard - -"@sinclair/typebox@npm:^0.27.8": - version: 0.27.8 - resolution: "@sinclair/typebox@npm:0.27.8" - checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 + "@jest/schemas": ^28.1.3 + "@types/istanbul-lib-coverage": ^2.0.0 + "@types/istanbul-reports": ^3.0.0 + "@types/node": "*" + "@types/yargs": ^17.0.8 + chalk: ^4.0.0 + checksum: 1e258d9c063fcf59ebc91e46d5ea5984674ac7ae6cae3e50aa780d22b4405bf2c925f40350bf30013839eb5d4b5e521d956ddf8f3b7c78debef0e75a07f57350 languageName: node linkType: hard -"@sinonjs/commons@npm:^1.7.0": - version: 1.8.6 - resolution: "@sinonjs/commons@npm:1.8.6" +"@jest/types@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/types@npm:29.6.3" dependencies: - type-detect: 4.0.8 - checksum: 7d3f8c1e85f30cd4e83594fc19b7a657f14d49eb8d95a30095631ce15e906c869e0eff96c5b93dffea7490c00418b07f54582ba49c6560feb2a8c34c0b16832d + "@jest/schemas": ^29.6.3 + "@types/istanbul-lib-coverage": ^2.0.0 + "@types/istanbul-reports": ^3.0.0 + "@types/node": "*" + "@types/yargs": ^17.0.8 + chalk: ^4.0.0 + checksum: a0bcf15dbb0eca6bdd8ce61a3fb055349d40268622a7670a3b2eb3c3dbafe9eb26af59938366d520b86907b9505b0f9b29b85cec11579a9e580694b87cd90fcc languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^8.0.1": - version: 8.1.0 - resolution: "@sinonjs/fake-timers@npm:8.1.0" +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" dependencies: - "@sinonjs/commons": ^1.7.0 - checksum: 09b5a158ce013a6c37613258bad79ca4efeb99b1f59c41c73cca36cac00b258aefcf46eeea970fccf06b989414d86fe9f54c1102272c0c3bdd51a313cea80949 + "@jridgewell/set-array": ^1.2.1 + "@jridgewell/sourcemap-codec": ^1.4.10 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 languageName: node linkType: hard -"@slack/events-api@npm:^3.0.1": - version: 3.0.1 - resolution: "@slack/events-api@npm:3.0.1" - dependencies: - "@types/debug": ^4.1.4 - "@types/express": ^4.17.0 - "@types/lodash.isstring": ^4.0.6 - "@types/node": ">=12.13.0 < 13" - "@types/yargs": ^15.0.4 - debug: ^2.6.1 - express: ^4.0.0 - lodash.isstring: ^4.0.1 - raw-body: ^2.3.3 - tsscmp: ^1.0.6 - yargs: ^15.3.1 - dependenciesMeta: - express: - optional: true - bin: - slack-verify: dist/verify.js - checksum: ce62dc2ee9dd93b88820e18f88f543228740243dc390caf49b3a7e1ad351b298e3961898bd78f5eb43e9f6acac067458257cd34c9661089f684bb5cf4af468c3 +"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 languageName: node linkType: hard -"@slack/logger@npm:^4.0.0": - version: 4.0.0 - resolution: "@slack/logger@npm:4.0.0" - dependencies: - "@types/node": ">=18.0.0" - checksum: dc79e9d2032c4bf9ce01d96cc72882f003dd376d036f172d4169662cfc2c9b384a80d5546b06021578dd473e7059f064303f0ba851eeb153387f2081a1e3062e +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 languageName: node linkType: hard -"@slack/types@npm:^2.9.0": - version: 2.16.0 - resolution: "@slack/types@npm:2.16.0" - checksum: f1db2b8c18af245f78d5c178d98ed57fa5c8c18a1ea2e922bc0d330178a483ee7a29834b42a6710ece005789d91266d62195c93e8e2411ca707f8e438442c7f1 +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.6 + resolution: "@jridgewell/source-map@npm:0.3.6" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + checksum: c9dc7d899397df95e3c9ec287b93c0b56f8e4453cd20743e2b9c8e779b1949bc3cccf6c01bb302779e46560eb45f62ea38d19fedd25370d814734268450a9f30 languageName: node linkType: hard -"@slack/web-api@npm:^7.8.0": - version: 7.10.0 - resolution: "@slack/web-api@npm:7.10.0" - dependencies: - "@slack/logger": ^4.0.0 - "@slack/types": ^2.9.0 - "@types/node": ">=18.0.0" - "@types/retry": 0.12.0 - axios: ^1.11.0 - eventemitter3: ^5.0.1 - form-data: ^4.0.4 - is-electron: 2.2.2 - is-stream: ^2 - p-queue: ^6 - p-retry: ^4 - retry: ^0.13.1 - checksum: 6aa3f19892713c1efd5ec4dbca493f28725d185de478226b179cc9e8456c5fb7e38dc6092a5a93a6e4ce49e45a6cf2c287d18969b9563b52941db1e1679ecb96 +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.15": + version: 1.4.15 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" + checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8 languageName: node linkType: hard -"@smithy/abort-controller@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/abort-controller@npm:4.1.1" +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: c05ba27366becd5ad6eddaf648e440efd51ac21c3721f3da8d03d977826a139cbe48f2c5f52be2ef3178c8692e899c568e7c1dba3724a92fbf248a65e3eeb15b + "@jridgewell/resolve-uri": ^3.0.3 + "@jridgewell/sourcemap-codec": ^1.4.10 + checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef languageName: node linkType: hard -"@smithy/config-resolver@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/config-resolver@npm:4.2.1" +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" dependencies: - "@smithy/node-config-provider": ^4.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-config-provider": ^4.1.0 - "@smithy/util-middleware": ^4.1.1 - tslib: ^2.6.2 - checksum: b993a32f4d89e4db6cf1e4ce58f26966a2ffb57fa47508997ce5c3b14dc75141fe980f418e41984f9c0df65d69bdf90bafcca06b33ad5ea62d79fea016153ce1 + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 languageName: node linkType: hard -"@smithy/core@npm:^3.11.0": - version: 3.11.0 - resolution: "@smithy/core@npm:3.11.0" +"@mswjs/cookies@npm:^0.2.2": + version: 0.2.2 + resolution: "@mswjs/cookies@npm:0.2.2" dependencies: - "@smithy/middleware-serde": ^4.1.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-stream": ^4.3.1 - "@smithy/util-utf8": ^4.1.0 - "@types/uuid": ^9.0.1 - tslib: ^2.6.2 - uuid: ^9.0.1 - checksum: 1e6274090961398776fbc5e00b93bc84d5fe2aff6bf0909c84d0a03a3e384db03d52bd9a7c147cc5834b9c9511db80121d09a3c81497405718d8cff20892ab02 + "@types/set-cookie-parser": ^2.4.0 + set-cookie-parser: ^2.4.6 + checksum: 23b1ef56d57efcc1b44600076f531a1fb703855af342a31e01bad4adaf0dab51f6d3b5595a95a7988c3f612ba075835f9a06c52833205284d101eb9a51dd72b0 languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^4.0.7, @smithy/credential-provider-imds@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/credential-provider-imds@npm:4.1.1" +"@mswjs/interceptors@npm:^0.17.2": + version: 0.17.10 + resolution: "@mswjs/interceptors@npm:0.17.10" dependencies: - "@smithy/node-config-provider": ^4.2.1 - "@smithy/property-provider": ^4.1.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - tslib: ^2.6.2 - checksum: ae6faec4626d6cbe4e1a403761163309d4f225a18851b10e4b743556c7842ced69812fd7fd9873322596fae4465424342ab6d00a24231d5800b76483c3b0c896 + "@open-draft/until": ^1.0.3 + "@types/debug": ^4.1.7 + "@xmldom/xmldom": ^0.8.3 + debug: ^4.3.3 + headers-polyfill: 3.2.5 + outvariant: ^1.2.1 + strict-event-emitter: ^0.2.4 + web-encoding: ^1.1.5 + checksum: 0e6d32f399144b5cefe6fd7620f2776c83adc9bbbbccf2eb4ea347332be059f585136c44168c09b544c41cd3d686f88e43432e10192227a24fbb0c98a2f52dc8 languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/fetch-http-handler@npm:5.2.1" +"@mui/base@npm:5.0.0-beta.40": + version: 5.0.0-beta.40 + resolution: "@mui/base@npm:5.0.0-beta.40" dependencies: - "@smithy/protocol-http": ^5.2.1 - "@smithy/querystring-builder": ^4.1.1 - "@smithy/types": ^4.5.0 - "@smithy/util-base64": ^4.1.0 - tslib: ^2.6.2 - checksum: 68733a2d4a47002c9059af23078712ebc451dacca9542a3f6a70ba2288a017bb474a15ff6c10816c04296011c833d9ad8f957d22eedb33ea3a0edc12ad62160e + "@babel/runtime": ^7.23.9 + "@floating-ui/react-dom": ^2.0.8 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 + "@popperjs/core": ^2.11.8 + clsx: ^2.1.0 + prop-types: ^15.8.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 9c084ee67de372411a71af5eca9a5367db9f5bce57bb43973629c522760fe64fa2a43d2934dccd24d6dcbcd0ed399c5fc5c461226c86104f5767de1c9b8deba2 languageName: node linkType: hard -"@smithy/hash-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/hash-node@npm:4.1.1" +"@mui/base@npm:^5.0.0-beta.22": + version: 5.0.0-beta.42 + resolution: "@mui/base@npm:5.0.0-beta.42" dependencies: - "@smithy/types": ^4.5.0 - "@smithy/util-buffer-from": ^4.1.0 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: ee0d5ed0355d5551cc8805e55dcca582d75b062c15b5f1cde15a0376b3e0254ef4803a80f16f1c4125a985545e4fa99b4a7021199cc5ffa5457f829056962146 + "@babel/runtime": ^7.24.4 + "@floating-ui/react-dom": ^2.0.8 + "@mui/types": ^7.2.14 + "@mui/utils": ^6.0.0-alpha.1 + "@popperjs/core": ^2.11.8 + clsx: ^2.1.0 + prop-types: ^15.8.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: f7af6e6003a4a8502062607b7861490eb6dc3a1f617532c92521981329ae077535444d65e378718bbf59ce8b7a52fc32275dc794969c73bdb389e5d69155fc69 languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/invalid-dependency@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 039893fddde6786eb0c50c1a7c33768e9b052c5bc36c5ff1bec517290dab06f9e8ddf07323a3ef594f80b30fc4eaeb35bed1e0ef9b7aa9588aa99f169dd02ada +"@mui/core-downloads-tracker@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/core-downloads-tracker@npm:5.15.15" + checksum: 3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/is-array-buffer@npm:2.2.0" +"@mui/icons-material@npm:^5.10.3": + version: 5.15.15 + resolution: "@mui/icons-material@npm:5.15.15" dependencies: - tslib: ^2.6.2 - checksum: cd12c2e27884fec89ca8966d33c9dc34d3234efe89b33a9b309c61ebcde463e6f15f6a02d31d4fddbfd6e5904743524ca5b95021b517b98fe10957c2da0cd5fc + "@babel/runtime": ^7.23.9 + peerDependencies: + "@mui/material": ^5.0.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 42d62fc94be25a361034a8974b1860608e866c155ff2eea7dc18f10a4acc71dbe2f48af3f0309a345ff6fb16be30c6fbc1d8a0a447c828aa1380a49e176a8803 languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/is-array-buffer@npm:4.1.0" +"@mui/material@npm:^5.10.3": + version: 5.15.15 + resolution: "@mui/material@npm:5.15.15" dependencies: - tslib: ^2.6.2 - checksum: 8ab4c920f9f9dc10dadcbc32fef439e9809da8065898ef05007c46c9d4a6494b512240cd25652b8be533f17aee0ce441c412fa0de535128ea7f8e610fda3acbd + "@babel/runtime": ^7.23.9 + "@mui/base": 5.0.0-beta.40 + "@mui/core-downloads-tracker": ^5.15.15 + "@mui/system": ^5.15.15 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 + "@types/react-transition-group": ^4.4.10 + clsx: ^2.1.0 + csstype: ^3.1.3 + prop-types: ^15.8.1 + react-is: ^18.2.0 + react-transition-group: ^4.4.5 + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: ee0dc22fc4d617f7cf69f2451b6d5139978e6c5319e3056e7719159aff786ee3b80abd07691e230371811d9b5b574aef4559d7855bfe2f8493d596d960a91ab7 languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-content-length@npm:4.1.1" +"@mui/private-theming@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/private-theming@npm:5.15.14" dependencies: - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: e136bd0f2a95b6baba0d226289bfa430f2cad9180f952d4b8abda49362adbbe02cfed85726dd54d4be3f7e07196e6dffd1af56616ab922b1485571891dae3633 + "@babel/runtime": ^7.23.9 + "@mui/utils": ^5.15.14 + prop-types: ^15.8.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 1b1ef54e8281c9b13fcc58f4c39682efc610946a68402283c19fcfbce8a7d7a231d61b536d6df9bf7a59a1426591bd403a453a59eb8efb9689437fb58554dc8c languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/middleware-endpoint@npm:4.2.1" +"@mui/styled-engine@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/styled-engine@npm:5.15.14" dependencies: - "@smithy/core": ^3.11.0 - "@smithy/middleware-serde": ^4.1.1 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/shared-ini-file-loader": ^4.1.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-middleware": ^4.1.1 - tslib: ^2.6.2 - checksum: c1da39fe173c8d88214bec6c57d7210d2aac682672b9e54228a8f15232bd884f7362e00177241c3e0015e68e16dafd04011284ad2bdb4c54c55661737df9b536 + "@babel/runtime": ^7.23.9 + "@emotion/cache": ^11.11.0 + csstype: ^3.1.3 + prop-types: ^15.8.1 + peerDependencies: + "@emotion/react": ^11.4.1 + "@emotion/styled": ^11.3.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + checksum: 23b45c859a4f0d2b10933d06a6082c0ff093f7b6d8d32a2bfe3a6e515fe46d7a38ca9e7150d45c025a2e98d963bae9a5991d131cf4748b62670075ef0fa321ed languageName: node linkType: hard -"@smithy/middleware-retry@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/middleware-retry@npm:4.2.1" +"@mui/system@npm:^5.10.16, @mui/system@npm:^5.15.15": + version: 5.15.15 + resolution: "@mui/system@npm:5.15.15" dependencies: - "@smithy/node-config-provider": ^4.2.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/service-error-classification": ^4.1.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-retry": ^4.1.1 - "@types/uuid": ^9.0.1 - tslib: ^2.6.2 - uuid: ^9.0.1 - checksum: 3d1e723f90cb11b9c118cce7a55e30dca84db6e752b6d4abffb99acce3383a23063027774fec46ff7c2bc5b926cbe34d4cbfe4506d8aaa7606d8325a046dcd7c + "@babel/runtime": ^7.23.9 + "@mui/private-theming": ^5.15.14 + "@mui/styled-engine": ^5.15.14 + "@mui/types": ^7.2.14 + "@mui/utils": ^5.15.14 + clsx: ^2.1.0 + csstype: ^3.1.3 + prop-types: ^15.8.1 + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 9ca96d5f66b2a9d6471909cc98c671eea5ec0a6d58a7ec071073b9e5200b95c3f017f0ca5cc946abc7f83074bd11830ca18f5e30bc98e25cd6ca217bd1b3a26f languageName: node linkType: hard -"@smithy/middleware-serde@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-serde@npm:4.1.1" - dependencies: - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: e0f6d3895ec83b2e70a8282d058c1862d73ed4d6a2ca878cda6c97b439e52bf3df3f3b4c44e7749262cdf87e5e7c30d10f1fb081ade79689cf0ac17061cf447b +"@mui/types@npm:^7.2.14": + version: 7.2.14 + resolution: "@mui/types@npm:7.2.14" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 615c9f9110933157f5d3c4fee69d6e70b98fc0d9ebc3b63079b6a1e23e6b389748687a25ab4ac15b56166fc228885da87c3929503b41fa322cfdee0f6d411206 languageName: node linkType: hard -"@smithy/middleware-stack@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-stack@npm:4.1.1" +"@mui/utils@npm:^5.10.3, @mui/utils@npm:^5.14.16, @mui/utils@npm:^5.15.14": + version: 5.15.14 + resolution: "@mui/utils@npm:5.15.14" dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 9046afc321356a8d26d1db41a700a5ac0d9d370d561725c0bb9239db7aaa2ad02b3747998da6497238a3c4bd7169cbbf8bd4936c123f0fc219c4b17611a663ea + "@babel/runtime": ^7.23.9 + "@types/prop-types": ^15.7.11 + prop-types: ^15.8.1 + react-is: ^18.2.0 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 36543ba7e3b65fb3219ed27e8f1455aff15b47a74c9b642c63e60774e22baa6492a196079e72bcfa5a570421dab32160398f892110bd444428bcf8b266b11893 languageName: node linkType: hard -"@smithy/node-config-provider@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/node-config-provider@npm:4.2.1" +"@mui/utils@npm:^6.0.0-alpha.1": + version: 6.0.0-alpha.3 + resolution: "@mui/utils@npm:6.0.0-alpha.3" dependencies: - "@smithy/property-provider": ^4.1.1 - "@smithy/shared-ini-file-loader": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 0750bc5d6a1e29eec83c842642fb1a2b2918f4700cfe741139e9f2bd84da8a76f194d3308000731397b73bcc79fa67614029faea8beed928fd1223002b9444de + "@babel/runtime": ^7.24.4 + "@types/prop-types": ^15.7.12 + prop-types: ^15.8.1 + react-is: ^18.2.0 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 4122813e8f10b0c907ab28e062287e234760a532203b47459469411460302e33856b2bd43c4febcc0b8f5b0ad4f8f028f3e6af8e34631e35e5fe9f82b9f0a330 languageName: node linkType: hard -"@smithy/node-http-handler@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/node-http-handler@npm:4.2.1" +"@mui/x-data-grid@npm:^5.16.0": + version: 5.17.26 + resolution: "@mui/x-data-grid@npm:5.17.26" dependencies: - "@smithy/abort-controller": ^4.1.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/querystring-builder": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 93d006a5908b41cf8bb9b4564c4f2274825db44755dd6949490405e859419cba73afd6c34de93a4e2ee4ef7cc2524a91853fbcca16261ab302b1bd08e73694c9 + "@babel/runtime": ^7.18.9 + "@mui/utils": ^5.10.3 + clsx: ^1.2.1 + prop-types: ^15.8.1 + reselect: ^4.1.6 + peerDependencies: + "@mui/material": ^5.4.1 + "@mui/system": ^5.4.1 + react: ^17.0.2 || ^18.0.0 + react-dom: ^17.0.2 || ^18.0.0 + checksum: 521d9c76c7275836dda0b7ace197553142a33de702cb172cfdfbaf505379faa7566da5340eb9bdf7980909e8034b1fe0eae2b7aca6a499667ecb76f4442dc9e7 languageName: node linkType: hard -"@smithy/property-provider@npm:^4.0.5, @smithy/property-provider@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/property-provider@npm:4.1.1" +"@mui/x-date-pickers@npm:^6.19.4": + version: 6.19.9 + resolution: "@mui/x-date-pickers@npm:6.19.9" dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 0173716227d82d50845121202dc157dd23e75786d3ab994ea91666e2441a66c972c27e71d67992688a10b7ca4e988a7b809668d20c0c35a66a39c824842fd6ee + "@babel/runtime": ^7.23.2 + "@mui/base": ^5.0.0-beta.22 + "@mui/utils": ^5.14.16 + "@types/react-transition-group": ^4.4.8 + clsx: ^2.0.0 + prop-types: ^15.8.1 + react-transition-group: ^4.4.5 + peerDependencies: + "@emotion/react": ^11.9.0 + "@emotion/styled": ^11.8.1 + "@mui/material": ^5.8.6 + "@mui/system": ^5.8.0 + date-fns: ^2.25.0 || ^3.2.0 + date-fns-jalali: ^2.13.0-0 + dayjs: ^1.10.7 + luxon: ^3.0.2 + moment: ^2.29.4 + moment-hijri: ^2.1.2 + moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + date-fns: + optional: true + date-fns-jalali: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + moment-hijri: + optional: true + moment-jalaali: + optional: true + checksum: 830d9cb64187613fdb99cdf465ba6b144169dae944e2c850eedb360d4c8e11943f3b602ffa7c141a4ecf6b02e278f56cd58186b1c25b6beb42d047a9dcbddf56 languageName: node linkType: hard -"@smithy/protocol-http@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/protocol-http@npm:5.2.1" +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 6a8509a7fd38a039e6db10d372f0698ea841fe73c49cb7f03a7718ff2b5e60776f4f3a9d7658020f9ad981917ce46e40d7d38fbd8675330031d6483ef3aafc42 + "@nodelib/fs.stat": 2.0.5 + run-parallel: ^1.1.9 + checksum: a970d595bd23c66c880e0ef1817791432dbb7acbb8d44b7e7d0e7a22f4521260d4a83f7f9fd61d44fda4610105577f8f58a60718105fb38352baed612fd79e59 languageName: node linkType: hard -"@smithy/querystring-builder@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/querystring-builder@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - "@smithy/util-uri-escape": ^4.1.0 - tslib: ^2.6.2 - checksum: 01d7ff1a21547a8a7e687ebcb7f2b9c94c8cd62403e1c5e88fab340c7e5bc11162e66b08d1b75876c7221e352272e33dd2066a19e270171f8eb63bbf6a1d92a6 +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 languageName: node linkType: hard -"@smithy/querystring-parser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/querystring-parser@npm:4.1.1" +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: b70f09e2a778a6037d9ff3e9c67707d4744dba4d0f760b9e79a0d4469ff6f68d493d1c3d4104441de040cf8ab6e15acc06ae5dbba7a30a418306af3771117cba + "@nodelib/fs.scandir": 2.1.5 + fastq: ^1.6.0 + checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53 languageName: node linkType: hard -"@smithy/service-error-classification@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/service-error-classification@npm:4.1.1" +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" dependencies: - "@smithy/types": ^4.5.0 - checksum: 7d8bc8fa9faf4047b8386e45e74f033feedd8824483ab8ab9a37046405a6a5c15cf66d1f7e32a179336b415974d1b55b750727c823d55b288618793dfefb0633 + 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 + checksum: 67de7b88cc627a79743c88bab35e023e23daf13831a8aa4e15f998b92f5507b644d8ffc3788afc8e64423c612e0785a6a92b74782ce368f49a6746084b50d874 languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^4.0.5, @smithy/shared-ini-file-loader@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/shared-ini-file-loader@npm:4.1.1" +"@npmcli/fs@npm:^1.0.0": + version: 1.1.1 + resolution: "@npmcli/fs@npm:1.1.1" dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: ee5262e6134d391145f4ad91e43997ee8aaf73ce46b1b38b715edbfb4576a01b0f2828e3710402fcbb19ef86332cb1d432f502c95b14978e617bba7ad3d2b93f + "@gar/promisify": ^1.0.1 + semver: ^7.3.5 + checksum: f5ad92f157ed222e4e31c352333d0901df02c7c04311e42a81d8eb555d4ec4276ea9c635011757de20cc476755af33e91622838de573b17e52e2e7703f0a9965 languageName: node linkType: hard -"@smithy/signature-v4@npm:^5.1.3": - version: 5.2.1 - resolution: "@smithy/signature-v4@npm:5.2.1" +"@npmcli/fs@npm:^3.1.0": + version: 3.1.0 + resolution: "@npmcli/fs@npm:3.1.0" dependencies: - "@smithy/is-array-buffer": ^4.1.0 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-hex-encoding": ^4.1.0 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-uri-escape": ^4.1.0 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: d609451fead77465d04b3d2fb614cfd51c5c66020429ecf97c871952e70d0cacb9d4ff8b15271cc7b38fcfa852b3d141e1811804ecab0eb522cadb9d43f3c10c + semver: ^7.3.5 + checksum: a50a6818de5fc557d0b0e6f50ec780a7a02ab8ad07e5ac8b16bf519e0ad60a144ac64f97d05c443c3367235d337182e1d012bbac0eb8dbae8dc7b40b193efd0e languageName: node linkType: hard -"@smithy/smithy-client@npm:^4.6.1": - version: 4.6.1 - resolution: "@smithy/smithy-client@npm:4.6.1" +"@npmcli/move-file@npm:^1.0.1": + version: 1.1.2 + resolution: "@npmcli/move-file@npm:1.1.2" dependencies: - "@smithy/core": ^3.11.0 - "@smithy/middleware-endpoint": ^4.2.1 - "@smithy/middleware-stack": ^4.1.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-stream": ^4.3.1 - tslib: ^2.6.2 - checksum: 22aa3b67f91e5cf509f157605144fd1e937b3d19c1bb40c8e65e4e2d2c53a80f22082d94c24279d70ae60547b21d93fffb44fb9c09244793c746c5001e6db9ec + mkdirp: ^1.0.4 + rimraf: ^3.0.2 + checksum: c96381d4a37448ea280951e46233f7e541058cf57a57d4094dd4bdcaae43fa5872b5f2eb6bfb004591a68e29c5877abe3cdc210cb3588cbf20ab2877f31a7de7 languageName: node linkType: hard -"@smithy/types@npm:^4.5.0": - version: 4.5.0 - resolution: "@smithy/types@npm:4.5.0" - dependencies: - tslib: ^2.6.2 - checksum: 5fb38dcf554e8ecf3654cbcc295fffcf35517f7e792ed158f4119223982f57d4e3ec79ad56e8e9a590c8843990bef217da8a88e02e197ee7f6d4737abcc9c075 +"@open-draft/until@npm:^1.0.3": + version: 1.0.3 + resolution: "@open-draft/until@npm:1.0.3" + checksum: 323e92ebef0150ed0f8caedc7d219b68cdc50784fa4eba0377eef93533d3f46514eb2400ced83dda8c51bddc3d2c7b8e9cf95e5ec85ab7f62dfc015d174f62f2 languageName: node linkType: hard -"@smithy/url-parser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/url-parser@npm:4.1.1" +"@pdf-lib/standard-fonts@npm:^1.0.0": + version: 1.0.0 + resolution: "@pdf-lib/standard-fonts@npm:1.0.0" dependencies: - "@smithy/querystring-parser": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 189d60c99b3610bb4be2f32474551e4431273891093232f38553a27541ba1379df70a625b83390f259aafbddb3307e531b8210148c854eb39763e2d0e5ec3769 + pako: ^1.0.6 + checksum: 7dc629b83862424a64b10c7ae34d789e0045a1a589f34a66a7f8e197f177cdb410969424e5d90f67b35c848db8b045cfa0a664941bdfb2d9b5413dbf44232981 languageName: node linkType: hard -"@smithy/util-base64@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-base64@npm:4.1.0" +"@pdf-lib/upng@npm:^1.0.1": + version: 1.0.1 + resolution: "@pdf-lib/upng@npm:1.0.1" dependencies: - "@smithy/util-buffer-from": ^4.1.0 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: 8855de07897631f835fc47b9c17938a5e927291ce6ef08cfd1424431333fc4c4797c18e2094790c5331388f39bd5ed0a76a913e9b7f3c7f61c0e228bf18a3cf9 + pako: ^1.0.10 + checksum: acd8ac0974a3c2ed12c4e21d6340c4f77f8dde6727a74075b2faf69fb9dc4051b9e576479caf8e870f67d1bb37b953dfe50c4784892b466f01a29b55272d5e1f languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-body-length-browser@npm:4.1.0" - dependencies: - tslib: ^2.6.2 - checksum: 7aa162eb084ffeb7b0b6d504494e248e7da72447f08cda02120d5594ddb146544dcee19b92d6e57dc3115372e2ce018147692e44c7cb1498f634a3fa17d22aa9 +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-body-length-node@npm:4.1.0" +"@pmmmwh/react-refresh-webpack-plugin@npm:0.4.3": + version: 0.4.3 + resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.4.3" dependencies: - tslib: ^2.6.2 - checksum: dfaf22fd6fc086544f582dd5c64a4416c01bad8b92f5891add84b9086a9b0a8815659269c91b8adee7ef3b36f21701c6aaab2313bfbe21a2c189eb15943a0c25 + ansi-html: ^0.0.7 + error-stack-parser: ^2.0.6 + html-entities: ^1.2.1 + native-url: ^0.2.6 + schema-utils: ^2.6.5 + source-map: ^0.7.3 + peerDependencies: + "@types/webpack": 4.x + react-refresh: ">=0.8.3 <0.10.0" + sockjs-client: ^1.4.0 + type-fest: ^0.13.1 + webpack: ">=4.43.0 <6.0.0" + webpack-dev-server: 3.x + webpack-hot-middleware: 2.x + webpack-plugin-serve: 0.x || 1.x + peerDependenciesMeta: + "@types/webpack": + optional: true + sockjs-client: + optional: true + type-fest: + optional: true + webpack-dev-server: + optional: true + webpack-hot-middleware: + optional: true + webpack-plugin-serve: + optional: true + checksum: 36a7b0c63f0aabde856a2b43f3f3bfa7919920afa67b4fbcf7d4980b286c7c11e34ada13654d81bf30c3d3e2c12a5b9eef6c15e21a200003b8030809d3ddd6c6 languageName: node linkType: hard -"@smithy/util-buffer-from@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-buffer-from@npm:2.2.0" - dependencies: - "@smithy/is-array-buffer": ^2.2.0 - tslib: ^2.6.2 - checksum: 424c5b7368ae5880a8f2732e298d17879a19ca925f24ca45e1c6c005f717bb15b76eb28174d308d81631ad457ea0088aab0fd3255dd42f45a535c81944ad64d3 +"@popperjs/core@npm:^2.11.8": + version: 2.11.8 + resolution: "@popperjs/core@npm:2.11.8" + checksum: e5c69fdebf52a4012f6a1f14817ca8e9599cb1be73dd1387e1785e2ed5e5f0862ff817f420a87c7fc532add1f88a12e25aeb010ffcbdc98eace3d55ce2139cf0 languageName: node linkType: hard -"@smithy/util-buffer-from@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-buffer-from@npm:4.1.0" +"@prisma/client@npm:^4.4.0": + version: 4.16.2 + resolution: "@prisma/client@npm:4.16.2" dependencies: - "@smithy/is-array-buffer": ^4.1.0 - tslib: ^2.6.2 - checksum: a8523e142cfa8a5526ada1bb2f4264c7dc6027875a16752995324c294ea6b2bd502303db16ac74eb49fe602f20d847cdb09054d611e3aa9916c09b7a41e379c0 + "@prisma/engines-version": 4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81 + peerDependencies: + prisma: "*" + peerDependenciesMeta: + prisma: + optional: true + checksum: 38e1356644a764946c69c8691ea4bbed0ba37739d833a435625bd5435912bed4b9bdd7c384125f3a4ab8128faf566027985c0f0840a42741c338d72e40b5d565 languageName: node linkType: hard -"@smithy/util-config-provider@npm:^4.0.0, @smithy/util-config-provider@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-config-provider@npm:4.1.0" - dependencies: - tslib: ^2.6.2 - checksum: 8d13ec9246b05bc3b8af9312ba53d266cb9fff6400957630e3288ed1807c6fb433a7383df385282b84f699f112653069008b9c972e520393a4fed88d19a2e8e3 +"@prisma/engines-version@npm:4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81": + version: 4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81 + resolution: "@prisma/engines-version@npm:4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81" + checksum: b42c6abe7c1928e546f15449e40ffa455701ef2ab1f62973628ecb4e19ff3652e34609a0d83196d1cbd0864adb44c55e082beec852b11929acf1c15fb57ca45a languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-defaults-mode-browser@npm:4.1.1" - dependencies: - "@smithy/property-provider": ^4.1.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - bowser: ^2.11.0 - tslib: ^2.6.2 - checksum: d11a05ecfa89b8ea68d991d925b6799e0b52ae80a3e7e319d41365d1f3ee7852321f84f60997fbd343ef3f51b0148c2b5777e886912f7426b74fd4867d132744 +"@prisma/engines@npm:4.16.2": + version: 4.16.2 + resolution: "@prisma/engines@npm:4.16.2" + checksum: f423e6092c3e558cd089a68ae87459fba7fd390c433df087342b3269c3b04163965b50845150dfe47d01f811781bfff89d5ae81c95ca603c59359ab69ebd810f languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-defaults-mode-node@npm:4.1.1" +"@rollup/plugin-node-resolve@npm:^7.1.1": + version: 7.1.3 + resolution: "@rollup/plugin-node-resolve@npm:7.1.3" dependencies: - "@smithy/config-resolver": ^4.2.1 - "@smithy/credential-provider-imds": ^4.1.1 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/property-provider": ^4.1.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: e28e0febb781f033ff9715e6e17ba0c228507238145ac9c81735c22d3fbff193f42ca2f281cf4fa8a954f1ea629b4ab867a3bae634a92df65ec254498624157a + "@rollup/pluginutils": ^3.0.8 + "@types/resolve": 0.0.8 + builtin-modules: ^3.1.0 + is-module: ^1.0.0 + resolve: ^1.14.2 + peerDependencies: + rollup: ^1.20.0||^2.0.0 + checksum: e787c35f123652762d212b63f8cfaf577307434a935466397021c31b71d0d94357c6fa4e326b49bf44b959e22e41bc21f5648470eabec086566e7c36c5d041b1 languageName: node linkType: hard -"@smithy/util-endpoints@npm:^3.1.1": - version: 3.1.1 - resolution: "@smithy/util-endpoints@npm:3.1.1" +"@rollup/plugin-replace@npm:^2.3.1": + version: 2.4.2 + resolution: "@rollup/plugin-replace@npm:2.4.2" dependencies: - "@smithy/node-config-provider": ^4.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 8c455e689f915c3cd1608f07e0e0e225d6a2eb0d777afb5a950a6332af8928c2688b9089dd56a15dbe3fff52da5f4532b8d630f4abb3a2b934ca01b701e44821 + "@rollup/pluginutils": ^3.1.0 + magic-string: ^0.25.7 + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + checksum: b2f1618ee5526d288e2f8ae328dcb326e20e8dc8bd1f60d3e14d6708a5832e4aa44811f7d493f4aed2deeadca86e3b6b0503cd39bf50cfb4b595bb9da027fad0 languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-hex-encoding@npm:4.1.0" +"@rollup/pluginutils@npm:^3.0.8, @rollup/pluginutils@npm:^3.1.0": + version: 3.1.0 + resolution: "@rollup/pluginutils@npm:3.1.0" dependencies: - tslib: ^2.6.2 - checksum: 0005c0569a18edc9a6fe991acca95c35e1bfecaf7bb4a9ed2a54eed249e7ccc3662c7d5e3c995db5c47dece9841690f56c4cb93b5adc8681c9436dd7cb8ebff5 + "@types/estree": 0.0.39 + estree-walker: ^1.0.1 + picomatch: ^2.2.2 + peerDependencies: + rollup: ^1.20.0||^2.0.0 + checksum: 8be16e27863c219edbb25a4e6ec2fe0e1e451d9e917b6a43cf2ae5bc025a6b8faaa40f82a6e53b66d0de37b58ff472c6c3d57a83037ae635041f8df959d6d9aa languageName: node linkType: hard -"@smithy/util-middleware@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-middleware@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 9f8dc9f29730f70c0575920f9f88073af0c8359e1e0a4114a60834cf1053f6ee8df687814f8f4f9b87a02a591a2a3592ffa2b0d7b93234309fe1cdc52cd51e3a +"@sinclair/typebox@npm:^0.24.1": + version: 0.24.51 + resolution: "@sinclair/typebox@npm:0.24.51" + checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0 languageName: node linkType: hard -"@smithy/util-retry@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-retry@npm:4.1.1" - dependencies: - "@smithy/service-error-classification": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 7ed26ae7b9cd810752f692c749bb8ad083c8fd5000cfd00c9c917806156486b84afb7b8fcf968395b84b3552a6bf46562ec479b97ab4f0cb9d4b121958f1cd5f +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 languageName: node linkType: hard -"@smithy/util-stream@npm:^4.3.1": - version: 4.3.1 - resolution: "@smithy/util-stream@npm:4.3.1" +"@sinonjs/commons@npm:^1.7.0": + version: 1.8.6 + resolution: "@sinonjs/commons@npm:1.8.6" dependencies: - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-buffer-from": ^4.1.0 - "@smithy/util-hex-encoding": ^4.1.0 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: a1b73d9f39811065729bd7304a6deaceea99ddb2f736fb5b95c20d3db53f84e4e53f956c358d95fa747967488b2193b581e96ed75d841164cdb5176fef928eb8 + type-detect: 4.0.8 + checksum: 7d3f8c1e85f30cd4e83594fc19b7a657f14d49eb8d95a30095631ce15e906c869e0eff96c5b93dffea7490c00418b07f54582ba49c6560feb2a8c34c0b16832d languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-uri-escape@npm:4.1.0" +"@sinonjs/fake-timers@npm:^6.0.1": + version: 6.0.1 + resolution: "@sinonjs/fake-timers@npm:6.0.1" dependencies: - tslib: ^2.6.2 - checksum: 0c55f4981af8be1a67fdd154497d41b3ea130da2a409b06a5e899d5f86b498fe4e5b9c065ee018379b976d74ae9aaf45180548e0d96bf7e474fb039da667aac6 + "@sinonjs/commons": ^1.7.0 + checksum: 8e331aa1412d905ecc8efd63550f58a6f77dcb510f878172004e53be63eb82650623618763001a918fc5e21257b86c45041e4e97c454ed6a2d187de084abbd11 languageName: node linkType: hard -"@smithy/util-utf8@npm:^2.0.0": - version: 2.3.0 - resolution: "@smithy/util-utf8@npm:2.3.0" +"@slack/logger@npm:^3.0.0": + version: 3.0.0 + resolution: "@slack/logger@npm:3.0.0" dependencies: - "@smithy/util-buffer-from": ^2.2.0 - tslib: ^2.6.2 - checksum: 00e55d4b4e37d48be0eef3599082402b933c52a1407fed7e8e8ad76d94d81a0b30b8bfaf2047c59d9c3af31e5f20e7a8c959cb7ae270f894255e05a2229964f0 + "@types/node": ">=12.0.0" + checksum: 6512d0e9e4be47ea465705ab9b6e6901f36fa981da0d4a657fde649d452b567b351002049b5ee0a22569b5119bf6c2f61befd5b8022d878addb7a99c91b03389 languageName: node linkType: hard -"@smithy/util-utf8@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-utf8@npm:4.1.0" - dependencies: - "@smithy/util-buffer-from": ^4.1.0 - tslib: ^2.6.2 - checksum: 3a5a1420a5f06bfcc1c15935344f245ea5d297c0d021c52589cb7125fe5a3546e69cedf37940fd84962405116d59c81f56d1adb463105715f4b534f0fe3bf9db +"@slack/types@npm:^2.11.0": + version: 2.11.0 + resolution: "@slack/types@npm:2.11.0" + checksum: b5b7e4be242c9409b247c5be9df480b91a5ad21f367ae96945a7752bd720c65b13623c4a9b37b812107b3a5aa5e5013d7962807230913781ff5f0ad427a79ec2 languageName: node linkType: hard -"@smithy/util-waiter@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-waiter@npm:4.1.1" +"@slack/web-api@npm:^6.7.2": + version: 6.12.0 + resolution: "@slack/web-api@npm:6.12.0" dependencies: - "@smithy/abort-controller": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: f4d16ee1cbcc34a2519e835f70b4e3430fe1bbff611e30951ea83ed997ee6a6c01a3189e4e8c8c2bae441520622f03c6324bd4decac77b02f7001637f26cf83a + "@slack/logger": ^3.0.0 + "@slack/types": ^2.11.0 + "@types/is-stream": ^1.1.0 + "@types/node": ">=12.0.0" + axios: ^1.6.5 + eventemitter3: ^3.1.0 + form-data: ^2.5.0 + is-electron: 2.2.2 + is-stream: ^1.1.0 + p-queue: ^6.6.1 + p-retry: ^4.0.0 + checksum: d0cc16a2981167f3780a07542b4c88d31fc836a743de04e52e9f8fe8a82281781103f8821b3db5aa9de55471b6e550f044e767dbf482045865bd713b90fddd65 languageName: node linkType: hard -"@surma/rollup-plugin-off-main-thread@npm:^2.2.3": - version: 2.2.3 - resolution: "@surma/rollup-plugin-off-main-thread@npm:2.2.3" +"@surma/rollup-plugin-off-main-thread@npm:^1.1.1": + version: 1.4.2 + resolution: "@surma/rollup-plugin-off-main-thread@npm:1.4.2" dependencies: - ejs: ^3.1.6 - json5: ^2.2.0 + ejs: ^2.6.1 magic-string: ^0.25.0 - string.prototype.matchall: ^4.0.6 - checksum: 2c021349442e2e2cec96bb50fd82ec8bf8514d909bc73594f6cfc89b3b68f2feed909a8161d7d307d9455585c97e6b66853ce334db432626c7596836d4549c0c + checksum: da721792036a0e1253911f9b5280e6cb236024d7d2255bde3b6e87587c0ea8f46404224c8c032a27ee11ab3244eda752587fb37ec78c2e64eb53e10557373102 languageName: node linkType: hard @@ -5478,7 +3252,7 @@ __metadata: languageName: node linkType: hard -"@svgr/webpack@npm:^5.5.0": +"@svgr/webpack@npm:5.5.0": version: 5.5.0 resolution: "@svgr/webpack@npm:5.5.0" dependencies: @@ -5494,33 +3268,52 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^10.4.0": - version: 10.4.1 - resolution: "@testing-library/dom@npm:10.4.1" +"@testing-library/dom@npm:^7.28.1": + version: 7.31.2 + resolution: "@testing-library/dom@npm:7.31.2" + dependencies: + "@babel/code-frame": ^7.10.4 + "@babel/runtime": ^7.12.5 + "@types/aria-query": ^4.2.0 + aria-query: ^4.2.2 + chalk: ^4.1.0 + dom-accessibility-api: ^0.5.6 + lz-string: ^1.4.4 + pretty-format: ^26.6.2 + checksum: 54fbedd1ecdfe1d47be2e592b98d18b2ab9d7e731f57231caf9b152593fe7329fe5ebe219e0e5d1e0df5b1ab803121cb8acd8b73bd1fb292bfdc2c55663eb01d + languageName: node + linkType: hard + +"@testing-library/dom@npm:^8.19.0": + version: 8.20.1 + resolution: "@testing-library/dom@npm:8.20.1" dependencies: "@babel/code-frame": ^7.10.4 "@babel/runtime": ^7.12.5 "@types/aria-query": ^5.0.1 - aria-query: 5.3.0 + aria-query: 5.1.3 + chalk: ^4.1.0 dom-accessibility-api: ^0.5.9 lz-string: ^1.5.0 - picocolors: 1.1.1 pretty-format: ^27.0.2 - checksum: 3887fe95594b6d9467a804e2cc82e719c57f4d55d7d9459b72a949b3a8189db40375b89034637326d4be559f115abc6b6bcfcc6fec0591c4a4d4cdde96751a6c + checksum: 06fc8dc67849aadb726cbbad0e7546afdf8923bd39acb64c576d706249bd7d0d05f08e08a31913fb621162e3b9c2bd0dce15964437f030f9fa4476326fdd3007 languageName: node linkType: hard -"@testing-library/jest-dom@npm:^6.6.3": - version: 6.8.0 - resolution: "@testing-library/jest-dom@npm:6.8.0" +"@testing-library/jest-dom@npm:^5.11.9, @testing-library/jest-dom@npm:^5.16.4": + version: 5.17.0 + resolution: "@testing-library/jest-dom@npm:5.17.0" dependencies: - "@adobe/css-tools": ^4.4.0 + "@adobe/css-tools": ^4.0.1 + "@babel/runtime": ^7.9.2 + "@types/testing-library__jest-dom": ^5.9.1 aria-query: ^5.0.0 + chalk: ^3.0.0 css.escape: ^1.5.1 - dom-accessibility-api: ^0.6.3 - picocolors: ^1.1.1 + dom-accessibility-api: ^0.5.6 + lodash: ^4.17.15 redent: ^3.0.0 - checksum: a3cfb162b6ec6e98277187d9488234ba3e3ee25f24a86facdae092dbe54a015c845bcb81daa6de7afadcac5a5fe25becd7c7e9b67bb01ee4ccf7d67ee907adc9 + checksum: 9f28dbca8b50d7c306aae40c3aa8e06f0e115f740360004bd87d57f95acf7ab4b4f4122a7399a76dbf2bdaaafb15c99cc137fdcb0ae457a92e2de0f3fbf9b03b languageName: node linkType: hard @@ -5546,32 +3339,27 @@ __metadata: languageName: node linkType: hard -"@testing-library/react@npm:^16.2.0": - version: 16.3.0 - resolution: "@testing-library/react@npm:16.3.0" +"@testing-library/react@npm:^11.2.5": + version: 11.2.7 + resolution: "@testing-library/react@npm:11.2.7" dependencies: "@babel/runtime": ^7.12.5 + "@testing-library/dom": ^7.28.1 peerDependencies: - "@testing-library/dom": ^10.0.0 - "@types/react": ^18.0.0 || ^19.0.0 - "@types/react-dom": ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 85728ea8a1bcc9d865782a3d3bcc1db6632cb77907b47fb99c7f338e3ebdfc74dc6d21dfc5526a215a4f4f7b7d8a6392de87f48da3848866ab088f327ebb3e92 + react: "*" + react-dom: "*" + checksum: 64e07cb96e40dbdbd3c46a09c47bed14446b30efafaa65a5d4fed5a7553878990cda108578f2b114422a775f31c635d51fd50b752f6163ddd6b8474e0e5fc2ce languageName: node linkType: hard -"@testing-library/user-event@npm:^14.6.0": - version: 14.6.1 - resolution: "@testing-library/user-event@npm:14.6.1" +"@testing-library/user-event@npm:^12.6.3": + version: 12.8.3 + resolution: "@testing-library/user-event@npm:12.8.3" + dependencies: + "@babel/runtime": ^7.12.5 peerDependencies: "@testing-library/dom": ">=7.21.4" - checksum: 4cb8a81fea1fea83a42619e9545137b51636bb7a3182c596bb468e5664f1e4699a275c2d0fb8b6dcc3fe2684f9d87b0637ab7cb4f566051539146872c9141fcb + checksum: c9fb5ee07cbe79ddf32d81e1a353e556d02a1f1619456ccfad6abcdf1b7db400fdc9d7a8e0be3994f456e7135a0dfb7fa10b29fb98a0f5fc417b99fce0ce8166 languageName: node linkType: hard @@ -5582,13 +3370,6 @@ __metadata: languageName: node linkType: hard -"@trysound/sax@npm:0.2.0": - version: 0.2.0 - resolution: "@trysound/sax@npm:0.2.0" - checksum: 11226c39b52b391719a2a92e10183e4260d9651f86edced166da1d95f39a0a1eaa470e44d14ac685ccd6d3df7e2002433782872c0feeb260d61e80f21250e65c - languageName: node - linkType: hard - "@tsconfig/node10@npm:^1.0.7": version: 1.0.11 resolution: "@tsconfig/node10@npm:1.0.11" @@ -5617,6 +3398,13 @@ __metadata: languageName: node linkType: hard +"@types/aria-query@npm:^4.2.0": + version: 4.2.2 + resolution: "@types/aria-query@npm:4.2.2" + checksum: 6f2ce11d91e2d665f3873258db19da752d91d85d3679eb5efcdf9c711d14492287e1e4eb52613b28e60375841a9e428594e745b68436c963d8bad4bf72188df3 + languageName: node + linkType: hard + "@types/aria-query@npm:^5.0.1": version: 5.0.4 resolution: "@types/aria-query@npm:5.0.4" @@ -5624,7 +3412,7 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.14, @types/babel__core@npm:^7.20.5": +"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.7, @types/babel__core@npm:^7.20.5": version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" dependencies: @@ -5638,11 +3426,11 @@ __metadata: linkType: hard "@types/babel__generator@npm:*": - version: 7.27.0 - resolution: "@types/babel__generator@npm:7.27.0" + version: 7.6.8 + resolution: "@types/babel__generator@npm:7.6.8" dependencies: "@babel/types": ^7.0.0 - checksum: e6739cacfa276c1ad38e1d8a6b4b1f816c2c11564e27f558b68151728489aaf0f4366992107ee4ed7615dfa303f6976dedcdce93df2b247116d1bcd1607ee260 + checksum: 5b332ea336a2efffbdeedb92b6781949b73498606ddd4205462f7d96dafd45ff3618770b41de04c4881e333dd84388bfb8afbdf6f2764cbd98be550d85c6bb48 languageName: node linkType: hard @@ -5657,39 +3445,37 @@ __metadata: linkType: hard "@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.4, @types/babel__traverse@npm:^7.0.6": - version: 7.28.0 - resolution: "@types/babel__traverse@npm:7.28.0" + version: 7.20.5 + resolution: "@types/babel__traverse@npm:7.20.5" dependencies: - "@babel/types": ^7.28.2 - checksum: e3124e6575b2f70de338eab8a9c704d315a86c46a8e395b6ec78a0157ab7b5fd877289556a57dcf28e4ff3543714e359cc1182d4afc4bcb4f3575a0bbafa0dad + "@babel/types": ^7.20.7 + checksum: 608e0ab4fc31cd47011d98942e6241b34d461608c0c0e153377c5fd822c436c475f1ded76a56bfa76a1adf8d9266b727bbf9bfac90c4cb152c97f30dadc5b7e8 languageName: node linkType: hard "@types/body-parser@npm:*": - version: 1.19.6 - resolution: "@types/body-parser@npm:1.19.6" + version: 1.19.5 + resolution: "@types/body-parser@npm:1.19.5" dependencies: "@types/connect": "*" "@types/node": "*" - checksum: 33041e88eae00af2cfa0827e951e5f1751eafab2a8b6fce06cd89ef368a988907996436b1325180edaeddd1c0c7d0d0d4c20a6c9ff294a91e0039a9db9e9b658 + checksum: 1e251118c4b2f61029cc43b0dc028495f2d1957fe8ee49a707fb940f86a9bd2f9754230805598278fe99958b49e9b7e66eec8ef6a50ab5c1f6b93e1ba2aaba82 languageName: node linkType: hard -"@types/bonjour@npm:^3.5.9": - version: 3.5.13 - resolution: "@types/bonjour@npm:3.5.13" +"@types/chai-subset@npm:^1.3.3": + version: 1.3.5 + resolution: "@types/chai-subset@npm:1.3.5" dependencies: - "@types/node": "*" - checksum: e827570e097bd7d625a673c9c208af2d1a22fa3885c0a1646533cf24394c839c3e5f60ac1bc60c0ddcc69c0615078c9fb2c01b42596c7c582d895d974f2409ee + "@types/chai": "*" + checksum: 715c46d3e90f87482c2769389d560456bb257b225716ff44c275c231bdb62c8a30629f355f412bac0ecab07ebc036c1806d9ed9dde9792254f8ef4f07f76033b languageName: node linkType: hard -"@types/chai@npm:^5.2.2": - version: 5.2.2 - resolution: "@types/chai@npm:5.2.2" - dependencies: - "@types/deep-eql": "*" - checksum: 386887bd55ba684572cececd833ed91aba6cce2edd8cc1d8cefa78800b3a74db6dbf5c5c41af041d1d1f3ce672ea30b45c9520f948cdc75431eb7df3fbba8405 +"@types/chai@npm:*, @types/chai@npm:^4.3.5": + version: 4.3.14 + resolution: "@types/chai@npm:4.3.14" + checksum: 962c67d1295005886ced8f87c73614616f6d65ed1ec71818021c9206decbaab1234da878295ba52450883c78a8ee5e1359e5deeadee3b7d058538b0ae8c67b08 languageName: node linkType: hard @@ -5702,16 +3488,6 @@ __metadata: languageName: node linkType: hard -"@types/connect-history-api-fallback@npm:^1.3.5": - version: 1.5.4 - resolution: "@types/connect-history-api-fallback@npm:1.5.4" - dependencies: - "@types/express-serve-static-core": "*" - "@types/node": "*" - checksum: e1dee43b8570ffac02d2d47a2b4ba80d3ca0dd1840632dafb221da199e59dbe3778d3d7303c9e23c6b401f37c076935a5bc2aeae1c4e5feaefe1c371fe2073fd - languageName: node - linkType: hard - "@types/connect@npm:*": version: 3.4.38 resolution: "@types/connect@npm:3.4.38" @@ -5722,18 +3498,18 @@ __metadata: linkType: hard "@types/cookie-parser@npm:^1.4.3": - version: 1.4.9 - resolution: "@types/cookie-parser@npm:1.4.9" - peerDependencies: + version: 1.4.7 + resolution: "@types/cookie-parser@npm:1.4.7" + dependencies: "@types/express": "*" - checksum: 6192a4899b5412a4c3be0f47158321aef73a4cd7e7a4f7b2a37e2e1045f11a21209681cb1bc5335f250ee2a6ce64d8a3fefb851181a98e6415d3716ef9ed1f62 + checksum: 7b87c59420598e686a57e240be6e0db53967c3c8814be9326bf86609ee2fc39c4b3b9f2263e1deba43526090121d1df88684b64c19f7b494a80a4437caf3d40b languageName: node linkType: hard -"@types/cookie@npm:^0.6.0": - version: 0.6.0 - resolution: "@types/cookie@npm:0.6.0" - checksum: 5edce7995775b0b196b142883e4d4f71fd93c294eaec973670f1fa2540b70ea7390408ed513ddefef5fcb12a578100c76596e8f2a714b0c2ae9f70ee773f4510 +"@types/cookie@npm:^0.4.1": + version: 0.4.1 + resolution: "@types/cookie@npm:0.4.1" + checksum: 3275534ed69a76c68eb1a77d547d75f99fedc80befb75a3d1d03662fb08d697e6f8b1274e12af1a74c6896071b11510631ba891f64d30c78528d0ec45a9c1a18 languageName: node linkType: hard @@ -5745,84 +3521,15 @@ __metadata: linkType: hard "@types/cors@npm:^2.8.12": - version: 2.8.19 - resolution: "@types/cors@npm:2.8.19" + version: 2.8.17 + resolution: "@types/cors@npm:2.8.17" dependencies: "@types/node": "*" - checksum: 9545cc532c9218754443f48a0c98c1a9ba4af1fe54a3425c95de75ff3158147bb39e666cb7c6bf98cc56a9c6dc7b4ce5b2cbdae6b55d5942e50c81b76ed6b825 - languageName: node - linkType: hard - -"@types/d3-array@npm:^3.0.3": - version: 3.2.2 - resolution: "@types/d3-array@npm:3.2.2" - checksum: 72e8e2abe0911cb431d6f3fe0a1f71b915356b679d4d9c826f52941bb30210c0fe8299dde066b08d9986754c620f031b13b13ab6dfc60d404eceab66a075dd5d - languageName: node - linkType: hard - -"@types/d3-color@npm:*": - version: 3.1.3 - resolution: "@types/d3-color@npm:3.1.3" - checksum: 8a0e79a709929502ec4effcee2c786465b9aec51b653ba0b5d05dbfec3e84f418270dd603002d94021885061ff592f614979193bd7a02ad76317f5608560e357 - languageName: node - linkType: hard - -"@types/d3-ease@npm:^3.0.0": - version: 3.0.2 - resolution: "@types/d3-ease@npm:3.0.2" - checksum: 0885219966294bfc99548f37297e1c75e75da812a5f3ec941977ebb57dcab0a25acec5b2bbd82d09a49d387daafca08521ca269b7e4c27ddca7768189e987b54 - languageName: node - linkType: hard - -"@types/d3-interpolate@npm:^3.0.1": - version: 3.0.4 - resolution: "@types/d3-interpolate@npm:3.0.4" - dependencies: - "@types/d3-color": "*" - checksum: efd2770e174e84fc7316fdafe03cf3688451f767dde1fa6211610137f495be7f3923db7e1723a6961a0e0e9ae0ed969f4f47c038189fa0beb1d556b447922622 - languageName: node - linkType: hard - -"@types/d3-path@npm:*": - version: 3.1.1 - resolution: "@types/d3-path@npm:3.1.1" - checksum: fee8f6b0d3b28a3611c7d7fda3bf2f79392ded266f54b03a220f205c42117644bdcd33dcbf4853da3cca02229f1c669d2a60d5d297a24ce459ba8271ccb26c03 - languageName: node - linkType: hard - -"@types/d3-scale@npm:^4.0.2": - version: 4.0.9 - resolution: "@types/d3-scale@npm:4.0.9" - dependencies: - "@types/d3-time": "*" - checksum: c44265a38e538983686b1b8d159abfb4e81c09b33316f3a68f0f372d38400fa950ad531644d25230cc7b48ea5adb50270fc54823f088979ade62dcd0225f7aa3 - languageName: node - linkType: hard - -"@types/d3-shape@npm:^3.1.0": - version: 3.1.7 - resolution: "@types/d3-shape@npm:3.1.7" - dependencies: - "@types/d3-path": "*" - checksum: 776b982e2c4fc04763782af5100993c02bca338632ff2c76d2423ace398300ba7c48cd745f95b5f51edefabbfd026c45829a146c411f8facde09ef92580b20ce - languageName: node - linkType: hard - -"@types/d3-time@npm:*, @types/d3-time@npm:^3.0.0": - version: 3.0.4 - resolution: "@types/d3-time@npm:3.0.4" - checksum: 0c296884571ce70c4bbd4ea9cd1c93c0c8aee602c6c806b056187dd4ee49daf70c2f41da94b25ba0d796edf8ca83cbb87fe6d1cdda7ca669ab800170ece1c12b - languageName: node - linkType: hard - -"@types/d3-timer@npm:^3.0.0": - version: 3.0.2 - resolution: "@types/d3-timer@npm:3.0.2" - checksum: 1643eebfa5f4ae3eb00b556bbc509444d88078208ec2589ddd8e4a24f230dd4cf2301e9365947e70b1bee33f63aaefab84cd907822aae812b9bc4871b98ab0e1 + checksum: 469bd85e29a35977099a3745c78e489916011169a664e97c4c3d6538143b0a16e4cc72b05b407dc008df3892ed7bf595f9b7c0f1f4680e169565ee9d64966bde languageName: node linkType: hard -"@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.4": +"@types/debug@npm:^4.1.7": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" dependencies: @@ -5831,56 +3538,20 @@ __metadata: languageName: node linkType: hard -"@types/deep-eql@npm:*": - version: 4.0.2 - resolution: "@types/deep-eql@npm:4.0.2" - checksum: 249a27b0bb22f6aa28461db56afa21ec044fa0e303221a62dff81831b20c8530502175f1a49060f7099e7be06181078548ac47c668de79ff9880241968d43d0c - languageName: node - linkType: hard - -"@types/eslint-scope@npm:^3.7.7": - version: 3.7.7 - resolution: "@types/eslint-scope@npm:3.7.7" - dependencies: - "@types/eslint": "*" - "@types/estree": "*" - checksum: e2889a124aaab0b89af1bab5959847c5bec09809209255de0e63b9f54c629a94781daa04adb66bffcdd742f5e25a17614fb933965093c0eea64aacda4309380e - languageName: node - linkType: hard - -"@types/eslint@npm:*": - version: 9.6.1 - resolution: "@types/eslint@npm:9.6.1" - dependencies: - "@types/estree": "*" - "@types/json-schema": "*" - checksum: c286e79707ab604b577cf8ce51d9bbb9780e3d6a68b38a83febe13fa05b8012c92de17c28532fac2b03d3c460123f5055d603a579685325246ca1c86828223e0 - languageName: node - linkType: hard - -"@types/eslint@npm:^7.29.0 || ^8.4.1": - version: 8.56.12 - resolution: "@types/eslint@npm:8.56.12" +"@types/eslint@npm:^7.29.0": + version: 7.29.0 + resolution: "@types/eslint@npm:7.29.0" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: 0f7710ee02a256c499514251f527f84de964bb29487db840408e4cde79283124a38935597636d2265756c34dd1d902e1b00ae78930d4a0b55111909cb7b80d84 + checksum: df13991c554954353ce8f3bb03e19da6cc71916889443d68d178d4f858b561ba4cc4a4f291c6eb9eebb7f864b12b9b9313051b3a8dfea3e513dadf3188a77bdf languageName: node linkType: hard -"@types/estree-jsx@npm:^1.0.0": +"@types/estree@npm:*": version: 1.0.5 - resolution: "@types/estree-jsx@npm:1.0.5" - dependencies: - "@types/estree": "*" - checksum: a028ab0cd7b2950168a05c6a86026eb3a36a54a4adfae57f13911d7b49dffe573d9c2b28421b2d029b49b3d02fcd686611be2622dc3dad6d9791166c083f6008 - languageName: node - linkType: hard - -"@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.8": - version: 1.0.8 - resolution: "@types/estree@npm:1.0.8" - checksum: bd93e2e415b6f182ec4da1074e1f36c480f1d26add3e696d54fb30c09bc470897e41361c8fd957bf0985024f8fbf1e6e2aff977d79352ef7eb93a5c6dcff6c11 + resolution: "@types/estree@npm:1.0.5" + checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a languageName: node linkType: hard @@ -5901,27 +3572,15 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^5.0.0": - version: 5.0.7 - resolution: "@types/express-serve-static-core@npm:5.0.7" - dependencies: - "@types/node": "*" - "@types/qs": "*" - "@types/range-parser": "*" - "@types/send": "*" - checksum: 3539f5866720c081053daeb97d6786614791b382ec2f30b46f05c09076c99ae14c87755b00d8367f7d456535191594d67336dbaa764e8fbbba9ca3dfb15dae00 - languageName: node - linkType: hard - "@types/express-serve-static-core@npm:^4.17.33": - version: 4.19.6 - resolution: "@types/express-serve-static-core@npm:4.19.6" + version: 4.19.0 + resolution: "@types/express-serve-static-core@npm:4.19.0" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: b0576eddc2d25ccdf10e68ba09598b87a4d7b2ad04a81dc847cb39fe56beb0b6a5cc017b1e00aa0060cb3b38e700384ce96d291a116a0f1e54895564a104aae9 + checksum: 39c09fcb3f61de96ed56d97273874cafe50e6675ac254af4d77014e569e4fdc29d1d0d1dd12e11f008cb9a52785b07c2801c6ba91397965392b20c75ee01fb4e languageName: node linkType: hard @@ -5934,26 +3593,15 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^5.0.0": - version: 5.0.3 - resolution: "@types/express@npm:5.0.3" - dependencies: - "@types/body-parser": "*" - "@types/express-serve-static-core": ^5.0.0 - "@types/serve-static": "*" - checksum: bb6f10c14c8e3cce07f79ee172688aa9592852abd7577b663cd0c2054307f172c2b2b36468c918fed0d4ac359b99695807b384b3da6157dfa79acbac2226b59b - languageName: node - linkType: hard - -"@types/express@npm:^4.17.0, @types/express@npm:^4.17.13": - version: 4.17.23 - resolution: "@types/express@npm:4.17.23" +"@types/express@npm:*, @types/express@npm:^4.17.6": + version: 4.17.21 + resolution: "@types/express@npm:4.17.21" dependencies: "@types/body-parser": "*" "@types/express-serve-static-core": ^4.17.33 "@types/qs": "*" "@types/serve-static": "*" - checksum: f1a020c6ad6dc0169a3277199605d60649d463a72c920673e0f230ab1e76f2d3aa23daabd25ef8e62eda314e26b879306c58ec806e669e1e40ca37a4b73a44b0 + checksum: fb238298630370a7392c7abdc80f495ae6c716723e114705d7e3fb67e3850b3859bbfd29391463a3fb8c0b32051847935933d99e719c0478710f8098ee7091c5 languageName: node linkType: hard @@ -5964,6 +3612,16 @@ __metadata: languageName: node linkType: hard +"@types/glob@npm:^7.1.1": + version: 7.2.0 + resolution: "@types/glob@npm:7.2.0" + dependencies: + "@types/minimatch": "*" + "@types/node": "*" + checksum: 6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19 + languageName: node + linkType: hard + "@types/graceful-fs@npm:^4.1.2": version: 4.1.9 resolution: "@types/graceful-fs@npm:4.1.9" @@ -5973,12 +3631,12 @@ __metadata: languageName: node linkType: hard -"@types/hast@npm:^3.0.0": - version: 3.0.4 - resolution: "@types/hast@npm:3.0.4" +"@types/hast@npm:^2.0.0": + version: 2.3.10 + resolution: "@types/hast@npm:2.3.10" dependencies: - "@types/unist": "*" - checksum: 7a973e8d16fcdf3936090fa2280f408fb2b6a4f13b42edeb5fbd614efe042b82eac68e298e556d50f6b4ad585a3a93c353e9c826feccdc77af59de8dd400d044 + "@types/unist": ^2 + checksum: 41531b7fbf590b02452996fc63272479c20a07269e370bd6514982cbcd1819b4b84d3ea620f2410d1b9541a23d08ce2eeb0a592145d05e00e249c3d56700d460 languageName: node linkType: hard @@ -5989,26 +3647,26 @@ __metadata: languageName: node linkType: hard -"@types/html-minifier-terser@npm:^6.0.0": - version: 6.1.0 - resolution: "@types/html-minifier-terser@npm:6.1.0" - checksum: eb843f6a8d662d44fb18ec61041117734c6aae77aa38df1be3b4712e8e50ffaa35f1e1c92fdd0fde14a5675fecf457abcd0d15a01fae7506c91926176967f452 +"@types/html-minifier-terser@npm:^5.0.0": + version: 5.1.2 + resolution: "@types/html-minifier-terser@npm:5.1.2" + checksum: 4bca779c44d2aebe4cc4036c5db370abe7466249038e9c5996cb3c192debeff1c75b7a2ab78e5fd2a014ad24ebf0f357f9a174a4298540dc1e1317d43aa69cfa languageName: node linkType: hard "@types/http-errors@npm:*": - version: 2.0.5 - resolution: "@types/http-errors@npm:2.0.5" - checksum: a88da669366bc483e8f3b3eb3d34ada5f8d13eeeef851b1204d77e2ba6fc42aba4566d877cca5c095204a3f4349b87fe397e3e21288837bdd945dd514120755b + version: 2.0.4 + resolution: "@types/http-errors@npm:2.0.4" + checksum: 1f3d7c3b32c7524811a45690881736b3ef741bf9849ae03d32ad1ab7062608454b150a4e7f1351f83d26a418b2d65af9bdc06198f1c079d75578282884c4e8e3 languageName: node linkType: hard -"@types/http-proxy@npm:^1.17.8": - version: 1.17.16 - resolution: "@types/http-proxy@npm:1.17.16" +"@types/is-stream@npm:^1.1.0": + version: 1.1.0 + resolution: "@types/is-stream@npm:1.1.0" dependencies: "@types/node": "*" - checksum: f5ab4afe7e3feba9d87bdddbf44e03d9a836bd2cdab679a794badbff7c4bfb6bebf46bfe22d9964eb1820e1349f2ff7807cccb20fd27cb17f03db849289e5892 + checksum: 23fcb06cd8adc0124d4c44071bd4b447c41f5e4c2eccb6166789c7fc0992b566e2e8b628a3800ff4472b686d9085adbec203925068bf72e350e085650e83adec languageName: node linkType: hard @@ -6037,17 +3695,34 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:^29.5.14": - version: 29.5.14 - resolution: "@types/jest@npm:29.5.14" +"@types/jest@npm:*": + version: 29.5.12 + resolution: "@types/jest@npm:29.5.12" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: 18dba4623f26661641d757c63da2db45e9524c9be96a29ef713c703a9a53792df9ecee9f7365a0858ddbd6440d98fe6b65ca67895ca5884b73cbc7ffc11f3838 + checksum: 19b1efdeed9d9a60a81edc8226cdeae5af7479e493eaed273e01243891c9651f7b8b4c08fc633a7d0d1d379b091c4179bbaa0807af62542325fd72f2dd17ce1c + languageName: node + linkType: hard + +"@types/jest@npm:^28.1.6": + version: 28.1.8 + resolution: "@types/jest@npm:28.1.8" + dependencies: + expect: ^28.0.0 + pretty-format: ^28.0.0 + checksum: d4cd36158a3ae1d4b42cc48a77c95de74bc56b84cf81e09af3ee0399c34f4a7da8ab9e787570f10004bd642f9e781b0033c37327fbbf4a8e4b6e37e8ee3693a7 + languageName: node + linkType: hard + +"@types/js-levenshtein@npm:^1.1.1": + version: 1.1.3 + resolution: "@types/js-levenshtein@npm:1.1.3" + checksum: eb338696da976925ea8448a42d775d7615a14323dceeb08909f187d0b3d3b4c1f67a1c36ef586b1c2318b70ab141bba8fc58311ba1c816711704605aec09db8b languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.3, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 @@ -6070,28 +3745,19 @@ __metadata: languageName: node linkType: hard -"@types/lodash.isstring@npm:^4.0.6": - version: 4.0.9 - resolution: "@types/lodash.isstring@npm:4.0.9" - dependencies: - "@types/lodash": "*" - checksum: ef381be69b459caa42d7c5dc4ff5b3653e6b3c9b2393f6e92848efeafe7690438e058b26f036b11b4e535fc7645ff12d1203847b9a82e9ae0593bdd3b25a971b - languageName: node - linkType: hard - -"@types/lodash@npm:*": - version: 4.17.20 - resolution: "@types/lodash@npm:4.17.20" - checksum: dc7bb4653514dd91117a4c4cec2c37e2b5a163d7643445e4757d76a360fabe064422ec7a42dde7450c5e7e0e7e678d5e6eae6d2a919abcddf581d81e63e63839 +"@types/lodash@npm:^4.14.175": + version: 4.17.0 + resolution: "@types/lodash@npm:4.17.0" + checksum: 3f98c0b67a93994cbc3403d4fa9dbaf52b0b6bb7f07a764d73875c2dcd5ef91222621bd5bcf8eee7b417a74d175c2f7191b9f595f8603956fd06f0674c0cba93 languageName: node linkType: hard -"@types/mdast@npm:^4.0.0": - version: 4.0.4 - resolution: "@types/mdast@npm:4.0.4" +"@types/mdast@npm:^3.0.0": + version: 3.0.15 + resolution: "@types/mdast@npm:3.0.15" dependencies: - "@types/unist": "*" - checksum: 20c4e9574cc409db662a35cba52b068b91eb696b3049e94321219d47d34c8ccc99a142be5c76c80a538b612457b03586bc2f6b727a3e9e7530f4c8568f6282ee + "@types/unist": ^2 + checksum: af85042a4e3af3f879bde4059fa9e76c71cb552dffc896cdcc6cf9dc1fd38e37035c2dbd6245cfa6535b433f1f0478f5549696234ccace47a64055a10c656530 languageName: node linkType: hard @@ -6109,37 +3775,35 @@ __metadata: languageName: node linkType: hard -"@types/ms@npm:*": - version: 2.1.0 - resolution: "@types/ms@npm:2.1.0" - checksum: 532d2ebb91937ccc4a89389715e5b47d4c66e708d15942fe6cc25add6dc37b2be058230a327dd50f43f89b8b6d5d52b74685a9e8f70516edfc9bdd6be910eff4 +"@types/minimatch@npm:*": + version: 5.1.2 + resolution: "@types/minimatch@npm:5.1.2" + checksum: 0391a282860c7cb6fe262c12b99564732401bdaa5e395bee9ca323c312c1a0f45efbf34dce974682036e857db59a5c9b1da522f3d6055aeead7097264c8705a8 languageName: node linkType: hard -"@types/multer@npm:^1.4.12, @types/multer@npm:^1.4.7": - version: 1.4.13 - resolution: "@types/multer@npm:1.4.13" - dependencies: - "@types/express": "*" - checksum: 9692a1ad5b185c86b15e852be8d6c2ba8fd85c22beffdb52cc5770bd6c0710bc904c134011949547dbd3e113899d0136a3c63fa5fc8c300be182cfdb8670de42 +"@types/ms@npm:*": + version: 0.7.34 + resolution: "@types/ms@npm:0.7.34" + checksum: f38d36e7b6edecd9badc9cf50474159e9da5fa6965a75186cceaf883278611b9df6669dc3a3cc122b7938d317b68a9e3d573d316fcb35d1be47ec9e468c6bd8a languageName: node linkType: hard -"@types/node-forge@npm:^1.3.0": - version: 1.3.14 - resolution: "@types/node-forge@npm:1.3.14" +"@types/multer@npm:^1.4.7": + version: 1.4.11 + resolution: "@types/multer@npm:1.4.11" dependencies: - "@types/node": "*" - checksum: ff621803390e723e56b289a89fca3a06f9f8b438add1b843203a0f64bcbc7ac03d457136b3c15010b5bc89d81f57b35f62964e6e980f6290597bb21b4463c009 + "@types/express": "*" + checksum: 3d80b2acdfbc9f3e9027d4467e948925810b67e5622a3017f42f58a3598d34b25376890801e55d0c03973ccc34573abf5218af334e8292ec455832f4ade3e5f5 languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=18.0.0": - version: 24.3.3 - resolution: "@types/node@npm:24.3.3" +"@types/node@npm:*, @types/node@npm:>=12.0.0": + version: 20.12.7 + resolution: "@types/node@npm:20.12.7" dependencies: - undici-types: ~7.10.0 - checksum: b67244aa37ab53690ac6f3565f06ad2e3ca5fae78ef3f60431e1c78e014426106643d3dc31d6f00b62aa8051cd1360178cafb6ce6a49afa5dcecba8339e23462 + undici-types: ~5.26.4 + checksum: 7cc979f7e2ca9a339ec71318c3901b9978555257929ef3666987f3e447123bc6dc92afcc89f6347e09e07d602fde7d51bcddea626c23aa2bb74aeaacfd1e1686 languageName: node linkType: hard @@ -6150,36 +3814,19 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:20.0.0": - version: 20.0.0 - resolution: "@types/node@npm:20.0.0" - checksum: 7dadc41081eee634fd0b19e46dfb0a74f8296ee562533118f7c2f2b54dcaba7124961d506db425fff74d8e8288610b93939cd06fa723f053c72b1a7e87aa4ddc - languageName: node - linkType: hard - -"@types/node@npm:>=12.13.0 < 13": - version: 12.20.55 - resolution: "@types/node@npm:12.20.55" - checksum: e4f86785f4092706e0d3b0edff8dca5a13b45627e4b36700acd8dfe6ad53db71928c8dee914d4276c7fd3b6ccd829aa919811c9eb708a2c8e4c6eb3701178c37 - languageName: node - linkType: hard - -"@types/node@npm:^20.0.0": - version: 20.19.14 - resolution: "@types/node@npm:20.19.14" +"@types/nodemailer@npm:^6.4.7": + version: 6.4.14 + resolution: "@types/nodemailer@npm:6.4.14" dependencies: - undici-types: ~6.21.0 - checksum: a19533f35718cfb543caa33a65abe020bf6ca9e8ae1db0b6802df152adcdc7d00a3793e811c89b5b51c1d0f4ee32e6650f1ed21e0f49948e4d36c849b5a2917a + "@types/node": "*" + checksum: 5f61f01dd736b17f431d1e8b320322f86460604b45df947fc4bc8999d7c7719405e349f7abba86e4fb100a464a30b52615d00dac03d9cb37562ff04487ebd310 languageName: node linkType: hard -"@types/nodemailer@npm:^6.4.0": - version: 6.4.19 - resolution: "@types/nodemailer@npm:6.4.19" - dependencies: - "@aws-sdk/client-ses": ^3.731.1 - "@types/node": "*" - checksum: 7f449db31d8c0b150da554158e04d9fd631832ff2c01cc7c906ec9619a5295d7f525db959bfd3fc0eb451f386dd052ddbcbe1a337e3f776a3d9d554701a9df53 +"@types/normalize-package-data@npm:^2.4.0": + version: 2.4.4 + resolution: "@types/normalize-package-data@npm:2.4.4" + checksum: 65dff72b543997b7be8b0265eca7ace0e34b75c3e5fee31de11179d08fa7124a7a5587265d53d0409532ecb7f7fba662c2012807963e1f9b059653ec2c83ee05 languageName: node linkType: hard @@ -6190,17 +3837,17 @@ __metadata: languageName: node linkType: hard -"@types/prettier@npm:^2.1.5": +"@types/prettier@npm:^2.0.0": version: 2.7.3 resolution: "@types/prettier@npm:2.7.3" checksum: 705384209cea6d1433ff6c187c80dcc0b95d99d5c5ce21a46a9a58060c527973506822e428789d842761e0280d25e3359300f017fbe77b9755bc772ab3dc2f83 languageName: node linkType: hard -"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.12, @types/prop-types@npm:^15.7.14, @types/prop-types@npm:^15.7.15": - version: 15.7.15 - resolution: "@types/prop-types@npm:15.7.15" - checksum: 31aa2f59b28f24da6fb4f1d70807dae2aedfce090ec63eaf9ea01727a9533ef6eaf017de5bff99fbccad7d1c9e644f52c6c2ba30869465dd22b1a7221c29f356 +"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.11, @types/prop-types@npm:^15.7.12": + version: 15.7.12 + resolution: "@types/prop-types@npm:15.7.12" + checksum: ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe languageName: node linkType: hard @@ -6212,9 +3859,9 @@ __metadata: linkType: hard "@types/qs@npm:*": - version: 6.14.0 - resolution: "@types/qs@npm:6.14.0" - checksum: 1909205514d22b3cbc7c2314e2bd8056d5f05dfb21cf4377f0730ee5e338ea19957c41735d5e4806c746176563f50005bbab602d8358432e25d900bdf4970826 + version: 6.9.15 + resolution: "@types/qs@npm:6.9.15" + checksum: 97d8208c2b82013b618e7a9fc14df6bd40a73e1385ac479b6896bafc7949a46201c15f42afd06e86a05e914f146f495f606b6fb65610cc60cf2e0ff743ec38a2 languageName: node linkType: hard @@ -6273,12 +3920,12 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:^4.4.11, @types/react-transition-group@npm:^4.4.12": - version: 4.4.12 - resolution: "@types/react-transition-group@npm:4.4.12" - peerDependencies: +"@types/react-transition-group@npm:^4.4.10, @types/react-transition-group@npm:^4.4.8": + version: 4.4.10 + resolution: "@types/react-transition-group@npm:4.4.10" + dependencies: "@types/react": "*" - checksum: 13d36396cae4d3c316b03d4a0ba299f0d039c59368ba65e04b0c3dc06fd0a16f59d2c669c3e32d6d525a95423f156b84e550d26bff0bdd8df285f305f8f3a0ed + checksum: fe2ea11f70251e9f79f368e198c18fd469b1d4f1e1d44e4365845b44e15974b0ec925100036f449b023b0ca3480a82725c5f0a73040e282ad32ec7b0def9b57c languageName: node linkType: hard @@ -6292,12 +3939,12 @@ __metadata: languageName: node linkType: hard -"@types/resolve@npm:1.17.1": - version: 1.17.1 - resolution: "@types/resolve@npm:1.17.1" +"@types/resolve@npm:0.0.8": + version: 0.0.8 + resolution: "@types/resolve@npm:0.0.8" dependencies: "@types/node": "*" - checksum: dc6a6df507656004e242dcb02c784479deca516d5f4b58a1707e708022b269ae147e1da0521f3e8ad0d63638869d87e0adc023f0bd5454aa6f72ac66c7525cf5 + checksum: f241bb773ab14b14500623ac3b57c52006ce32b20426b6d8bf2fe5fdc0344f42c77ac0f94ff57b443ae1d320a1a86c62b4e47239f0321699404402fbeb24bad6 languageName: node linkType: hard @@ -6308,49 +3955,40 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.12": - version: 7.7.1 - resolution: "@types/semver@npm:7.7.1" - checksum: 76d218e414482a398148d5c28f2bfa017108869f3fc18cda379c9d8d062348f8b9653ae2fa8642d3b5b52e211928fe8be34f22da4e1f08245c84e0e51e040673 - languageName: node - linkType: hard - "@types/send@npm:*": - version: 0.17.5 - resolution: "@types/send@npm:0.17.5" + version: 0.17.4 + resolution: "@types/send@npm:0.17.4" dependencies: "@types/mime": ^1 "@types/node": "*" - checksum: bff5add75eb178c3b80bebc422db483c76eeb2cb5016508c952e4fc67d968794f9c709b978d086bf60e4d6fbfe8c0b77e99a7603a615c671c1f97f808458d4a8 + checksum: cf4db48251bbb03cd6452b4de6e8e09e2d75390a92fd798eca4a803df06444adc94ed050246c94c7ed46fb97be1f63607f0e1f13c3ce83d71788b3e08640e5e0 languageName: node linkType: hard -"@types/serve-index@npm:^1.9.1": - version: 1.9.4 - resolution: "@types/serve-index@npm:1.9.4" - dependencies: - "@types/express": "*" - checksum: 72727c88d54da5b13275ebfb75dcdc4aa12417bbe9da1939e017c4c5f0c906fae843aa4e0fbfe360e7ee9df2f3d388c21abfc488f77ce58693fb57809f8ded92 - languageName: node - linkType: hard - -"@types/serve-static@npm:*, @types/serve-static@npm:^1.13.10": - version: 1.15.8 - resolution: "@types/serve-static@npm:1.15.8" +"@types/serve-static@npm:*": + version: 1.15.7 + resolution: "@types/serve-static@npm:1.15.7" dependencies: "@types/http-errors": "*" "@types/node": "*" "@types/send": "*" - checksum: 41e0fb40bfdf3b5c2ac997c5dd5d58af9229e6a325dab1cf5f73b488b09635d933c1aa6f0e3265d6df8b45be0d09af36a9ffe90175088726f1db6bf104bf9ecf + checksum: bbbf00dbd84719da2250a462270dc68964006e8d62f41fe3741abd94504ba3688f420a49afb2b7478921a1544d3793183ffa097c5724167da777f4e0c7f1a7d6 languageName: node linkType: hard -"@types/sockjs@npm:^0.3.33": - version: 0.3.36 - resolution: "@types/sockjs@npm:0.3.36" +"@types/set-cookie-parser@npm:^2.4.0": + version: 2.4.7 + resolution: "@types/set-cookie-parser@npm:2.4.7" dependencies: "@types/node": "*" - checksum: b4b5381122465d80ea8b158537c00bc82317222d3fb31fd7229ff25b31fa89134abfbab969118da55622236bf3d8fee75759f3959908b5688991f492008f29bc + checksum: 01ef803e24b8cd33e49fe7463f32a562da45ce3f960381b90cccf67ea71b1830d2273df044255b040069c0a92ea25b4bf21c39ac2f85b50c01818ded5e918554 + languageName: node + linkType: hard + +"@types/source-list-map@npm:*": + version: 0.1.6 + resolution: "@types/source-list-map@npm:0.1.6" + checksum: 9cd294c121f1562062de5d241fe4d10780b1131b01c57434845fe50968e9dcf67ede444591c2b1ad6d3f9b6bc646ac02cc8f51a3577c795f9c64cf4573dcc6b1 languageName: node linkType: hard @@ -6361,22 +3999,14 @@ __metadata: languageName: node linkType: hard -"@types/statuses@npm:^2.0.4": - version: 2.0.6 - resolution: "@types/statuses@npm:2.0.6" - checksum: dadfbb4f32a16d3106a8e2a957dab17b1ae99fc4788e1fd96aeaf82355e3b2b069d5ea0f5fb887efa830def033828955a5bbdfd35454ba2088822537aed9e5db - languageName: node - linkType: hard - "@types/superagent@npm:*": - version: 8.1.9 - resolution: "@types/superagent@npm:8.1.9" + version: 8.1.6 + resolution: "@types/superagent@npm:8.1.6" dependencies: "@types/cookiejar": ^2.1.5 "@types/methods": ^1.1.4 "@types/node": "*" - form-data: ^4.0.0 - checksum: 530d8c2e87706315c82c8c9696500c40621de3353bc54ea9b104947f3530243abf54d0a49a6ae219d4947606a102ceb94bedfc43b9cc49f74069a18cbb3be8e2 + checksum: 240ea5a58bb3c9e53f0dbe1ccd1bfe046e084fffdb4eaf44f0bf846fb98dad98ce03d057fdfb555bfa06afbb76a0e5877fe639750b798edac594bc7e19833934 languageName: node linkType: hard @@ -6389,54 +4019,60 @@ __metadata: languageName: node linkType: hard -"@types/trusted-types@npm:^2.0.2": - version: 2.0.7 - resolution: "@types/trusted-types@npm:2.0.7" - checksum: 8e4202766a65877efcf5d5a41b7dd458480b36195e580a3b1085ad21e948bc417d55d6f8af1fd2a7ad008015d4117d5fdfe432731157da3c68678487174e4ba3 - languageName: node - linkType: hard - -"@types/unist@npm:*, @types/unist@npm:^3.0.0": - version: 3.0.3 - resolution: "@types/unist@npm:3.0.3" - checksum: 96e6453da9e075aaef1dc22482463898198acdc1eeb99b465e65e34303e2ec1e3b1ed4469a9118275ec284dc98019f63c3f5d49422f0e4ac707e5ab90fb3b71a +"@types/tapable@npm:^1, @types/tapable@npm:^1.0.5": + version: 1.0.12 + resolution: "@types/tapable@npm:1.0.12" + checksum: 5312fbc01e0135bd11b44cfea2bf29943807cd9675c10bbed13873ad0e73f656993fb88bb6ceaf05b12a55c570e6acc0267faf59e9c4d2f032fc833bafcf0597 languageName: node linkType: hard -"@types/unist@npm:^2.0.0": - version: 2.0.11 - resolution: "@types/unist@npm:2.0.11" - checksum: 6d436e832bc35c6dde9f056ac515ebf2b3384a1d7f63679d12358766f9b313368077402e9c1126a14d827f10370a5485e628bf61aa91117cf4fc882423191a4e +"@types/testing-library__jest-dom@npm:^5.9.1": + version: 5.14.9 + resolution: "@types/testing-library__jest-dom@npm:5.14.9" + dependencies: + "@types/jest": "*" + checksum: d364494fc2545316292e88861146146af1e3818792ca63b62a63758b2f737669b687f4aaddfcfbcb7d0e1ed7890a9bd05de23ff97f277d5e68de574497a9ee72 languageName: node linkType: hard -"@types/use-sync-external-store@npm:^0.0.6": - version: 0.0.6 - resolution: "@types/use-sync-external-store@npm:0.0.6" - checksum: a95ce330668501ad9b1c5b7f2b14872ad201e552a0e567787b8f1588b22c7040c7c3d80f142cbb9f92d13c4ea41c46af57a20f2af4edf27f224d352abcfe4049 +"@types/uglify-js@npm:*": + version: 3.17.5 + resolution: "@types/uglify-js@npm:3.17.5" + dependencies: + source-map: ^0.6.1 + checksum: ffed5d63637c6ea5c155469121ee40d9b652e677e6d9eb07b72ff72bb4029ffad19049a0af6e91a5021bad6c481cff2572fbf6367e319c6885cf1537c20d861d languageName: node linkType: hard -"@types/uuid@npm:^10.0.0": - version: 10.0.0 - resolution: "@types/uuid@npm:10.0.0" - checksum: e3958f8b0fe551c86c14431f5940c3470127293280830684154b91dc7eb3514aeb79fe3216968833cf79d4d1c67f580f054b5be2cd562bebf4f728913e73e944 +"@types/unist@npm:^2, @types/unist@npm:^2.0.0, @types/unist@npm:^2.0.2, @types/unist@npm:^2.0.3": + version: 2.0.10 + resolution: "@types/unist@npm:2.0.10" + checksum: e2924e18dedf45f68a5c6ccd6015cd62f1643b1b43baac1854efa21ae9e70505db94290434a23da1137d9e31eb58e54ca175982005698ac37300a1c889f6c4aa languageName: node linkType: hard -"@types/uuid@npm:^9.0.1": - version: 9.0.8 - resolution: "@types/uuid@npm:9.0.8" - checksum: b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 +"@types/webpack-sources@npm:*": + version: 3.2.3 + resolution: "@types/webpack-sources@npm:3.2.3" + dependencies: + "@types/node": "*" + "@types/source-list-map": "*" + source-map: ^0.7.3 + checksum: 7b557f242efaa10e4e3e18cc4171a0c98e22898570caefdd4f7b076fe8534b5abfac92c953c6604658dcb7218507f970230352511840fe9fdea31a9af3b9a906 languageName: node linkType: hard -"@types/ws@npm:^8.5.5": - version: 8.18.1 - resolution: "@types/ws@npm:8.18.1" +"@types/webpack@npm:^4.41.8": + version: 4.41.38 + resolution: "@types/webpack@npm:4.41.38" dependencies: "@types/node": "*" - checksum: 0331b14cde388e2805af66cad3e3f51857db8e68ed91e5b99750915e96fe7572e58296dc99999331bbcf08f0ff00a227a0bb214e991f53c2a5aca7b0e71173fa + "@types/tapable": ^1 + "@types/uglify-js": "*" + "@types/webpack-sources": "*" + anymatch: ^3.0.0 + source-map: ^0.6.0 + checksum: d3de65993ef3a7621f75548c2f6f509e8f87f586032238e999743d6067030655c67e38ec5f8b32e04fa5276c83bdfb7a761773bce0e6f28605da87e3fc388e3e languageName: node linkType: hard @@ -6447,7 +4083,7 @@ __metadata: languageName: node linkType: hard -"@types/yargs@npm:^15.0.4": +"@types/yargs@npm:^15.0.0": version: 15.0.19 resolution: "@types/yargs@npm:15.0.19" dependencies: @@ -6456,603 +4092,418 @@ __metadata: languageName: node linkType: hard -"@types/yargs@npm:^16.0.0": - version: 16.0.9 - resolution: "@types/yargs@npm:16.0.9" - dependencies: - "@types/yargs-parser": "*" - checksum: 00d9276ed4e0f17a78c1ed57f644a8c14061959bd5bfab113d57f082ea4b663ba97f71b89371304a34a2dba5061e9ae4523e357e577ba61834d661f82c223bf8 - languageName: node - linkType: hard - "@types/yargs@npm:^17.0.8": - version: 17.0.33 - resolution: "@types/yargs@npm:17.0.33" + version: 17.0.32 + resolution: "@types/yargs@npm:17.0.32" dependencies: "@types/yargs-parser": "*" - checksum: ee013f257472ab643cb0584cf3e1ff9b0c44bca1c9ba662395300a7f1a6c55fa9d41bd40ddff42d99f5d95febb3907c9ff600fbcb92dadbec22c6a76de7e1236 - languageName: node - linkType: hard - -"@typescript-eslint/eslint-plugin@npm:8.20.0": - version: 8.20.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.20.0" - dependencies: - "@eslint-community/regexpp": ^4.10.0 - "@typescript-eslint/scope-manager": 8.20.0 - "@typescript-eslint/type-utils": 8.20.0 - "@typescript-eslint/utils": 8.20.0 - "@typescript-eslint/visitor-keys": 8.20.0 - graphemer: ^1.4.0 - ignore: ^5.3.1 - natural-compare: ^1.4.0 - ts-api-utils: ^2.0.0 - peerDependencies: - "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: f029bfcce3dc12d7b539f86142857d680e06d798eca213d9fb564685d12b479205b7f40b4996e30e3f7301c7bb6d15484741352f54ddd00d74a07ea2aca53cf6 + checksum: 4505bdebe8716ff383640c6e928f855b5d337cb3c68c81f7249fc6b983d0aa48de3eee26062b84f37e0d75a5797bc745e0c6e76f42f81771252a758c638f36ba languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^5.5.0": - version: 5.62.0 - resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" +"@typescript-eslint/eslint-plugin@npm:^4.18.0, @typescript-eslint/eslint-plugin@npm:^4.5.0": + version: 4.33.0 + resolution: "@typescript-eslint/eslint-plugin@npm:4.33.0" dependencies: - "@eslint-community/regexpp": ^4.4.0 - "@typescript-eslint/scope-manager": 5.62.0 - "@typescript-eslint/type-utils": 5.62.0 - "@typescript-eslint/utils": 5.62.0 - debug: ^4.3.4 - graphemer: ^1.4.0 - ignore: ^5.2.0 - natural-compare-lite: ^1.4.0 - semver: ^7.3.7 + "@typescript-eslint/experimental-utils": 4.33.0 + "@typescript-eslint/scope-manager": 4.33.0 + debug: ^4.3.1 + functional-red-black-tree: ^1.0.1 + ignore: ^5.1.8 + regexpp: ^3.1.0 + semver: ^7.3.5 tsutils: ^3.21.0 peerDependencies: - "@typescript-eslint/parser": ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + "@typescript-eslint/parser": ^4.0.0 + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: typescript: optional: true - checksum: fc104b389c768f9fa7d45a48c86d5c1ad522c1d0512943e782a56b1e3096b2cbcc1eea3fcc590647bf0658eef61aac35120a9c6daf979bf629ad2956deb516a1 + checksum: d74855d0a5ffe0b2f362ec02fcd9301d39a53fb4155b9bd0cb15a0a31d065143129ebf98df9d86af4b6f74de1d423a4c0d8c0095520844068117453afda5bc4f languageName: node linkType: hard -"@typescript-eslint/experimental-utils@npm:^5.0.0": - version: 5.62.0 - resolution: "@typescript-eslint/experimental-utils@npm:5.62.0" +"@typescript-eslint/experimental-utils@npm:4.33.0, @typescript-eslint/experimental-utils@npm:^4.0.1": + version: 4.33.0 + resolution: "@typescript-eslint/experimental-utils@npm:4.33.0" dependencies: - "@typescript-eslint/utils": 5.62.0 + "@types/json-schema": ^7.0.7 + "@typescript-eslint/scope-manager": 4.33.0 + "@typescript-eslint/types": 4.33.0 + "@typescript-eslint/typescript-estree": 4.33.0 + eslint-scope: ^5.1.1 + eslint-utils: ^3.0.0 peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: ce55d9f74eac5cb94d66d5db9ead9a5d734f4301519fb5956a57f4b405a5318a115b0316195a3c039e0111489138680411709cb769085d71e1e1db1376ea0949 + eslint: "*" + checksum: f859800ada0884f92db6856f24efcb1d073ac9883ddc2b1aa9339f392215487895bed8447ebce3741e8141bb32e545244abef62b73193ba9a8a0527c523aabae languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.20.0": - version: 8.20.0 - resolution: "@typescript-eslint/parser@npm:8.20.0" +"@typescript-eslint/experimental-utils@npm:^3.10.1": + version: 3.10.1 + resolution: "@typescript-eslint/experimental-utils@npm:3.10.1" dependencies: - "@typescript-eslint/scope-manager": 8.20.0 - "@typescript-eslint/types": 8.20.0 - "@typescript-eslint/typescript-estree": 8.20.0 - "@typescript-eslint/visitor-keys": 8.20.0 - debug: ^4.3.4 + "@types/json-schema": ^7.0.3 + "@typescript-eslint/types": 3.10.1 + "@typescript-eslint/typescript-estree": 3.10.1 + eslint-scope: ^5.0.0 + eslint-utils: ^2.0.0 peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 00b265ed42ee1d8eb715f9978d701be0958baf7a5be9de74a1b58c09c78e3558e1e6352c4476ec8ea376c28f1437de0b58b3e1e2a9975c489f2ecd369a9050eb + eslint: "*" + checksum: 635cc1afe466088b04901c2bce0e4c3e48bb74668e61e39aa74a485f856c6f9683482350d4b16b3f4c0112ce40cad2c2c427d4fe5e11a3329b3bb93286d4ab26 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.5.0": - version: 5.62.0 - resolution: "@typescript-eslint/parser@npm:5.62.0" +"@typescript-eslint/parser@npm:^4.18.0, @typescript-eslint/parser@npm:^4.5.0": + version: 4.33.0 + resolution: "@typescript-eslint/parser@npm:4.33.0" dependencies: - "@typescript-eslint/scope-manager": 5.62.0 - "@typescript-eslint/types": 5.62.0 - "@typescript-eslint/typescript-estree": 5.62.0 - debug: ^4.3.4 + "@typescript-eslint/scope-manager": 4.33.0 + "@typescript-eslint/types": 4.33.0 + "@typescript-eslint/typescript-estree": 4.33.0 + debug: ^4.3.1 peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: typescript: optional: true - checksum: d168f4c7f21a7a63f47002e2d319bcbb6173597af5c60c1cf2de046b46c76b4930a093619e69faf2d30214c29ab27b54dcf1efc7046a6a6bd6f37f59a990e752 + checksum: 102457eae1acd516211098fea081c8a2ed728522bbda7f5a557b6ef23d88970514f9a0f6285d53fca134d3d4d7d17822b5d5e12438d5918df4d1f89cc9e67d57 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/scope-manager@npm:5.62.0" +"@typescript-eslint/scope-manager@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/scope-manager@npm:4.33.0" dependencies: - "@typescript-eslint/types": 5.62.0 - "@typescript-eslint/visitor-keys": 5.62.0 - checksum: 6062d6b797fe1ce4d275bb0d17204c827494af59b5eaf09d8a78cdd39dadddb31074dded4297aaf5d0f839016d601032857698b0e4516c86a41207de606e9573 + "@typescript-eslint/types": 4.33.0 + "@typescript-eslint/visitor-keys": 4.33.0 + checksum: 9a25fb7ba7c725ea7227a24d315b0f6aacbad002e2549a049edf723c1d3615c22f5c301f0d7d615b377f2cdf2f3519d97e79af0c459de6ef8d2aaf0906dff13e languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.20.0": - version: 8.20.0 - resolution: "@typescript-eslint/scope-manager@npm:8.20.0" - dependencies: - "@typescript-eslint/types": 8.20.0 - "@typescript-eslint/visitor-keys": 8.20.0 - checksum: d90d89f3dc8394e44652526b88c81a977b251702a9dc5be89ac0bf7412d79d18879e03c2d6018980a09bc7c50d28dbf91ba06e056e081e6000783d69bd280761 +"@typescript-eslint/types@npm:3.10.1": + version: 3.10.1 + resolution: "@typescript-eslint/types@npm:3.10.1" + checksum: 3ea820d37c2595d457acd6091ffda8b531e5d916e1cce708336bf958aa8869126f95cca3268a724f453ce13be11c5388a0a4143bf09bca51be1020ec46635d92 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/type-utils@npm:5.62.0" - dependencies: - "@typescript-eslint/typescript-estree": 5.62.0 - "@typescript-eslint/utils": 5.62.0 - debug: ^4.3.4 - tsutils: ^3.21.0 - peerDependencies: - eslint: "*" - peerDependenciesMeta: - typescript: - optional: true - checksum: fc41eece5f315dfda14320be0da78d3a971d650ea41300be7196934b9715f3fe1120a80207551eb71d39568275dbbcf359bde540d1ca1439d8be15e9885d2739 +"@typescript-eslint/types@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/types@npm:4.33.0" + checksum: 3baae1ca35872421b4eb60f5d3f3f32dc1d513f2ae0a67dee28c7d159fd7a43ed0d11a8a5a0f0c2d38507ffa036fc7c511cb0f18a5e8ac524b3ebde77390ec53 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.20.0": - version: 8.20.0 - resolution: "@typescript-eslint/type-utils@npm:8.20.0" +"@typescript-eslint/typescript-estree@npm:3.10.1": + version: 3.10.1 + resolution: "@typescript-eslint/typescript-estree@npm:3.10.1" dependencies: - "@typescript-eslint/typescript-estree": 8.20.0 - "@typescript-eslint/utils": 8.20.0 - debug: ^4.3.4 - ts-api-utils: ^2.0.0 - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 705a166dc2846f7fe79a123ee623da213a20289fba9c0cbbcc894fe7caaa1d4ddc81bf54db9dc918c29a34294a05768c38a4f00762ba3745e0e94e2e2963f104 - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/types@npm:5.62.0" - checksum: 48c87117383d1864766486f24de34086155532b070f6264e09d0e6139449270f8a9559cfef3c56d16e3bcfb52d83d42105d61b36743626399c7c2b5e0ac3b670 - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:8.20.0": - version: 8.20.0 - resolution: "@typescript-eslint/types@npm:8.20.0" - checksum: 4cb0af48411f282db33e7110e2f97de874c637e7b90ded91b77304e96f49663ca4b7308afc569bdd93766fe5f2c194686e32078d5513b5ba4e7d56191998190c + "@typescript-eslint/types": 3.10.1 + "@typescript-eslint/visitor-keys": 3.10.1 + debug: ^4.1.1 + glob: ^7.1.6 + is-glob: ^4.0.1 + lodash: ^4.17.15 + semver: ^7.3.2 + tsutils: ^3.17.1 + peerDependenciesMeta: + typescript: + optional: true + checksum: 911680da9d26220944f4f8f26f88349917609844fafcff566147cecae37ff0211d66c626eb62a2b24d17fd50d10715f5b0f32b2e7f5d9a88efc46709266d5053 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" +"@typescript-eslint/typescript-estree@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/typescript-estree@npm:4.33.0" dependencies: - "@typescript-eslint/types": 5.62.0 - "@typescript-eslint/visitor-keys": 5.62.0 - debug: ^4.3.4 - globby: ^11.1.0 - is-glob: ^4.0.3 - semver: ^7.3.7 + "@typescript-eslint/types": 4.33.0 + "@typescript-eslint/visitor-keys": 4.33.0 + debug: ^4.3.1 + globby: ^11.0.3 + is-glob: ^4.0.1 + semver: ^7.3.5 tsutils: ^3.21.0 peerDependenciesMeta: typescript: optional: true - checksum: 3624520abb5807ed8f57b1197e61c7b1ed770c56dfcaca66372d584ff50175225798bccb701f7ef129d62c5989070e1ee3a0aa2d84e56d9524dcf011a2bb1a52 - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:8.20.0": - version: 8.20.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.20.0" - dependencies: - "@typescript-eslint/types": 8.20.0 - "@typescript-eslint/visitor-keys": 8.20.0 - debug: ^4.3.4 - fast-glob: ^3.3.2 - is-glob: ^4.0.3 - minimatch: ^9.0.4 - semver: ^7.6.0 - ts-api-utils: ^2.0.0 - peerDependencies: - typescript: ">=4.8.4 <5.8.0" - checksum: 9690df2d4ec90966b8d5752ad0f1658a951fe76ea3cae8e6935e698715a25c1eb0b118fa8e044065f04ea9f6bef41d991de5298590ef2a4aa98d435bf1df6e15 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:5.62.0, @typescript-eslint/utils@npm:^5.58.0": - version: 5.62.0 - resolution: "@typescript-eslint/utils@npm:5.62.0" - dependencies: - "@eslint-community/eslint-utils": ^4.2.0 - "@types/json-schema": ^7.0.9 - "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.62.0 - "@typescript-eslint/types": 5.62.0 - "@typescript-eslint/typescript-estree": 5.62.0 - eslint-scope: ^5.1.1 - semver: ^7.3.7 - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: ee9398c8c5db6d1da09463ca7bf36ed134361e20131ea354b2da16a5fdb6df9ba70c62a388d19f6eebb421af1786dbbd79ba95ddd6ab287324fc171c3e28d931 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:8.20.0": - version: 8.20.0 - resolution: "@typescript-eslint/utils@npm:8.20.0" - dependencies: - "@eslint-community/eslint-utils": ^4.4.0 - "@typescript-eslint/scope-manager": 8.20.0 - "@typescript-eslint/types": 8.20.0 - "@typescript-eslint/typescript-estree": 8.20.0 - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 5c9d72eb0d4014e41de1faa4597371f19362ce47a491359be408bfba899277f8d5660f014651f7bd41435158ae4655ade205e92f175e2355ca51a07af35a53ed + checksum: 2566984390c76bd95f43240057215c068c69769e406e27aba41e9f21fd300074d6772e4983fa58fe61e80eb5550af1548d2e31e80550d92ba1d051bb00fe6f5c languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" +"@typescript-eslint/visitor-keys@npm:3.10.1": + version: 3.10.1 + resolution: "@typescript-eslint/visitor-keys@npm:3.10.1" dependencies: - "@typescript-eslint/types": 5.62.0 - eslint-visitor-keys: ^3.3.0 - checksum: 976b05d103fe8335bef5c93ad3f76d781e3ce50329c0243ee0f00c0fcfb186c81df50e64bfdd34970148113f8ade90887f53e3c4938183afba830b4ba8e30a35 + eslint-visitor-keys: ^1.1.0 + checksum: 0c4825b9829b1c11258a73aaee70d64834ba6d9b24157e7624e80f27f6537f468861d4dd33ad233c13ad2c6520afb9008c0675da6d792f26e82d75d6bfe9b0c6 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.20.0": - version: 8.20.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.20.0" +"@typescript-eslint/visitor-keys@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/visitor-keys@npm:4.33.0" dependencies: - "@typescript-eslint/types": 8.20.0 - eslint-visitor-keys: ^4.2.0 - checksum: d0bf89e431a686197c517fbb7d63ce4c8ef31e6629a545fd08198c67810ddd68c047c01fcfed8ffc3fe438654a2647b3dedf28f04beac23a65614b2e788d929a - languageName: node - linkType: hard - -"@ungap/structured-clone@npm:^1.0.0, @ungap/structured-clone@npm:^1.2.0": - version: 1.3.0 - resolution: "@ungap/structured-clone@npm:1.3.0" - checksum: 64ed518f49c2b31f5b50f8570a1e37bde3b62f2460042c50f132430b2d869c4a6586f13aa33a58a4722715b8158c68cae2827389d6752ac54da2893c83e480fc + "@typescript-eslint/types": 4.33.0 + eslint-visitor-keys: ^2.0.0 + checksum: 59953e474ad4610c1aa23b2b1a964445e2c6201521da6367752f37939d854352bbfced5c04ea539274065e012b1337ba3ffa49c2647a240a4e87155378ba9873 languageName: node linkType: hard "@vitejs/plugin-react@npm:^4.0.0": - version: 4.7.0 - resolution: "@vitejs/plugin-react@npm:4.7.0" + version: 4.2.1 + resolution: "@vitejs/plugin-react@npm:4.2.1" dependencies: - "@babel/core": ^7.28.0 - "@babel/plugin-transform-react-jsx-self": ^7.27.1 - "@babel/plugin-transform-react-jsx-source": ^7.27.1 - "@rolldown/pluginutils": 1.0.0-beta.27 + "@babel/core": ^7.23.5 + "@babel/plugin-transform-react-jsx-self": ^7.23.3 + "@babel/plugin-transform-react-jsx-source": ^7.23.3 "@types/babel__core": ^7.20.5 - react-refresh: ^0.17.0 + react-refresh: ^0.14.0 peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 3e3c4c58f65e8041c4891736613732d572f232bc6b039e74ea00554b94b8010ac246e2f6e099e8b6c474d9c1741e2b166b48fa47fe0093312beefa99a1b13d00 + vite: ^4.2.0 || ^5.0.0 + checksum: 08d227d27ff2304e395e746bd2d4b5fee40587f69d7e2fcd6beb7d91163c1f1dc26d843bc48e2ffb8f38c6b8a1b9445fb07840e3dcc841f97b56bbb8205346aa languageName: node linkType: hard -"@vitest/expect@npm:2.1.9": - version: 2.1.9 - resolution: "@vitest/expect@npm:2.1.9" +"@vitest/expect@npm:0.32.4": + version: 0.32.4 + resolution: "@vitest/expect@npm:0.32.4" dependencies: - "@vitest/spy": 2.1.9 - "@vitest/utils": 2.1.9 - chai: ^5.1.2 - tinyrainbow: ^1.2.0 - checksum: a234f96dd42c76e20af68b2ad2f00b80a3873501d5daa524bf1405b344e86123716b925f976d8104fd242bfbd0d9cf7084d0eb4a690097e6e5db456d220ed67a + "@vitest/spy": 0.32.4 + "@vitest/utils": 0.32.4 + chai: ^4.3.7 + checksum: fb44ae0507c3a0298e472e64f4d298f60b159c7ce05201987cbd60ba6b11069a97bed5f689f911ac66096ee573c64ed0c17a2511661ad7823ce31a86244b8cd8 languageName: node linkType: hard -"@vitest/expect@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/expect@npm:3.2.4" +"@vitest/runner@npm:0.32.4": + version: 0.32.4 + resolution: "@vitest/runner@npm:0.32.4" dependencies: - "@types/chai": ^5.2.2 - "@vitest/spy": 3.2.4 - "@vitest/utils": 3.2.4 - chai: ^5.2.0 - tinyrainbow: ^2.0.0 - checksum: 57627ee2b47555f47a15843fda05267816e9767e5a769179acac224b8682844e662fa77fbeeb04adcb0874779f3aca861f54e9fc630c1d256d5ea8211c223120 + "@vitest/utils": 0.32.4 + p-limit: ^4.0.0 + pathe: ^1.1.1 + checksum: 06f2b4003963a7f18954bcd690ebd3b917e1d45d998a8c9a23458569a8ae9b50a18fcf511ac100343eeddf1df1e47f8eba870e193afa895ccb348a679e5295de languageName: node linkType: hard -"@vitest/mocker@npm:2.1.9": - version: 2.1.9 - resolution: "@vitest/mocker@npm:2.1.9" +"@vitest/snapshot@npm:0.32.4": + version: 0.32.4 + resolution: "@vitest/snapshot@npm:0.32.4" dependencies: - "@vitest/spy": 2.1.9 - estree-walker: ^3.0.3 - magic-string: ^0.30.12 - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - checksum: 17de391acc4d899f15356b45cde8202e5d5ca4517c32c0c9dcf32ce0660501773fdc29675b4f7d48c1579a560ac41f8f5181ebe41a7daf675f561d611e8e30dc + magic-string: ^0.30.0 + pathe: ^1.1.1 + pretty-format: ^29.5.0 + checksum: d8907fc0504acfb59df88aaf43a210161f7e2f22eaaa96c6562b7a1c9e28b12d2b572afcd49ae224a8a9947fabf473e956c7ea7c7d25f794d5521d7d45f24b78 languageName: node linkType: hard -"@vitest/mocker@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/mocker@npm:3.2.4" +"@vitest/spy@npm:0.32.4": + version: 0.32.4 + resolution: "@vitest/spy@npm:0.32.4" dependencies: - "@vitest/spy": 3.2.4 - estree-walker: ^3.0.3 - magic-string: ^0.30.17 - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - checksum: 2c8ba286fc714036b645a7a72bfbbd6b243baa65320dd71009f5ed1115f70f69c0209e2e213a05202c172e09a408821a33f9df5bc7979900e91cde5d302976e0 + tinyspy: ^2.1.1 + checksum: 742870e7554dd8d478de85bc265c3af051e1f3420093fdc9978fe9871472db37da6da69c66d80ad604029d1dfdc303f1159613d9ccf08dba1c3991eb4e7616a7 languageName: node linkType: hard -"@vitest/pretty-format@npm:2.1.9, @vitest/pretty-format@npm:^2.1.9": - version: 2.1.9 - resolution: "@vitest/pretty-format@npm:2.1.9" +"@vitest/utils@npm:0.32.4": + version: 0.32.4 + resolution: "@vitest/utils@npm:0.32.4" dependencies: - tinyrainbow: ^1.2.0 - checksum: 33f7ff0a9d356ddd6534390a0aea260dc04a3022a94901c87d141bacf71d2b3fff2e3bf08a55dd424c5355fd3b41656cb7871c76372fef45ffac1ea89d0dc508 + diff-sequences: ^29.4.3 + loupe: ^2.3.6 + pretty-format: ^29.5.0 + checksum: 7d81162c3afaa638d30c47a28b7eced62abb8d7a8c891b10fa2f9756b2b6609d767142162044fe976c2cb8c17911d135fb3950f83e6d2bbd90150a042237bd25 languageName: node linkType: hard -"@vitest/pretty-format@npm:3.2.4, @vitest/pretty-format@npm:^3.2.4": - version: 3.2.4 - resolution: "@vitest/pretty-format@npm:3.2.4" +"@webassemblyjs/ast@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/ast@npm:1.9.0" dependencies: - tinyrainbow: ^2.0.0 - checksum: 68a196e4bdfce6fd03c3958b76cddb71bec65a62ab5aff05ba743a44853b03a95c2809b4e5733d21abff25c4d070dd64f60c81ac973a9fd21a840ff8f8a8d184 + "@webassemblyjs/helper-module-context": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/wast-parser": 1.9.0 + checksum: 8a9838dc7fdac358aee8daa75eefa35934ab18dafb594092ff7be79c467ebe9dabb2543e58313c905fd802bdcc3cb8320e4e19af7444e49853a7a24e25138f75 languageName: node linkType: hard -"@vitest/runner@npm:2.1.9": - version: 2.1.9 - resolution: "@vitest/runner@npm:2.1.9" - dependencies: - "@vitest/utils": 2.1.9 - pathe: ^1.1.2 - checksum: d8aaadc98bcbe1ee7c832a7d619d3c77d3c67536f10b80a3106d9d6e03ecc0f5467ef7bd4a65a07fe924cc166fe7415d637b2b08ef71e1a208a250543f9f3545 +"@webassemblyjs/floating-point-hex-parser@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.9.0" + checksum: d3aeb19bc30da26f639698daa28e44e0c18d5aa135359ef3c54148e194eec46451a912d0506099d479a71a94bc3eef6ef52d6ec234799528a25a9744789852de languageName: node linkType: hard -"@vitest/runner@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/runner@npm:3.2.4" - dependencies: - "@vitest/utils": 3.2.4 - pathe: ^2.0.3 - strip-literal: ^3.0.0 - checksum: c8b08365818f408eec2fe3acbffa0cc7279939a43c02074cd03b853fa37bc68aa181c8f8c2175513a4c5aa4dd3e52a0573d5897a16846d55b2ff4f3577e6c7c8 +"@webassemblyjs/helper-api-error@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-api-error@npm:1.9.0" + checksum: 9179d3148639cc202e89a118145b485cf834613260679a99af6ec487bbc15f238566ca713207394b336160a41bf8c1b75cf2e853b3e96f0cc73c1e5c735b3f64 languageName: node linkType: hard -"@vitest/snapshot@npm:2.1.9": - version: 2.1.9 - resolution: "@vitest/snapshot@npm:2.1.9" - dependencies: - "@vitest/pretty-format": 2.1.9 - magic-string: ^0.30.12 - pathe: ^1.1.2 - checksum: fb693dea59709c9df8660e5948c7971d2c3ce74212eafa7d542a578bbb8aed203dc03129dd5e476251e1946b50432e79a4fd59069fd4f950283e188167b9496d +"@webassemblyjs/helper-buffer@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-buffer@npm:1.9.0" + checksum: dcb85f630f8a2e22b7346ad4dd58c3237a2cad1457699423e8fd19592a0bd3eacbc2639178a1b9a873c3ac217bfc7a23a134ff440a099496b590e82c7a4968d5 languageName: node linkType: hard -"@vitest/snapshot@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/snapshot@npm:3.2.4" +"@webassemblyjs/helper-code-frame@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-code-frame@npm:1.9.0" dependencies: - "@vitest/pretty-format": 3.2.4 - magic-string: ^0.30.17 - pathe: ^2.0.3 - checksum: 2f00fb83d5c9ed1f2a79323db3993403bd34265314846cb1bcf1cb9b68f56dfde5ee5a4a8dcb6d95317835bc203662e333da6841e50800c6707e0d22e48ebe6e + "@webassemblyjs/wast-printer": 1.9.0 + checksum: a28fa057f7beff0fd14bff716561520f8edb8c9c56c7a5559451e6765acfb70aaeb8af718ea2bd2262e7baeba597545af407e28eb2eff8329235afe8605f20d1 languageName: node linkType: hard -"@vitest/spy@npm:2.1.9": - version: 2.1.9 - resolution: "@vitest/spy@npm:2.1.9" - dependencies: - tinyspy: ^3.0.2 - checksum: f9279488b5d2a27800e33e8fe51cc685b2a0db49d30b80b2b0cc924f8b1736eb520459c6e8bd09fa4457f5bb86ff073e7bdcf60d36452c11a8a8f9cbc8030237 +"@webassemblyjs/helper-fsm@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-fsm@npm:1.9.0" + checksum: 374cc510c8f5a7a07d4fe9eb7036cc475a96a670b5d25c31f16757ac8295be8d03a2f29657ff53eaefa9e8315670a48824d430ed910e7c1835788ac79f93124e languageName: node linkType: hard -"@vitest/spy@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/spy@npm:3.2.4" +"@webassemblyjs/helper-module-context@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-module-context@npm:1.9.0" dependencies: - tinyspy: ^4.0.3 - checksum: 0e3b591e0c67275b747c5aa67946d6496cd6759dd9b8e05c524426207ca9631fe2cae8ac85a8ba22acec4a593393cd97d825f88a42597fc65441f0b633986f49 + "@webassemblyjs/ast": 1.9.0 + checksum: 55e8f89c7ea1beaa78fad88403f3753b8413b0f3b6bb32d898ce95078b3e1d1b48ade0919c00b82fc2e3813c0ab6901e415f7a4d4fa9be50944e2431adde75a5 languageName: node linkType: hard -"@vitest/utils@npm:2.1.9": - version: 2.1.9 - resolution: "@vitest/utils@npm:2.1.9" - dependencies: - "@vitest/pretty-format": 2.1.9 - loupe: ^3.1.2 - tinyrainbow: ^1.2.0 - checksum: b24fb9c6765801f2e0578ad5c32fadf9541a833301eaed2877a427096cf05214244b361f94eda80be2b9c841f58ae3c67d37dedc5a902b2cb44041979bae4d8f +"@webassemblyjs/helper-wasm-bytecode@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.9.0" + checksum: 280da4df3c556f73a1a02053277f8a4be481de32df4aa21050b015c8f4d27c46af89f0417eb88e486df117e5df4bccffae593f78cb1e79f212d3b3d4f3ed0f04 languageName: node linkType: hard -"@vitest/utils@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/utils@npm:3.2.4" +"@webassemblyjs/helper-wasm-section@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.9.0" dependencies: - "@vitest/pretty-format": 3.2.4 - loupe: ^3.1.4 - tinyrainbow: ^2.0.0 - checksum: 6b0fd0075c23b8e3f17ecf315adc1e565e5a9e7d1b8ad78bbccf2505e399855d176254d974587c00bc4396a0e348bae1380e780a1e7f6b97ea6399a9ab665ba7 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-buffer": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/wasm-gen": 1.9.0 + checksum: b8f7bb45d4194074c82210211a5d3e402a5b5fa63ecae26d2c356ae3978af5a530e91192fb260f32f9d561b18e2828b3da2e2f41c59efadb5f3c6d72446807f0 languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/ast@npm:1.14.1" +"@webassemblyjs/ieee754@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/ieee754@npm:1.9.0" dependencies: - "@webassemblyjs/helper-numbers": 1.13.2 - "@webassemblyjs/helper-wasm-bytecode": 1.13.2 - checksum: f9154ad9ea14f6f2374ebe918c221fd69a4d4514126a1acc6fa4966e8d27ab28cb550a5e6880032cf620e19640578658a7e5a55bd2aad1e3db4e9d598b8f2099 - languageName: node - linkType: hard - -"@webassemblyjs/floating-point-hex-parser@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2" - checksum: e866ec8433f4a70baa511df5e8f2ebcd6c24f4e2cc6274c7c5aabe2bcce3459ea4680e0f35d450e1f3602acf3913b6b8e4f15069c8cfd34ae8609fb9a7d01795 - languageName: node - linkType: hard - -"@webassemblyjs/helper-api-error@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-api-error@npm:1.13.2" - checksum: 48b5df7fd3095bb252f59a139fe2cbd999a62ac9b488123e9a0da3906ad8a2f2da7b2eb21d328c01a90da987380928706395c2897d1f3ed9e2125b6d75a920d0 - languageName: node - linkType: hard - -"@webassemblyjs/helper-buffer@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/helper-buffer@npm:1.14.1" - checksum: b611e981dfd6a797c3d8fc3a772de29a6e55033737c2c09c31bb66c613bdbb2d25f915df1dee62a602c6acc057ca71128432fa8c3e22a893e1219dc454f14ede + "@xtuc/ieee754": ^1.2.0 + checksum: 7fe4a217ba0f7051e2cfef92919d4a64fac1a63c65411763779bd50907820f33f440255231a474fe3ba03bd1d9ee0328662d1eae3fce4c59b91549d6b62b839b languageName: node linkType: hard -"@webassemblyjs/helper-numbers@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-numbers@npm:1.13.2" +"@webassemblyjs/leb128@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/leb128@npm:1.9.0" dependencies: - "@webassemblyjs/floating-point-hex-parser": 1.13.2 - "@webassemblyjs/helper-api-error": 1.13.2 "@xtuc/long": 4.2.2 - checksum: 49e2c9bf9b66997e480f6b44d80f895b3cde4de52ac135921d28e144565edca6903a519f627f4089b5509de1d7f9e5023f0e1a94ff78a36c9e2eb30e7c18ffd2 - languageName: node - linkType: hard - -"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2" - checksum: 8e059e1c1f0294f4fc3df8e4eaff3c5ef6e2e1358f34ebc118eaf5070ed59e56ed7fc92b28be734ebde17c8d662d5d27e06ade686c282445135da083ae11c128 + checksum: 4ca7cbb869530d78d42a414f34ae53249364cb1ecebbfb6ed5d562c2f209fce857502f088822ee82a23876f653a262ddc34ab64e45a7962510a263d39bb3f51a languageName: node linkType: hard -"@webassemblyjs/helper-wasm-section@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1" - 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 - checksum: 0a08d454a63192cd66abf91b6f060ac4b466cef341262246e9dcc828dd4c8536195dea9b46a1244b1eac65b59b8b502164a771a190052a92ff0a0a2ded0f8f53 +"@webassemblyjs/utf8@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/utf8@npm:1.9.0" + checksum: e328a30ac8a503bbd015d32e75176e0dedcb45a21d4be051c25dfe89a00035ca7a6dbd8937b442dd5b4b334de3959d4f5fe0b330037bd226a28b9814cd49e84f languageName: node linkType: hard -"@webassemblyjs/ieee754@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/ieee754@npm:1.13.2" +"@webassemblyjs/wasm-edit@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wasm-edit@npm:1.9.0" dependencies: - "@xtuc/ieee754": ^1.2.0 - checksum: d7e3520baa37a7309fa7db4d73d69fb869878853b1ebd4b168821bd03fcc4c0e1669c06231315b0039035d9a7a462e53de3ad982da4a426a4b0743b5888e8673 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-buffer": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/helper-wasm-section": 1.9.0 + "@webassemblyjs/wasm-gen": 1.9.0 + "@webassemblyjs/wasm-opt": 1.9.0 + "@webassemblyjs/wasm-parser": 1.9.0 + "@webassemblyjs/wast-printer": 1.9.0 + checksum: 1997e0c2f4051c33239587fb143242919320bc861a0af03a873c7150a27d6404bd2e063c658193288b0aa88c35aadbe0c4fde601fe642bae0743a8c8eda52717 languageName: node linkType: hard -"@webassemblyjs/leb128@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/leb128@npm:1.13.2" +"@webassemblyjs/wasm-gen@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wasm-gen@npm:1.9.0" dependencies: - "@xtuc/long": 4.2.2 - checksum: 64083507f7cff477a6d71a9e325d95665cea78ec8df99ca7c050e1cfbe300fbcf0842ca3dcf3b4fa55028350135588a4f879398d3dd2b6a8de9913ce7faf5333 - languageName: node - linkType: hard - -"@webassemblyjs/utf8@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/utf8@npm:1.13.2" - checksum: 95ec6052f30eefa8d50c9b2a3394d08b17d53a4aa52821451d41d774c126fa8f39b988fbf5bff56da86852a87c16d676e576775a4071e5e5ccf020cc85a4b281 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/ieee754": 1.9.0 + "@webassemblyjs/leb128": 1.9.0 + "@webassemblyjs/utf8": 1.9.0 + checksum: 2456e84e8e6bedb7ab47f6333a0ee170f7ef62842c90862ca787c08528ca8041061f3f8bc257fc2a01bf6e8d1a76fddaddd43418c738f681066e5b50f88fe7df languageName: node linkType: hard -"@webassemblyjs/wasm-edit@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-edit@npm:1.14.1" +"@webassemblyjs/wasm-opt@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wasm-opt@npm:1.9.0" 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 - checksum: 9341c3146bb1b7863f03d6050c2a66990f20384ca137388047bbe1feffacb599e94fca7b7c18287d17e2449ffb4005fdc7f41f674a6975af9ad8522756f8ffff + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-buffer": 1.9.0 + "@webassemblyjs/wasm-gen": 1.9.0 + "@webassemblyjs/wasm-parser": 1.9.0 + checksum: 91242205bdbd1aa8045364a5338bfb34880cb2c65f56db8dd19382894209673699fb31a0e5279f25c7e5bcd8f3097d6c9ca84d8969d9613ef2cf166450cc3515 languageName: node linkType: hard -"@webassemblyjs/wasm-gen@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-gen@npm:1.14.1" +"@webassemblyjs/wasm-parser@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wasm-parser@npm:1.9.0" 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 - checksum: 401b12bec7431c4fc29d9414bbe40d3c6dc5be04d25a116657c42329f5481f0129f3b5834c293f26f0e42681ceac9157bf078ce9bdb6a7f78037c650373f98b2 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-api-error": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/ieee754": 1.9.0 + "@webassemblyjs/leb128": 1.9.0 + "@webassemblyjs/utf8": 1.9.0 + checksum: 493f6cfc63a5e16073056c81ff0526a9936f461327379ef3c83cc841000e03623b6352704f6bf9f7cb5b3610f0032020a61f9cca78c91b15b8e995854b29c098 languageName: node linkType: hard -"@webassemblyjs/wasm-opt@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-opt@npm:1.14.1" +"@webassemblyjs/wast-parser@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wast-parser@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.14.1 - "@webassemblyjs/helper-buffer": 1.14.1 - "@webassemblyjs/wasm-gen": 1.14.1 - "@webassemblyjs/wasm-parser": 1.14.1 - checksum: 60c697a9e9129d8d23573856df0791ba33cea4a3bc2339044cae73128c0983802e5e50a42157b990eeafe1237eb8e7653db6de5f02b54a0ae7b81b02dcdf2ae9 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/floating-point-hex-parser": 1.9.0 + "@webassemblyjs/helper-api-error": 1.9.0 + "@webassemblyjs/helper-code-frame": 1.9.0 + "@webassemblyjs/helper-fsm": 1.9.0 + "@xtuc/long": 4.2.2 + checksum: 705dd48fbbceec7f6bed299b8813631b242fd9312f9594dbb2985dda86c9688048692357d684f6080fc2c5666287cefaa26b263d01abadb6a9049d4c8978b9db languageName: node linkType: hard -"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-parser@npm:1.14.1" +"@webassemblyjs/wast-printer@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wast-printer@npm:1.9.0" 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 - checksum: 93f1fe2676da465b4e824419d9812a3d7218de4c3addd4e916c04bc86055fa134416c1b67e4b7cbde8d728c0dce2721d06cc0bfe7a7db7c093a0898009937405 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/wast-parser": 1.9.0 + "@xtuc/long": 4.2.2 + checksum: 3d1e1b2e84745a963f69acd1c02425b321dd2e608e11dabc467cae0c9a808962bc769ec9afc46fbcea7188cc1e47d72370da762d258f716fb367cb1a7865c54b languageName: node linkType: hard -"@webassemblyjs/wast-printer@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wast-printer@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": 1.14.1 - "@xtuc/long": 4.2.2 - checksum: 517881a0554debe6945de719d100b2d8883a2d24ddf47552cdeda866341e2bb153cd824a864bc7e2a61190a4b66b18f9899907e0074e9e820d2912ac0789ea60 +"@xmldom/xmldom@npm:^0.8.3": + version: 0.8.10 + resolution: "@xmldom/xmldom@npm:0.8.10" + checksum: 4c136aec31fb3b49aaa53b6fcbfe524d02a1dc0d8e17ee35bd3bf35e9ce1344560481cd1efd086ad1a4821541482528672306d5e37cdbd187f33d7fadd3e2cf0 languageName: node linkType: hard @@ -7070,6 +4521,13 @@ __metadata: languageName: node linkType: hard +"@zxing/text-encoding@npm:0.9.0": + version: 0.9.0 + resolution: "@zxing/text-encoding@npm:0.9.0" + checksum: c23b12aee7639382e4949961304a1294776afaffa40f579e09ffecd0e5e68cf26ef3edd75009de46da8a536e571448755ca68b3e2ea707d53793c0edb2e2c34a + languageName: node + linkType: hard + "abab@npm:^2.0.3, abab@npm:^2.0.5": version: 2.0.6 resolution: "abab@npm:2.0.6" @@ -7077,24 +4535,21 @@ __metadata: languageName: node linkType: hard -"abbrev@npm:^3.0.0": - version: 3.0.1 - resolution: "abbrev@npm:3.0.1" - checksum: e70b209f5f408dd3a3bbd0eec4b10a2ffd64704a4a3821d0969d84928cc490a8eb60f85b78a95622c1841113edac10161c62e52f5e7d0027aa26786a8136e02e +"abbrev@npm:1": + version: 1.1.1 + resolution: "abbrev@npm:1.1.1" + checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17 languageName: node linkType: hard -"accepts@npm:^2.0.0": +"abbrev@npm:^2.0.0": version: 2.0.0 - resolution: "accepts@npm:2.0.0" - dependencies: - mime-types: ^3.0.0 - negotiator: ^1.0.0 - checksum: 49fe6c050cb6f6ff4e771b4d88324fca4d3127865f2473872e818dca127d809ba3aa8fdfc7acb51dd3c5bade7311ca6b8cfff7015ea6db2f7eb9c8444d223a4f + resolution: "abbrev@npm:2.0.0" + checksum: 0e994ad2aa6575f94670d8a2149afe94465de9cedaaaac364e7fb43a40c3691c980ff74899f682f4ca58fa96b4cbd7421a015d3a6defe43a442117d7821a2f36 languageName: node linkType: hard -"accepts@npm:~1.3.4, accepts@npm:~1.3.8": +"accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -7114,16 +4569,7 @@ __metadata: languageName: node linkType: hard -"acorn-import-phases@npm:^1.0.3": - version: 1.0.4 - resolution: "acorn-import-phases@npm:1.0.4" - peerDependencies: - acorn: ^8.14.0 - checksum: e669cccfb6711af305150fcbfddcf4485fffdc4547a0ecabebe94103b47124cc02bfd186240061c00ac954cfb0461b4ecc3e203e138e43042b7af32063fa9510 - languageName: node - linkType: hard - -"acorn-jsx@npm:^5.3.1, acorn-jsx@npm:^5.3.2": +"acorn-jsx@npm:^5.3.1": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" peerDependencies: @@ -7139,16 +4585,23 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.1.1": - version: 8.3.4 - resolution: "acorn-walk@npm:8.3.4" - dependencies: - acorn: ^8.11.0 - checksum: 4ff03f42323e7cf90f1683e08606b0f460e1e6ac263d2730e3df91c7665b6f64e696db6ea27ee4bed18c2599569be61f28a8399fa170c611161a348c402ca19c +"acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.2.0": + version: 8.3.2 + resolution: "acorn-walk@npm:8.3.2" + checksum: 3626b9d26a37b1b427796feaa5261faf712307a8920392c8dce9a5739fb31077667f4ad2ec71c7ac6aaf9f61f04a9d3d67ff56f459587206fc04aa31c27ef392 + languageName: node + linkType: hard + +"acorn@npm:^6.4.1": + version: 6.4.2 + resolution: "acorn@npm:6.4.2" + bin: + acorn: bin/acorn + checksum: 44b07053729db7f44d28343eed32247ed56dc4a6ec6dff2b743141ecd6b861406bbc1c20bf9d4f143ea7dd08add5dc8c290582756539bc03a8db605050ce2fb4 languageName: node linkType: hard -"acorn@npm:^7.1.1, acorn@npm:^7.4.0": +"acorn@npm:^7.1.0, acorn@npm:^7.1.1, acorn@npm:^7.4.0": version: 7.4.1 resolution: "acorn@npm:7.4.1" bin: @@ -7157,29 +4610,36 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.9.0": - version: 8.15.0 - resolution: "acorn@npm:8.15.0" +"acorn@npm:^8.10.0, acorn@npm:^8.11.3, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.5.0, acorn@npm:^8.8.2, acorn@npm:^8.9.0": + version: 8.11.3 + resolution: "acorn@npm:8.11.3" bin: acorn: bin/acorn - checksum: 309c6b49aedf1a2e34aaf266de06de04aab6eb097c02375c66fdeb0f64556a6a823540409914fb364d9a11bc30d79d485a2eba29af47992d3490e9886c4391c3 + checksum: 76d8e7d559512566b43ab4aadc374f11f563f0a9e21626dd59cb2888444e9445923ae9f3699972767f18af61df89cd89f5eaaf772d1327b055b45cb829b4a88c + languageName: node + linkType: hard + +"address@npm:1.1.2": + version: 1.1.2 + resolution: "address@npm:1.1.2" + checksum: d966deee6ab9a0f96ed1d25dc73e91a248f64479c91f9daeb15237b8e3c39a02faac4e6afe8987ef9e5aea60a1593cef5882b7456ab2e6196fc0229a93ec39c2 languageName: node linkType: hard -"address@npm:^1.0.1, address@npm:^1.1.2": +"address@npm:^1.0.1": version: 1.2.2 resolution: "address@npm:1.2.2" checksum: ace439960c1e3564d8f523aff23a841904bf33a2a7c2e064f7f60a064194075758b9690e65bd9785692a4ef698a998c57eb74d145881a1cecab8ba658ddb1607 languageName: node linkType: hard -"adjust-sourcemap-loader@npm:^4.0.0": - version: 4.0.0 - resolution: "adjust-sourcemap-loader@npm:4.0.0" +"adjust-sourcemap-loader@npm:3.0.0": + version: 3.0.0 + resolution: "adjust-sourcemap-loader@npm:3.0.0" dependencies: loader-utils: ^2.0.0 regex-parser: ^2.2.11 - checksum: d524ae23582f41e2275af5d88faab7a9dc09770ed588244e0a76d3196d0d6a90bf02760c71bc6213dbfef3aef4a86232ac9521bfd629752c32b7af37bc74c660 + checksum: 5ceabea85219fcafed06f7d1aafb37dc761c6435e4ded2a8c6b01c69844250aa94ef65a4d07210dc7566c2d8b4c9ba8897518db596a550461eed26fbeb76b96f languageName: node linkType: hard @@ -7192,28 +4652,35 @@ __metadata: languageName: node linkType: hard -"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": - version: 7.1.4 - resolution: "agent-base@npm:7.1.4" - checksum: 86a7f542af277cfbd77dd61e7df8422f90bac512953709003a1c530171a9d019d072e2400eab2b59f84b49ab9dd237be44315ca663ac73e82b3922d10ea5eafa +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: ^4.3.4 + checksum: 51c158769c5c051482f9ca2e6e1ec085ac72b5a418a9b31b4e82fe6c0a6699adb94c1c42d246699a587b3335215037091c79e0de512c516f73b6ea844202f037 languageName: node linkType: hard -"ajv-formats@npm:^2.1.1": - version: 2.1.1 - resolution: "ajv-formats@npm:2.1.1" +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" dependencies: - ajv: ^8.0.0 + clean-stack: ^2.0.0 + indent-string: ^4.0.0 + checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ajv-errors@npm:^1.0.0": + version: 1.0.1 + resolution: "ajv-errors@npm:1.0.1" peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - checksum: 4a287d937f1ebaad4683249a4c40c0fa3beed30d9ddc0adba04859026a622da0d317851316ea64b3680dc60f5c3c708105ddd5d5db8fe595d9d0207fd19f90b7 + ajv: ">=5.0.0" + checksum: 2c9fc02cf58f9aae5bace61ebd1b162e1ea372ae9db5999243ba5e32a9a78c0d635d29ae085f652c61c941a43af0b2b1acdb255e29d44dc43a6e021085716d8c languageName: node linkType: hard -"ajv-keywords@npm:^3.4.1, ajv-keywords@npm:^3.5.2": +"ajv-keywords@npm:^3.1.0, ajv-keywords@npm:^3.4.1, ajv-keywords@npm:^3.5.2": version: 3.5.2 resolution: "ajv-keywords@npm:3.5.2" peerDependencies: @@ -7222,18 +4689,7 @@ __metadata: languageName: node linkType: hard -"ajv-keywords@npm:^5.1.0": - version: 5.1.0 - resolution: "ajv-keywords@npm:5.1.0" - dependencies: - fast-deep-equal: ^3.1.3 - peerDependencies: - ajv: ^8.8.2 - checksum: c35193940b853119242c6757787f09ecf89a2c19bcd36d03ed1a615e710d19d450cb448bfda407b939aba54b002368c8bff30529cc50a0536a8e10bcce300421 - languageName: node - linkType: hard - -"ajv@npm:^6.10.0, ajv@npm:^6.12.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5": +"ajv@npm:^6.1.0, ajv@npm:^6.10.0, ajv@npm:^6.10.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -7245,15 +4701,29 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.0.1, ajv@npm:^8.6.0, ajv@npm:^8.9.0": - version: 8.17.1 - resolution: "ajv@npm:8.17.1" +"ajv@npm:^8.0.1": + version: 8.12.0 + resolution: "ajv@npm:8.12.0" dependencies: - fast-deep-equal: ^3.1.3 - fast-uri: ^3.0.1 + fast-deep-equal: ^3.1.1 json-schema-traverse: ^1.0.0 require-from-string: ^2.0.2 - checksum: 1797bf242cfffbaf3b870d13565bd1716b73f214bb7ada9a497063aada210200da36e3ed40237285f3255acc4feeae91b1fb183625331bad27da95973f7253d9 + uri-js: ^4.2.2 + checksum: 4dc13714e316e67537c8b31bc063f99a1d9d9a497eb4bbd55191ac0dcd5e4985bbb71570352ad6f1e76684fb6d790928f96ba3b2d4fd6e10024be9612fe3f001 + languageName: node + linkType: hard + +"alphanum-sort@npm:^1.0.0": + version: 1.0.2 + resolution: "alphanum-sort@npm:1.0.2" + checksum: 5a32d0b3c0944e65d22ff3ae2f88d7a4f8d88a78a703033caeae33f2944915e053d283d02f630dc94823edc7757148ecdcf39fd687a5117bda5c10133a03a7d8 + languageName: node + linkType: hard + +"ansi-colors@npm:^3.0.0": + version: 3.2.4 + resolution: "ansi-colors@npm:3.2.4" + checksum: 026c51880e9f8eb59b112669a87dbea4469939ff94b131606303bbd697438a6691b16b9db3027aa9bf132a244214e83ab1508b998496a34d2aea5b437ac9e62d languageName: node linkType: hard @@ -7264,7 +4734,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.1, ansi-escapes@npm:^4.3.2": +"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.1": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -7273,25 +4743,30 @@ __metadata: languageName: node linkType: hard -"ansi-html-community@npm:^0.0.8": - version: 0.0.8 - resolution: "ansi-html-community@npm:0.0.8" +"ansi-html@npm:0.0.7, ansi-html@npm:^0.0.7": + version: 0.0.7 + resolution: "ansi-html@npm:0.0.7" bin: - ansi-html: bin/ansi-html - checksum: 04c568e8348a636963f915e48eaa3e01218322e1169acafdd79c384f22e5558c003f79bbc480c1563865497482817c7eed025f0653ebc17642fededa5cb42089 + ansi-html: ./bin/ansi-html + checksum: 9b839ce99650b4c2d83621d67d68622d27e7948b54f7a4386f2218a3997ee4e684e5a6e8d290880c3f3260e8d90c2613c59c7028f04992ad5c8d99d3a0fcc02c languageName: node linkType: hard -"ansi-html@npm:^0.0.9": - version: 0.0.9 - resolution: "ansi-html@npm:0.0.9" - bin: - ansi-html: bin/ansi-html - checksum: a03754d6f66bae33938ed8bb3dd98174b7f4895ebe45226185036ed4a1388a7aaf2f2b9581608f0626432ba7add92cfc590aa6475a78bbb90d9d1e1d1af8cbe6 +"ansi-regex@npm:^2.0.0": + version: 2.1.1 + resolution: "ansi-regex@npm:2.1.1" + checksum: 190abd03e4ff86794f338a31795d262c1dfe8c91f7e01d04f13f646f1dcb16c5800818f886047876f1272f065570ab86b24b99089f8b68a0e11ff19aed4ca8f1 + languageName: node + linkType: hard + +"ansi-regex@npm:^4.1.0": + version: 4.1.1 + resolution: "ansi-regex@npm:4.1.1" + checksum: b1a6ee44cb6ecdabaa770b2ed500542714d4395d71c7e5c25baa631f680fb2ad322eb9ba697548d498a6fd366949fc8b5bfcf48d49a32803611f648005b01888 languageName: node linkType: hard -"ansi-regex@npm:^5.0.1": +"ansi-regex@npm:^5.0.0, ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b @@ -7299,13 +4774,20 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.2.2 - resolution: "ansi-regex@npm:6.2.2" - checksum: 9b17ce2c6daecc75bcd5966b9ad672c23b184dc3ed9bf3c98a0702f0d2f736c15c10d461913568f2cf527a5e64291c7473358885dd493305c84a1cfed66ba94f + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^2.2.1": + version: 2.2.1 + resolution: "ansi-styles@npm:2.2.1" + checksum: ebc0e00381f2a29000d1dac8466a640ce11943cef3bda3cd0020dc042e31e1058ab59bf6169cd794a54c3a7338a61ebc404b7c91e004092dd20e028c432c9c2c languageName: node linkType: hard -"ansi-styles@npm:^3.2.1": +"ansi-styles@npm:^3.2.0, ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" dependencies: @@ -7331,20 +4813,23 @@ __metadata: linkType: hard "ansi-styles@npm:^6.1.0": - version: 6.2.3 - resolution: "ansi-styles@npm:6.2.3" - checksum: f1b0829cf048cce870a305819f65ce2adcebc097b6d6479e12e955fd6225df9b9eb8b497083b764df796d94383ff20016cc4dbbae5b40f36138fb65a9d33c2e2 + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 languageName: node linkType: hard -"any-promise@npm:^1.0.0": - version: 1.3.0 - resolution: "any-promise@npm:1.3.0" - checksum: 0ee8a9bdbe882c90464d75d1f55cf027f5458650c4bd1f0467e65aec38ccccda07ca5844969ee77ed46d04e7dded3eaceb027e8d32f385688523fe305fa7e1de +"anymatch@npm:^2.0.0": + version: 2.0.0 + resolution: "anymatch@npm:2.0.0" + dependencies: + micromatch: ^3.1.4 + normalize-path: ^2.1.1 + checksum: f7bb1929842b4585cdc28edbb385767d499ce7d673f96a8f11348d2b2904592ffffc594fe9229b9a1e9e4dccb9329b7692f9f45e6a11dcefbb76ecdc9ab740f6 languageName: node linkType: hard -"anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": +"anymatch@npm:^3.0.0, anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" dependencies: @@ -7361,6 +4846,13 @@ __metadata: languageName: node linkType: hard +"aproba@npm:^1.1.1": + version: 1.2.0 + resolution: "aproba@npm:1.2.0" + checksum: 0fca141966559d195072ed047658b6e6c4fe92428c385dd38e288eacfc55807e7b4989322f030faff32c0f46bb0bc10f1e0ac32ec22d25315a1e5bbc0ebb76dc + languageName: node + linkType: hard + "arg@npm:^4.1.0": version: 4.1.3 resolution: "arg@npm:4.1.3" @@ -7368,30 +4860,35 @@ __metadata: languageName: node linkType: hard -"arg@npm:^5.0.2": - version: 5.0.2 - resolution: "arg@npm:5.0.2" - checksum: 6c69ada1a9943d332d9e5382393e897c500908d91d5cb735a01120d5f71daf1b339b7b8980cbeaba8fd1afc68e658a739746179e4315a26e8a28951ff9930078 - languageName: node - linkType: hard - "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10" dependencies: - sprintf-js: ~1.0.2 - checksum: 7ca6e45583a28de7258e39e13d81e925cfa25d7d4aacbf806a382d3c02fcb13403a07fb8aeef949f10a7cfe4a62da0e2e807b348a5980554cc28ee573ef95945 + sprintf-js: ~1.0.2 + checksum: 7ca6e45583a28de7258e39e13d81e925cfa25d7d4aacbf806a382d3c02fcb13403a07fb8aeef949f10a7cfe4a62da0e2e807b348a5980554cc28ee573ef95945 + languageName: node + linkType: hard + +"aria-query@npm:5.1.3": + version: 5.1.3 + resolution: "aria-query@npm:5.1.3" + dependencies: + deep-equal: ^2.0.5 + checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b languageName: node linkType: hard -"argparse@npm:^2.0.1": - version: 2.0.1 - resolution: "argparse@npm:2.0.1" - checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced +"aria-query@npm:^4.2.2": + version: 4.2.2 + resolution: "aria-query@npm:4.2.2" + dependencies: + "@babel/runtime": ^7.10.2 + "@babel/runtime-corejs3": ^7.10.2 + checksum: 38401a9a400f26f3dcc24b84997461a16b32869a9893d323602bed8da40a8bcc0243b8d2880e942249a1496cea7a7de769e93d21c0baa439f01e1ee936fed665 languageName: node linkType: hard -"aria-query@npm:5.3.0": +"aria-query@npm:^5.0.0, aria-query@npm:^5.3.0": version: 5.3.0 resolution: "aria-query@npm:5.3.0" dependencies: @@ -7400,20 +4897,41 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^5.0.0, aria-query@npm:^5.3.2": - version: 5.3.2 - resolution: "aria-query@npm:5.3.2" - checksum: d971175c85c10df0f6d14adfe6f1292409196114ab3c62f238e208b53103686f46cc70695a4f775b73bc65f6a09b6a092fd963c4f3a5a7d690c8fc5094925717 +"arity-n@npm:^1.0.4": + version: 1.0.4 + resolution: "arity-n@npm:1.0.4" + checksum: 3d76e16907f7b8a9452690c1efc301d0fbecea457365797eccfbade9b8d1653175b2c38343201bf26fdcbf0bcbb31eab6d912e7c008c6d19042301dc0be80a73 languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2": - version: 1.0.2 - resolution: "array-buffer-byte-length@npm:1.0.2" +"arr-diff@npm:^4.0.0": + version: 4.0.0 + resolution: "arr-diff@npm:4.0.0" + checksum: ea7c8834842ad3869297f7915689bef3494fd5b102ac678c13ffccab672d3d1f35802b79e90c4cfec2f424af3392e44112d1ccf65da34562ed75e049597276a0 + languageName: node + linkType: hard + +"arr-flatten@npm:^1.1.0": + version: 1.1.0 + resolution: "arr-flatten@npm:1.1.0" + checksum: 963fe12564fca2f72c055f3f6c206b9e031f7c433a0c66ca9858b484821f248c5b1e5d53c8e4989d80d764cd776cf6d9b160ad05f47bdc63022bfd63b5455e22 + languageName: node + linkType: hard + +"arr-union@npm:^3.1.0": + version: 3.1.0 + resolution: "arr-union@npm:3.1.0" + checksum: b5b0408c6eb7591143c394f3be082fee690ddd21f0fdde0a0a01106799e847f67fcae1b7e56b0a0c173290e29c6aca9562e82b300708a268bc8f88f3d6613cb9 + languageName: node + linkType: hard + +"array-buffer-byte-length@npm:^1.0.0, array-buffer-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "array-buffer-byte-length@npm:1.0.1" dependencies: - call-bound: ^1.0.3 - is-array-buffer: ^3.0.5 - checksum: 0ae3786195c3211b423e5be8dd93357870e6fb66357d81da968c2c39ef43583ef6eece1f9cb1caccdae4806739c65dea832b44b8593414313cd76a89795fca63 + call-bind: ^1.0.5 + is-array-buffer: ^3.0.4 + checksum: 53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e languageName: node linkType: hard @@ -7424,19 +4942,33 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8, array-includes@npm:^3.1.9": - version: 3.1.9 - resolution: "array-includes@npm:3.1.9" +"array-flatten@npm:^2.1.0": + version: 2.1.2 + resolution: "array-flatten@npm:2.1.2" + checksum: e8988aac1fbfcdaae343d08c9a06a6fddd2c6141721eeeea45c3cf523bf4431d29a46602929455ed548c7a3e0769928cdc630405427297e7081bd118fdec9262 + languageName: node + linkType: hard + +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.7": + version: 3.1.8 + resolution: "array-includes@npm:3.1.8" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.4 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.24.0 - es-object-atoms: ^1.1.1 - get-intrinsic: ^1.3.0 - is-string: ^1.1.1 - math-intrinsics: ^1.1.0 - checksum: b58dc526fe415252e50319eaf88336e06e75aa673e3b58d252414739a4612dbe56e7b613fdcc7c90561dc9cf9202bbe5ca029ccd8c08362746459475ae5a8f3e + es-abstract: ^1.23.2 + es-object-atoms: ^1.0.0 + get-intrinsic: ^1.2.4 + is-string: ^1.0.7 + checksum: eb39ba5530f64e4d8acab39297c11c1c5be2a4ea188ab2b34aba5fb7224d918f77717a9d57a3e2900caaa8440e59431bdaf5c974d5212ef65d97f132e38e2d91 + languageName: node + linkType: hard + +"array-union@npm:^1.0.1": + version: 1.0.2 + resolution: "array-union@npm:1.0.2" + dependencies: + array-uniq: ^1.0.1 + checksum: 82cec6421b6e6766556c484835a6d476a873f1b71cace5ab2b4f1b15b1e3162dc4da0d16f7a2b04d4aec18146c6638fe8f661340b31ba8e469fd811a1b45dc8d languageName: node linkType: hard @@ -7447,7 +4979,21 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlast@npm:^1.2.5": +"array-uniq@npm:^1.0.1": + version: 1.0.3 + resolution: "array-uniq@npm:1.0.3" + checksum: 1625f06b093d8bf279b81adfec6e72951c0857d65b5e3f65f053fffe9f9dd61c2fc52cff57e38a4700817e7e3f01a4faa433d505ea9e33cdae4514c334e0bf9e + languageName: node + linkType: hard + +"array-unique@npm:^0.3.2": + version: 0.3.2 + resolution: "array-unique@npm:0.3.2" + checksum: da344b89cfa6b0a5c221f965c21638bfb76b57b45184a01135382186924f55973cd9b171d4dad6bf606c6d9d36b0d721d091afdc9791535ead97ccbe78f8a888 + languageName: node + linkType: hard + +"array.prototype.findlast@npm:^1.2.4": version: 1.2.5 resolution: "array.prototype.findlast@npm:1.2.5" dependencies: @@ -7461,90 +5007,101 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.6": - version: 1.2.6 - resolution: "array.prototype.findlastindex@npm:1.2.6" +"array.prototype.findlastindex@npm:^1.2.3": + version: 1.2.5 + resolution: "array.prototype.findlastindex@npm:1.2.5" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.4 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.23.9 + es-abstract: ^1.23.2 es-errors: ^1.3.0 - es-object-atoms: ^1.1.1 - es-shim-unscopables: ^1.1.0 - checksum: bd2665bd51f674d4e1588ce5d5848a8adb255f414070e8e652585598b801480516df2c6cef2c60b6ea1a9189140411c49157a3f112d52e9eabb4e9fc80936ea6 + es-object-atoms: ^1.0.0 + es-shim-unscopables: ^1.0.2 + checksum: 2c81cff2a75deb95bf1ed89b6f5f2bfbfb882211e3b7cc59c3d6b87df774cd9d6b36949a8ae39ac476e092c1d4a4905f5ee11a86a456abb10f35f8211ae4e710 languageName: node linkType: hard -"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.3": - version: 1.3.3 - resolution: "array.prototype.flat@npm:1.3.3" +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": + version: 1.3.2 + resolution: "array.prototype.flat@npm:1.3.2" dependencies: - call-bind: ^1.0.8 - define-properties: ^1.2.1 - es-abstract: ^1.23.5 - es-shim-unscopables: ^1.0.2 - checksum: 5d5a7829ab2bb271a8d30a1c91e6271cef0ec534593c0fe6d2fb9ebf8bb62c1e5326e2fddcbbcbbe5872ca04f5e6b54a1ecf092e0af704fb538da9b2bfd95b40 + call-bind: ^1.0.2 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + es-shim-unscopables: ^1.0.0 + checksum: 5d6b4bf102065fb3f43764bfff6feb3295d372ce89591e6005df3d0ce388527a9f03c909af6f2a973969a4d178ab232ffc9236654149173e0e187ec3a1a6b87b languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.2, array.prototype.flatmap@npm:^1.3.3": - version: 1.3.3 - resolution: "array.prototype.flatmap@npm:1.3.3" +"array.prototype.flatmap@npm:^1.3.2": + version: 1.3.2 + resolution: "array.prototype.flatmap@npm:1.3.2" dependencies: - call-bind: ^1.0.8 - define-properties: ^1.2.1 - es-abstract: ^1.23.5 - es-shim-unscopables: ^1.0.2 - checksum: 11b4de09b1cf008be6031bb507d997ad6f1892e57dc9153583de6ebca0f74ea403fffe0f203461d359de05048d609f3f480d9b46fed4099652d8b62cc972f284 + call-bind: ^1.0.2 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + es-shim-unscopables: ^1.0.0 + checksum: ce09fe21dc0bcd4f30271f8144083aa8c13d4639074d6c8dc82054b847c7fc9a0c97f857491f4da19d4003e507172a78f4bcd12903098adac8b9cd374f734be3 languageName: node linkType: hard "array.prototype.reduce@npm:^1.0.6": - version: 1.0.8 - resolution: "array.prototype.reduce@npm:1.0.8" + version: 1.0.7 + resolution: "array.prototype.reduce@npm:1.0.7" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.4 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.23.9 + es-abstract: ^1.23.2 es-array-method-boxes-properly: ^1.0.0 es-errors: ^1.3.0 - es-object-atoms: ^1.1.1 - is-string: ^1.1.1 - checksum: a2a25e087a75e4caae09414acdfffb6ed69f7dd696d8c612d86dfaa5590bde4d7bc934db8bdd28625703f574aa93731848bfc24a7ba65c558aeb222b2a4fd4c4 + es-object-atoms: ^1.0.0 + is-string: ^1.0.7 + checksum: 90303617bd70c8e9a81ebff041d3e10fad1a97f163699cb015b7c84a3f9e6960d9bb161a30f1d0309d6e476f166af5668c1e24f7add3202213d25f7c7f15475d languageName: node linkType: hard -"array.prototype.tosorted@npm:^1.1.4": - version: 1.1.4 - resolution: "array.prototype.tosorted@npm:1.1.4" +"array.prototype.toreversed@npm:^1.1.2": + version: 1.1.2 + resolution: "array.prototype.toreversed@npm:1.1.2" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.2 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + es-shim-unscopables: ^1.0.0 + checksum: 58598193426282155297bedf950dc8d464624a0d81659822fb73124286688644cb7e0e4927a07f3ab2daaeb6617b647736cc3a5e6ca7ade5bb8e573b284e6240 + languageName: node + linkType: hard + +"array.prototype.tosorted@npm:^1.1.3": + version: 1.1.3 + resolution: "array.prototype.tosorted@npm:1.1.3" + dependencies: + call-bind: ^1.0.5 define-properties: ^1.2.1 - es-abstract: ^1.23.3 - es-errors: ^1.3.0 + es-abstract: ^1.22.3 + es-errors: ^1.1.0 es-shim-unscopables: ^1.0.2 - checksum: e4142d6f556bcbb4f393c02e7dbaea9af8f620c040450c2be137c9cbbd1a17f216b9c688c5f2c08fbb038ab83f55993fa6efdd9a05881d84693c7bcb5422127a + checksum: 555e8808086bbde9e634c5dc5a8c0a2f1773075447b43b2fa76ab4f94f4e90f416d2a4f881024e1ce1a2931614caf76cd6b408af901c9d7cd13061d0d268f5af languageName: node linkType: hard -"arraybuffer.prototype.slice@npm:^1.0.4": - version: 1.0.4 - resolution: "arraybuffer.prototype.slice@npm:1.0.4" +"arraybuffer.prototype.slice@npm:^1.0.3": + version: 1.0.3 + resolution: "arraybuffer.prototype.slice@npm:1.0.3" dependencies: array-buffer-byte-length: ^1.0.1 - call-bind: ^1.0.8 + call-bind: ^1.0.5 define-properties: ^1.2.1 - es-abstract: ^1.23.5 - es-errors: ^1.3.0 - get-intrinsic: ^1.2.6 + es-abstract: ^1.22.3 + es-errors: ^1.2.1 + get-intrinsic: ^1.2.3 is-array-buffer: ^3.0.4 - checksum: b1d1fd20be4e972a3779b1569226f6740170dca10f07aa4421d42cefeec61391e79c557cda8e771f5baefe47d878178cd4438f60916ce831813c08132bced765 + is-shared-array-buffer: ^1.0.2 + checksum: 352259cba534dcdd969c92ab002efd2ba5025b2e3b9bead3973150edbdf0696c629d7f4b3f061c5931511e8207bdc2306da614703c820b45dabce39e3daf7e3e languageName: node linkType: hard -"arrify@npm:^2.0.0": +"arrify@npm:^2.0.0, arrify@npm:^2.0.1": version: 2.0.1 resolution: "arrify@npm:2.0.1" checksum: 067c4c1afd182806a82e4c1cb8acee16ab8b5284fbca1ce29408e6e91281c36bb5b612f6ddfbd40a0f7a7e0c75bf2696eb94c027f6e328d6e9c52465c98e4209 @@ -7558,10 +5115,38 @@ __metadata: languageName: node linkType: hard -"assertion-error@npm:^2.0.1": - version: 2.0.1 - resolution: "assertion-error@npm:2.0.1" - checksum: a0789dd882211b87116e81e2648ccb7f60340b34f19877dd020b39ebb4714e475eb943e14ba3e22201c221ef6645b7bfe10297e76b6ac95b48a9898c1211ce66 +"asn1.js@npm:^4.10.1": + version: 4.10.1 + resolution: "asn1.js@npm:4.10.1" + dependencies: + bn.js: ^4.0.0 + inherits: ^2.0.1 + minimalistic-assert: ^1.0.0 + checksum: 9289a1a55401238755e3142511d7b8f6fc32f08c86ff68bd7100da8b6c186179dd6b14234fba2f7f6099afcd6758a816708485efe44bc5b2a6ec87d9ceeddbb5 + languageName: node + linkType: hard + +"assert@npm:^1.1.1": + version: 1.5.1 + resolution: "assert@npm:1.5.1" + dependencies: + object.assign: ^4.1.4 + util: ^0.10.4 + checksum: bfc539da97545f9b2989395d6b85be40b70649ce57464f3cc6e61f4975fb097ba0689c386f95bdb4c3ab867931e40a565c9e193ae3c02263a8e92acb17c9dc93 + languageName: node + linkType: hard + +"assertion-error@npm:^1.1.0": + version: 1.1.0 + resolution: "assertion-error@npm:1.1.0" + checksum: fd9429d3a3d4fd61782eb3962ae76b6d08aa7383123fca0596020013b3ebd6647891a85b05ce821c47d1471ed1271f00b0545cf6a4326cf2fc91efcc3b0fbecf + languageName: node + linkType: hard + +"assign-symbols@npm:^1.0.0": + version: 1.0.0 + resolution: "assign-symbols@npm:1.0.0" + checksum: c0eb895911d05b6b2d245154f70461c5e42c107457972e5ebba38d48967870dee53bcdf6c7047990586daa80fab8dab3cc6300800fbd47b454247fdedd859a2c languageName: node linkType: hard @@ -7579,17 +5164,26 @@ __metadata: languageName: node linkType: hard -"async-function@npm:^1.0.0": - version: 1.0.0 - resolution: "async-function@npm:1.0.0" - checksum: 9102e246d1ed9b37ac36f57f0a6ca55226876553251a31fc80677e71471f463a54c872dc78d5d7f80740c8ba624395cccbe8b60f7b690c4418f487d8e9fd1106 +"async-each@npm:^1.0.1": + version: 1.0.6 + resolution: "async-each@npm:1.0.6" + checksum: d237e8c39348d5f1441edbd3893692912afbacaf83a2ccce8978ebeea804529a8838654b12208fbbc08c8b0411a1248948ee9bf9291ebe1921aabd5b613bc5db languageName: node linkType: hard -"async@npm:^3.2.6": - version: 3.2.6 - resolution: "async@npm:3.2.6" - checksum: ee6eb8cd8a0ab1b58bd2a3ed6c415e93e773573a91d31df9d5ef559baafa9dab37d3b096fa7993e84585cac3697b2af6ddb9086f45d3ac8cae821bb2aab65682 +"async-limiter@npm:~1.0.0": + version: 1.0.1 + resolution: "async-limiter@npm:1.0.1" + checksum: 2b849695b465d93ad44c116220dee29a5aeb63adac16c1088983c339b0de57d76e82533e8e364a93a9f997f28bbfc6a92948cefc120652bd07f3b59f8d75cf2b + languageName: node + linkType: hard + +"async@npm:^2.6.4": + version: 2.6.4 + resolution: "async@npm:2.6.4" + dependencies: + lodash: ^4.17.14 + checksum: a52083fb32e1ebe1d63e5c5624038bb30be68ff07a6c8d7dfe35e47c93fc144bd8652cbec869e0ac07d57dde387aa5f1386be3559cdee799cb1f789678d88e19 languageName: node linkType: hard @@ -7607,21 +5201,29 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:^10.4.13": - version: 10.4.21 - resolution: "autoprefixer@npm:10.4.21" +"atob@npm:^2.1.2": + version: 2.1.2 + resolution: "atob@npm:2.1.2" + bin: + atob: bin/atob.js + checksum: dfeeeb70090c5ebea7be4b9f787f866686c645d9f39a0d184c817252d0cf08455ed25267d79c03254d3be1f03ac399992a792edcd5ffb9c91e097ab5ef42833a + languageName: node + linkType: hard + +"autoprefixer@npm:^9.6.1": + version: 9.8.8 + resolution: "autoprefixer@npm:9.8.8" dependencies: - browserslist: ^4.24.4 - caniuse-lite: ^1.0.30001702 - fraction.js: ^4.3.7 + browserslist: ^4.12.0 + caniuse-lite: ^1.0.30001109 normalize-range: ^0.1.2 - picocolors: ^1.1.1 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.1.0 + num2fraction: ^1.2.2 + picocolors: ^0.2.1 + postcss: ^7.0.32 + postcss-value-parser: ^4.1.0 bin: autoprefixer: bin/autoprefixer - checksum: 11770ce635a0520e457eaf2ff89056cd57094796a9f5d6d9375513388a5a016cd947333dcfd213b822fdd8a0b43ce68ae4958e79c6f077c41d87444c8cca0235 + checksum: 8f017672fbac248db0cf4e86aa707d8b148d9abadb842b5cf4c6be306d80fa6a654fadefd17e46213234c1f0947612acce2864f93e903f3e736b183fc1aedc45 languageName: node linkType: hard @@ -7634,65 +5236,103 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:^4.10.0": - version: 4.10.3 - resolution: "axe-core@npm:4.10.3" - checksum: e89fa5bcad9216f2de29bbdf95d6211d8c5b1025cbdcf56b6695c18b2e9a1eebd0b997a0141334169f6f062fc68fd39a5b97f86348d9f5be05958eade5c1ec78 +"axe-core@npm:=4.7.0": + version: 4.7.0 + resolution: "axe-core@npm:4.7.0" + checksum: f086bcab42be1761ba2b0b127dec350087f4c3a853bba8dd58f69d898cefaac31a1561da23146f6f3c07954c76171d1f2ce460e555e052d2b02cd79af628fa4a languageName: node linkType: hard -"axios@npm:^1.11.0, axios@npm:^1.7.9": - version: 1.12.1 - resolution: "axios@npm:1.12.1" +"axios@npm:^0.27.2": + version: 0.27.2 + resolution: "axios@npm:0.27.2" + dependencies: + follow-redirects: ^1.14.9 + form-data: ^4.0.0 + checksum: 38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854 + languageName: node + linkType: hard + +"axios@npm:^1.6.5": + version: 1.6.8 + resolution: "axios@npm:1.6.8" dependencies: follow-redirects: ^1.15.6 - form-data: ^4.0.4 + form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: 5160cf4e319ecd22de2bc4ad263881b5fb4cea1dfd9b8032ce349609fff041e0434f14e72bf2571b37ea88d1860f3456a95f3f40f2c14e84edfb6e81e5f27c4d + checksum: bf007fa4b207d102459300698620b3b0873503c6d47bf5a8f6e43c0c64c90035a4f698b55027ca1958f61ab43723df2781c38a99711848d232cad7accbcdfcdd languageName: node linkType: hard -"axobject-query@npm:^4.1.0": - version: 4.1.0 - resolution: "axobject-query@npm:4.1.0" - checksum: 7d1e87bf0aa7ae7a76cd39ab627b7c48fda3dc40181303d9adce4ba1d5b5ce73b5e5403ee6626ec8e91090448c887294d6144e24b6741a976f5be9347e3ae1df +"axobject-query@npm:^3.2.1": + version: 3.2.1 + resolution: "axobject-query@npm:3.2.1" + dependencies: + dequal: ^2.0.3 + checksum: a94047e702b57c91680e6a952ec4a1aaa2cfd0d80ead76bc8c954202980d8c51968a6ea18b4d8010e8e2cf95676533d8022a8ebba9abc1dfe25686721df26fd2 languageName: node linkType: hard -"babel-jest@npm:^27.4.2, babel-jest@npm:^27.5.1": - version: 27.5.1 - resolution: "babel-jest@npm:27.5.1" +"babel-eslint@npm:^10.1.0": + version: 10.1.0 + resolution: "babel-eslint@npm:10.1.0" + dependencies: + "@babel/code-frame": ^7.0.0 + "@babel/parser": ^7.7.0 + "@babel/traverse": ^7.7.0 + "@babel/types": ^7.7.0 + eslint-visitor-keys: ^1.0.0 + resolve: ^1.12.0 + peerDependencies: + eslint: ">= 4.12.1" + checksum: bdc1f62b6b0f9c4d5108c96d835dad0c0066bc45b7c020fcb2d6a08107cf69c9217a99d3438dbd701b2816896190c4283ba04270ed9a8349ee07bd8dafcdc050 + languageName: node + linkType: hard + +"babel-extract-comments@npm:^1.0.0": + version: 1.0.0 + resolution: "babel-extract-comments@npm:1.0.0" + dependencies: + babylon: ^6.18.0 + checksum: 6345c688ccb56a7b750223afb42c1ddc83865b8ac33d7b808b5ad5e3619624563cf8324fbacdcf41cf073a40d935468a05f806e1a7622b0186fa5dad1232a07b + languageName: node + linkType: hard + +"babel-jest@npm:^26.6.0, babel-jest@npm:^26.6.3": + version: 26.6.3 + resolution: "babel-jest@npm:26.6.3" dependencies: - "@jest/transform": ^27.5.1 - "@jest/types": ^27.5.1 - "@types/babel__core": ^7.1.14 - babel-plugin-istanbul: ^6.1.1 - babel-preset-jest: ^27.5.1 + "@jest/transform": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/babel__core": ^7.1.7 + babel-plugin-istanbul: ^6.0.0 + babel-preset-jest: ^26.6.2 chalk: ^4.0.0 - graceful-fs: ^4.2.9 + graceful-fs: ^4.2.4 slash: ^3.0.0 peerDependencies: - "@babel/core": ^7.8.0 - checksum: 4e93e6e9fb996cc5f1505e924eb8e8cc7b25c294ba9629762a2715390f48af6a4c14dbb84cd9730013ac0e03267a5a9aa2fb6318c544489cda7f50f4e506def4 + "@babel/core": ^7.0.0 + checksum: 5917233f0d381e719e195b69b81e46da90293432d10288d79f8f59b8f3f9ac030e14701f3d9f90893fb739481df1d132446f1b983d841e65e2623775db100897 languageName: node linkType: hard -"babel-loader@npm:^8.2.3": - version: 8.4.1 - resolution: "babel-loader@npm:8.4.1" +"babel-loader@npm:8.1.0": + version: 8.1.0 + resolution: "babel-loader@npm:8.1.0" dependencies: - find-cache-dir: ^3.3.1 - loader-utils: ^2.0.4 - make-dir: ^3.1.0 + find-cache-dir: ^2.1.0 + loader-utils: ^1.4.0 + mkdirp: ^0.5.3 + pify: ^4.0.1 schema-utils: ^2.6.5 peerDependencies: "@babel/core": ^7.0.0 webpack: ">=2" - checksum: fa02db1a7d3ebb7b4aab83e926fb51e627a00427943c9dd1b3302c8099c67fa6a242a2adeed37d95abcd39ba619edf558a1dec369ce0849c5a87dc290c90fe2f + checksum: fdbcae91cc43366206320a1cbe40d358a64ba2dfaa561fbd690efe0db6256c9d27ab7600f7c84041fbc4c2a6f0279175b1f8d1fa5ed17ec30bbd734da84a1bc0 languageName: node linkType: hard -"babel-plugin-istanbul@npm:^6.1.1": +"babel-plugin-istanbul@npm:^6.0.0": version: 6.1.1 resolution: "babel-plugin-istanbul@npm:6.1.1" dependencies: @@ -7705,15 +5345,15 @@ __metadata: languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:^27.5.1": - version: 27.5.1 - resolution: "babel-plugin-jest-hoist@npm:27.5.1" +"babel-plugin-jest-hoist@npm:^26.6.2": + version: 26.6.2 + resolution: "babel-plugin-jest-hoist@npm:26.6.2" dependencies: "@babel/template": ^7.3.3 "@babel/types": ^7.3.3 "@types/babel__core": ^7.0.0 "@types/babel__traverse": ^7.0.6 - checksum: 709c17727aa8fd3be755d256fb514bf945a5c2ea6017f037d80280fc44ae5fe7dfeebf63d8412df53796455c2c216119d628d8cc90b099434fd819005943d058 + checksum: abe3732fdf20f96e91cbf788a54d776b30bd7a6054cb002a744d7071c656813e26e77a780dc2a6f6b197472897e220836cd907bda3fadb9d0481126bfd6c3783 languageName: node linkType: hard @@ -7728,7 +5368,7 @@ __metadata: languageName: node linkType: hard -"babel-plugin-named-asset-import@npm:^0.3.8": +"babel-plugin-named-asset-import@npm:^0.3.7": version: 0.3.8 resolution: "babel-plugin-named-asset-import@npm:0.3.8" peerDependencies: @@ -7737,39 +5377,56 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs2@npm:^0.4.14": - version: 0.4.14 - resolution: "babel-plugin-polyfill-corejs2@npm:0.4.14" +"babel-plugin-polyfill-corejs2@npm:^0.4.10": + version: 0.4.11 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.11" dependencies: - "@babel/compat-data": ^7.27.7 - "@babel/helper-define-polyfill-provider": ^0.6.5 + "@babel/compat-data": ^7.22.6 + "@babel/helper-define-polyfill-provider": ^0.6.2 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: d654334c1b4390d08282416144b7b6f3d74d2cab44b2bfa2b6405c828882c82907b8b67698dce1be046c218d2d4fe5bf7fb6d01879938f3129dad969e8cfc44d + checksum: f098353ce7c7dde1a1d2710858e01b471e85689110c9e37813e009072347eb8c55d5f84d20d3bf1cab31755f20078ba90f8855fdc4686a9daa826a95ff280bd7 languageName: node linkType: hard -"babel-plugin-polyfill-corejs3@npm:^0.13.0": - version: 0.13.0 - resolution: "babel-plugin-polyfill-corejs3@npm:0.13.0" +"babel-plugin-polyfill-corejs3@npm:^0.10.1, babel-plugin-polyfill-corejs3@npm:^0.10.4": + version: 0.10.4 + resolution: "babel-plugin-polyfill-corejs3@npm:0.10.4" dependencies: - "@babel/helper-define-polyfill-provider": ^0.6.5 - core-js-compat: ^3.43.0 + "@babel/helper-define-polyfill-provider": ^0.6.1 + core-js-compat: ^3.36.1 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: cf526031acd97ff2124e7c10e15047e6eeb0620d029c687f1dca99916a8fe6cac0e634b84c913db6cb68b7a024f82492ba8fdcc2a6266e7b05bdac2cba0c2434 + checksum: b96a54495f7cc8b3797251c8c15f5ed015edddc3110fc122f6b32c94bec33af1e8bc56fa99091808f500bde0cccaaa266889cdc5935d9e6e9cf09898214f02dd languageName: node linkType: hard -"babel-plugin-polyfill-regenerator@npm:^0.6.5": - version: 0.6.5 - resolution: "babel-plugin-polyfill-regenerator@npm:0.6.5" +"babel-plugin-polyfill-regenerator@npm:^0.6.1": + version: 0.6.2 + resolution: "babel-plugin-polyfill-regenerator@npm:0.6.2" dependencies: - "@babel/helper-define-polyfill-provider": ^0.6.5 + "@babel/helper-define-polyfill-provider": ^0.6.2 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: ed1932fa9a31e0752fd10ebf48ab9513a654987cab1182890839523cb898559d24ae0578fdc475d9f995390420e64eeaa4b0427045b56949dace3c725bc66dbb + checksum: 150233571072b6b3dfe946242da39cba8587b7f908d1c006f7545fc88b0e3c3018d445739beb61e7a75835f0c2751dbe884a94ff9b245ec42369d9267e0e1b3f + languageName: node + linkType: hard + +"babel-plugin-syntax-object-rest-spread@npm:^6.8.0": + version: 6.13.0 + resolution: "babel-plugin-syntax-object-rest-spread@npm:6.13.0" + checksum: 14083f2783c760f5f199160f48e42ad4505fd35fc7cf9c4530812b176705259562b77db6d3ddc5e3cbce9e9b2b61ec9db3065941f0949b68e77cae3e395a6eef + languageName: node + linkType: hard + +"babel-plugin-transform-object-rest-spread@npm:^6.26.0": + version: 6.26.0 + resolution: "babel-plugin-transform-object-rest-spread@npm:6.26.0" + dependencies: + babel-plugin-syntax-object-rest-spread: ^6.8.0 + babel-runtime: ^6.26.0 + checksum: aad583fb0d08073678838f77fa822788b9a0b842ba33e34f8d131246852f7ed31cfb5fdf57644dec952f84dcae862a27dbf3d12ccbee6bdb0aed6e7ed13ca9ba languageName: node linkType: hard @@ -7781,45 +5438,42 @@ __metadata: linkType: hard "babel-preset-current-node-syntax@npm:^1.0.0": - version: 1.2.0 - resolution: "babel-preset-current-node-syntax@npm:1.2.0" + version: 1.0.1 + resolution: "babel-preset-current-node-syntax@npm:1.0.1" dependencies: "@babel/plugin-syntax-async-generators": ^7.8.4 "@babel/plugin-syntax-bigint": ^7.8.3 - "@babel/plugin-syntax-class-properties": ^7.12.13 - "@babel/plugin-syntax-class-static-block": ^7.14.5 - "@babel/plugin-syntax-import-attributes": ^7.24.7 - "@babel/plugin-syntax-import-meta": ^7.10.4 + "@babel/plugin-syntax-class-properties": ^7.8.3 + "@babel/plugin-syntax-import-meta": ^7.8.3 "@babel/plugin-syntax-json-strings": ^7.8.3 - "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 + "@babel/plugin-syntax-logical-assignment-operators": ^7.8.3 "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 - "@babel/plugin-syntax-numeric-separator": ^7.10.4 + "@babel/plugin-syntax-numeric-separator": ^7.8.3 "@babel/plugin-syntax-object-rest-spread": ^7.8.3 "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 "@babel/plugin-syntax-optional-chaining": ^7.8.3 - "@babel/plugin-syntax-private-property-in-object": ^7.14.5 - "@babel/plugin-syntax-top-level-await": ^7.14.5 + "@babel/plugin-syntax-top-level-await": ^7.8.3 peerDependencies: - "@babel/core": ^7.0.0 || ^8.0.0-0 - checksum: 3608fa671cfa46364ea6ec704b8fcdd7514b7b70e6ec09b1199e13ae73ed346c51d5ce2cb6d4d5b295f6a3f2cad1fdeec2308aa9e037002dd7c929194cc838ea + "@babel/core": ^7.0.0 + checksum: d118c2742498c5492c095bc8541f4076b253e705b5f1ad9a2e7d302d81a84866f0070346662355c8e25fc02caa28dc2da8d69bcd67794a0d60c4d6fab6913cc8 languageName: node linkType: hard -"babel-preset-jest@npm:^27.5.1": - version: 27.5.1 - resolution: "babel-preset-jest@npm:27.5.1" +"babel-preset-jest@npm:^26.6.2": + version: 26.6.2 + resolution: "babel-preset-jest@npm:26.6.2" dependencies: - babel-plugin-jest-hoist: ^27.5.1 + babel-plugin-jest-hoist: ^26.6.2 babel-preset-current-node-syntax: ^1.0.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 251bcea11c18fd9672fec104eadb45b43f117ceeb326fa7345ced778d4c1feab29343cd7a87a1dcfae4997d6c851a8b386d7f7213792da6e23b74f4443a8976d + checksum: 1d9bef3a7ac6751a09d29ceb84be8b1998abd210fafa12223689c744db4f2a63ab90cba7986a71f3154d9aceda9dbeca563178731d21cbaf793b4096ed3a4d01 languageName: node linkType: hard -"babel-preset-react-app@npm:^10.0.1": - version: 10.1.0 - resolution: "babel-preset-react-app@npm:10.1.0" +"babel-preset-react-app@npm:^10.0.0": + version: 10.0.1 + resolution: "babel-preset-react-app@npm:10.0.1" dependencies: "@babel/core": ^7.16.0 "@babel/plugin-proposal-class-properties": ^7.16.0 @@ -7828,7 +5482,6 @@ __metadata: "@babel/plugin-proposal-numeric-separator": ^7.16.0 "@babel/plugin-proposal-optional-chaining": ^7.16.0 "@babel/plugin-proposal-private-methods": ^7.16.0 - "@babel/plugin-proposal-private-property-in-object": ^7.16.7 "@babel/plugin-transform-flow-strip-types": ^7.16.0 "@babel/plugin-transform-react-display-name": ^7.16.0 "@babel/plugin-transform-runtime": ^7.16.4 @@ -7838,7 +5491,26 @@ __metadata: "@babel/runtime": ^7.16.3 babel-plugin-macros: ^3.1.0 babel-plugin-transform-react-remove-prop-types: ^0.4.24 - checksum: e4ac6c85be4f56c7e45b52700e04aed01422221b5c988e7a192a80d3b5aa3abbd415c0b76e8b5d564a411477a0b03323a15108663a9f541bd9397fa32f28ed89 + checksum: ee66043484e67b8aef2541976388299691478ea00834f3bb14b6b3d5edcd316a5ac95351f6ec084b41ee555cad820d4194280ad38ce51884fedc7e8946a57b74 + languageName: node + linkType: hard + +"babel-runtime@npm:^6.26.0": + version: 6.26.0 + resolution: "babel-runtime@npm:6.26.0" + dependencies: + core-js: ^2.4.0 + regenerator-runtime: ^0.11.0 + checksum: 8aeade94665e67a73c1ccc10f6fd42ba0c689b980032b70929de7a6d9a12eb87ef51902733f8fefede35afea7a5c3ef7e916a64d503446c1eedc9e3284bd3d50 + languageName: node + linkType: hard + +"babylon@npm:^6.18.0": + version: 6.18.0 + resolution: "babylon@npm:6.18.0" + bin: + babylon: ./bin/babylon.js + checksum: 0777ae0c735ce1cbfc856d627589ed9aae212b84fb0c03c368b55e6c5d3507841780052808d0ad46e18a2ba516e93d55eeed8cd967f3b2938822dfeccfb2a16d languageName: node linkType: hard @@ -7846,18 +5518,16 @@ __metadata: version: 0.0.0-use.local resolution: "backend@workspace:src/backend" dependencies: - "@prisma/client": 6.2.1 - "@slack/events-api": ^3.0.1 - "@slack/web-api": ^7.8.0 + "@prisma/client": ^4.4.0 + "@slack/web-api": ^6.7.2 "@types/concat-stream": ^2.0.0 "@types/cookie-parser": ^1.4.3 "@types/cors": ^2.8.12 - "@types/express": ^5.0.0 + "@types/express": ^4.17.6 "@types/express-jwt": ^6.0.4 "@types/jsonwebtoken": ^8.5.9 "@types/multer": ^1.4.7 - "@types/node": ^20.0.0 - "@types/nodemailer": ^6.4.0 + "@types/node": 18.17.1 "@types/supertest": ^2.0.12 body-parser: ^1.19.0 concat-stream: ^2.0.0 @@ -7865,7 +5535,7 @@ __metadata: cors: ^2.8.5 decimal.js: ^10.4.3 dotenv: ^16.0.1 - express: ^5.0.0 + express: ^4.17.1 express-jwt: ^7.7.5 express-validator: ^6.14.2 google-auth-library: ^8.1.1 @@ -7874,19 +5544,20 @@ __metadata: multer: ^1.4.5-lts.1 nodemailer: ^6.9.1 nodemon: ^2.0.16 - prisma: 6.2.1 + prisma: ^4.4.0 shared: 1.0.0 supertest: ^6.2.4 + ts-jest: ^26.2.0 ts-node: ^8.10.1 - typescript: ^5.7.3 - vitest: ^3.0.0 + typescript: ^4.1.5 + vitest: ^0.32.1 languageName: unknown linkType: soft -"bail@npm:^2.0.0": - version: 2.0.2 - resolution: "bail@npm:2.0.2" - checksum: aab4e8ccdc8d762bf3fdfce8e706601695620c0c2eda256dd85088dc0be3cfd7ff126f6e99c2bee1f24f5d418414aacf09d7f9702f16d6963df2fa488cda8824 +"bail@npm:^1.0.0": + version: 1.0.5 + resolution: "bail@npm:1.0.5" + checksum: 6c334940d7eaa4e656a12fb12407b6555649b6deb6df04270fa806e0da82684ebe4a4e47815b271c794b40f8d6fa286e0c248b14ddbabb324a917fab09b7301a languageName: node linkType: hard @@ -7897,19 +5568,25 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": +"base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 languageName: node linkType: hard -"baseline-browser-mapping@npm:^2.8.2": - version: 2.8.3 - resolution: "baseline-browser-mapping@npm:2.8.3" - bin: - baseline-browser-mapping: dist/cli.js - checksum: 5b68bebb5ff1e2266e9252fdf13f23679ebd3b884cc4165a7257e6a09c5fdc51a1fb98bac24a78e3bf7c429f7a4c05743733e6255f0a6403ace8e6fcefd2ed53 +"base@npm:^0.11.1": + version: 0.11.2 + resolution: "base@npm:0.11.2" + dependencies: + cache-base: ^1.0.1 + class-utils: ^0.3.5 + component-emitter: ^1.2.1 + define-property: ^1.0.0 + isobject: ^3.0.1 + mixin-deep: ^1.2.0 + pascalcase: ^0.1.1 + checksum: a4a146b912e27eea8f66d09cb0c9eab666f32ce27859a7dfd50f38cd069a2557b39f16dba1bc2aecb3b44bf096738dd207b7970d99b0318423285ab1b1994edd languageName: node linkType: hard @@ -7948,9 +5625,16 @@ __metadata: linkType: hard "bignumber.js@npm:^9.0.0": - version: 9.3.1 - resolution: "bignumber.js@npm:9.3.1" - checksum: 6ab100271a23a75bb8b99a4b1a34a1a94967ac0b9a52a198147607bd91064e72c6f356380d7a09cd687bf50d81ad2ed1a0a8edfaa90369c9003ed8bb2440d7f0 + version: 9.1.2 + resolution: "bignumber.js@npm:9.1.2" + checksum: 582c03af77ec9cb0ebd682a373ee6c66475db94a4325f92299621d544aa4bd45cb45fd60001610e94aef8ae98a0905fa538241d9638d4422d57abbeeac6fadaf + languageName: node + linkType: hard + +"binary-extensions@npm:^1.0.0": + version: 1.13.1 + resolution: "binary-extensions@npm:1.13.1" + checksum: ad7747f33c07e94ba443055de130b50c8b8b130a358bca064c580d91769ca6a69c7ac65ca008ff044ed4541d2c6ad45496e1fadbef5218a68770996b6a2194d7 languageName: node linkType: hard @@ -7961,7 +5645,16 @@ __metadata: languageName: node linkType: hard -"bl@npm:^4.0.3": +"bindings@npm:^1.5.0": + version: 1.5.0 + resolution: "bindings@npm:1.5.0" + dependencies: + file-uri-to-path: 1.0.0 + checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7 + languageName: node + linkType: hard + +"bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" dependencies: @@ -7972,16 +5665,30 @@ __metadata: languageName: node linkType: hard -"bluebird@npm:^3.7.2": +"bluebird@npm:^3.5.5, bluebird@npm:^3.7.2": version: 3.7.2 resolution: "bluebird@npm:3.7.2" checksum: 869417503c722e7dc54ca46715f70e15f4d9c602a423a02c825570862d12935be59ed9c7ba34a9b31f186c017c23cac6b54e35446f8353059c101da73eac22ef languageName: node linkType: hard -"body-parser@npm:1.20.3, body-parser@npm:^1.19.0": - version: 1.20.3 - resolution: "body-parser@npm:1.20.3" +"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": + version: 4.12.0 + resolution: "bn.js@npm:4.12.0" + checksum: 39afb4f15f4ea537b55eaf1446c896af28ac948fdcf47171961475724d1bb65118cca49fa6e3d67706e4790955ec0e74de584e45c8f1ef89f46c812bee5b5a12 + languageName: node + linkType: hard + +"bn.js@npm:^5.0.0, bn.js@npm:^5.2.1": + version: 5.2.1 + resolution: "bn.js@npm:5.2.1" + checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 + languageName: node + linkType: hard + +"body-parser@npm:1.20.2, body-parser@npm:^1.19.0": + version: 1.20.2 + resolution: "body-parser@npm:1.20.2" dependencies: bytes: 3.1.2 content-type: ~1.0.5 @@ -7991,38 +5698,25 @@ __metadata: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.13.0 + qs: 6.11.0 raw-body: 2.5.2 type-is: ~1.6.18 unpipe: 1.0.0 - checksum: 1a35c59a6be8d852b00946330141c4f142c6af0f970faa87f10ad74f1ee7118078056706a05ae3093c54dabca9cd3770fa62a170a85801da1a4324f04381167d - languageName: node - linkType: hard - -"body-parser@npm:^2.2.0": - version: 2.2.0 - resolution: "body-parser@npm:2.2.0" - dependencies: - bytes: ^3.1.2 - content-type: ^1.0.5 - debug: ^4.4.0 - http-errors: ^2.0.0 - iconv-lite: ^0.6.3 - on-finished: ^2.4.1 - qs: ^6.14.0 - raw-body: ^3.0.0 - type-is: ^2.0.0 - checksum: 7fe3a2d288f0b632528d6ccb90052d1a9492c5b79d5716d32c8de1f5fb8237b0d31ee5050e1d0b7ff143a492ff151804612c6e2686a222a1d4c9e2e6531b8fb2 + checksum: 14d37ec638ab5c93f6099ecaed7f28f890d222c650c69306872e00b9efa081ff6c596cd9afb9930656aae4d6c4e1c17537bea12bb73c87a217cb3cfea8896737 languageName: node linkType: hard -"bonjour-service@npm:^1.0.11": - version: 1.3.0 - resolution: "bonjour-service@npm:1.3.0" +"bonjour@npm:^3.5.0": + version: 3.5.0 + resolution: "bonjour@npm:3.5.0" dependencies: - fast-deep-equal: ^3.1.3 - multicast-dns: ^7.2.5 - checksum: 737bd40d0b609b18afdfcaf3c416a60d7dc94aedc4cb9d6e7af459a7f3bdffadc199370a48c46739d92689741cad4ec8a6987a3e4d869dd301b521227b92e082 + array-flatten: ^2.1.0 + deep-equal: ^1.0.1 + dns-equal: ^1.0.0 + dns-txt: ^2.0.2 + multicast-dns: ^6.0.1 + multicast-dns-service-types: ^1.1.0 + checksum: 2cfbe9fa861f4507b5ff3853eeae3ef03a231ede2b7363efedd80880ea3c0576f64416f98056c96e429ed68ff38dc4a70c0583d1eb4dab72e491ca44a0f03444 languageName: node linkType: hard @@ -8033,47 +5727,59 @@ __metadata: languageName: node linkType: hard -"bootstrap@npm:^5.3.0": - version: 5.3.8 - resolution: "bootstrap@npm:5.3.8" +"bootstrap@npm:^4.6.0": + version: 4.6.2 + resolution: "bootstrap@npm:4.6.2" peerDependencies: - "@popperjs/core": ^2.11.8 - checksum: 6813254a1140646ca53f33f2d0c5fbf7cf544dabba06cddc061243acf4ec71fadff348860ed4623e1b486c05c151d7807da017dc473e748add0926d2cf9f1a04 - languageName: node - linkType: hard - -"bowser@npm:^2.11.0": - version: 2.12.1 - resolution: "bowser@npm:2.12.1" - checksum: 994a3da9e9b628892e0fbc4fd5afeec672003a9a72300ec8ac832f6707ba6ce68d137d50316f08e6197f9e0cca5c486aa4b9ce9db50013061225cab4e432f8a0 + jquery: 1.9.1 - 3 + popper.js: ^1.16.1 + checksum: 3f4e7768ff7d618c49d4bf4f02aa54a9bfb679d4eecb0f3854fa4af1a17b9114b147009c435946432cdd1572efffc71d88ec385c55943a12fa66253cde0876b0 languageName: node linkType: hard "brace-expansion@npm:^1.1.7": - version: 1.1.12 - resolution: "brace-expansion@npm:1.1.12" + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" dependencies: balanced-match: ^1.0.0 concat-map: 0.0.1 - checksum: 12cb6d6310629e3048cadb003e1aca4d8c9bb5c67c3c321bafdd7e7a50155de081f78ea3e0ed92ecc75a9015e784f301efc8132383132f4f7904ad1ac529c562 + checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 languageName: node linkType: hard "brace-expansion@npm:^2.0.1": - version: 2.0.2 - resolution: "brace-expansion@npm:2.0.2" + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" dependencies: balanced-match: ^1.0.0 - checksum: 01dff195e3646bc4b0d27b63d9bab84d2ebc06121ff5013ad6e5356daa5a9d6b60fa26cf73c74797f2dc3fbec112af13578d51f75228c1112b26c790a87b0488 + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 languageName: node linkType: hard -"braces@npm:^3.0.3, braces@npm:~3.0.2": - version: 3.0.3 - resolution: "braces@npm:3.0.3" +"braces@npm:^2.3.1, braces@npm:^2.3.2": + version: 2.3.2 + resolution: "braces@npm:2.3.2" + dependencies: + arr-flatten: ^1.1.0 + array-unique: ^0.3.2 + extend-shallow: ^2.0.1 + fill-range: ^4.0.0 + isobject: ^3.0.1 + repeat-element: ^1.1.2 + snapdragon: ^0.8.1 + snapdragon-node: ^2.0.1 + split-string: ^3.0.2 + to-regex: ^3.0.1 + checksum: e30dcb6aaf4a31c8df17d848aa283a65699782f75ad61ae93ec25c9729c66cf58e66f0000a9fec84e4add1135bb7da40f7cb9601b36bebcfa9ca58e8d5c07de0 + languageName: node + linkType: hard + +"braces@npm:^3.0.2, braces@npm:~3.0.2": + version: 3.0.2 + resolution: "braces@npm:3.0.2" dependencies: - fill-range: ^7.1.1 - checksum: b95aa0b3bd909f6cd1720ffcf031aeaf46154dd88b4da01f9a1d3f7ea866a79eba76a6d01cbc3c422b2ee5cdc39a4f02491058d5df0d7bf6e6a162a832df1f69 + fill-range: ^7.0.1 + checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459 languageName: node linkType: hard @@ -8093,25 +5799,128 @@ __metadata: languageName: node linkType: hard -"browser-process-hrtime@npm:^1.0.0": - version: 1.0.0 - resolution: "browser-process-hrtime@npm:1.0.0" - checksum: e30f868cdb770b1201afb714ad1575dd86366b6e861900884665fb627109b3cc757c40067d3bfee1ff2a29c835257ea30725a8018a9afd02ac1c24b408b1e45f +"brorand@npm:^1.0.1, brorand@npm:^1.1.0": + version: 1.1.0 + resolution: "brorand@npm:1.1.0" + checksum: 8a05c9f3c4b46572dec6ef71012b1946db6cae8c7bb60ccd4b7dd5a84655db49fe043ecc6272e7ef1f69dc53d6730b9e2a3a03a8310509a3d797a618cbee52be + languageName: node + linkType: hard + +"browser-process-hrtime@npm:^1.0.0": + version: 1.0.0 + resolution: "browser-process-hrtime@npm:1.0.0" + checksum: e30f868cdb770b1201afb714ad1575dd86366b6e861900884665fb627109b3cc757c40067d3bfee1ff2a29c835257ea30725a8018a9afd02ac1c24b408b1e45f + languageName: node + linkType: hard + +"browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": + version: 1.2.0 + resolution: "browserify-aes@npm:1.2.0" + dependencies: + buffer-xor: ^1.0.3 + cipher-base: ^1.0.0 + create-hash: ^1.1.0 + evp_bytestokey: ^1.0.3 + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: 4a17c3eb55a2aa61c934c286f34921933086bf6d67f02d4adb09fcc6f2fc93977b47d9d884c25619144fccd47b3b3a399e1ad8b3ff5a346be47270114bcf7104 + languageName: node + linkType: hard + +"browserify-cipher@npm:^1.0.0": + version: 1.0.1 + resolution: "browserify-cipher@npm:1.0.1" + dependencies: + browserify-aes: ^1.0.4 + browserify-des: ^1.0.0 + evp_bytestokey: ^1.0.0 + checksum: 2d8500acf1ee535e6bebe808f7a20e4c3a9e2ed1a6885fff1facbfd201ac013ef030422bec65ca9ece8ffe82b03ca580421463f9c45af6c8415fd629f4118c13 + languageName: node + linkType: hard + +"browserify-des@npm:^1.0.0": + version: 1.0.2 + resolution: "browserify-des@npm:1.0.2" + dependencies: + cipher-base: ^1.0.1 + des.js: ^1.0.0 + inherits: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: b15a3e358a1d78a3b62ddc06c845d02afde6fc826dab23f1b9c016e643e7b1fda41de628d2110b712f6a44fb10cbc1800bc6872a03ddd363fb50768e010395b7 + languageName: node + linkType: hard + +"browserify-rsa@npm:^4.0.0, browserify-rsa@npm:^4.1.0": + version: 4.1.0 + resolution: "browserify-rsa@npm:4.1.0" + dependencies: + bn.js: ^5.0.0 + randombytes: ^2.0.1 + checksum: 155f0c135873efc85620571a33d884aa8810e40176125ad424ec9d85016ff105a07f6231650914a760cca66f29af0494087947b7be34880dd4599a0cd3c38e54 + languageName: node + linkType: hard + +"browserify-sign@npm:^4.0.0": + version: 4.2.3 + resolution: "browserify-sign@npm:4.2.3" + dependencies: + bn.js: ^5.2.1 + browserify-rsa: ^4.1.0 + create-hash: ^1.2.0 + create-hmac: ^1.1.7 + elliptic: ^6.5.5 + hash-base: ~3.0 + inherits: ^2.0.4 + parse-asn1: ^5.1.7 + readable-stream: ^2.3.8 + safe-buffer: ^5.2.1 + checksum: 403a8061d229ae31266670345b4a7c00051266761d2c9bbeb68b1a9bcb05f68143b16110cf23a171a5d6716396a1f41296282b3e73eeec0a1871c77f0ff4ee6b + languageName: node + linkType: hard + +"browserify-zlib@npm:^0.2.0": + version: 0.2.0 + resolution: "browserify-zlib@npm:0.2.0" + dependencies: + pako: ~1.0.5 + checksum: 5cd9d6a665190fedb4a97dfbad8dabc8698d8a507298a03f42c734e96d58ca35d3c7d4085e283440bbca1cd1938cff85031728079bedb3345310c58ab1ec92d6 + languageName: node + linkType: hard + +"browserslist@npm:4.14.2": + version: 4.14.2 + resolution: "browserslist@npm:4.14.2" + dependencies: + caniuse-lite: ^1.0.30001125 + electron-to-chromium: ^1.3.564 + escalade: ^3.0.2 + node-releases: ^1.1.61 + bin: + browserslist: cli.js + checksum: 44b5d7a444b867e1f027923f37a8ed537b4403f8a85a35869904e7d3e4071b37459df08d41ab4d425f5191f3125f1c5a191cbff9070f81f4d311803dc0a2fb0f languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.25.3": - version: 4.26.0 - resolution: "browserslist@npm:4.26.0" +"browserslist@npm:^4.0.0, browserslist@npm:^4.12.0, browserslist@npm:^4.22.2, browserslist@npm:^4.23.0, browserslist@npm:^4.6.2, browserslist@npm:^4.6.4": + version: 4.23.0 + resolution: "browserslist@npm:4.23.0" dependencies: - baseline-browser-mapping: ^2.8.2 - caniuse-lite: ^1.0.30001741 - electron-to-chromium: ^1.5.218 - node-releases: ^2.0.21 - update-browserslist-db: ^1.1.3 + caniuse-lite: ^1.0.30001587 + electron-to-chromium: ^1.4.668 + node-releases: ^2.0.14 + update-browserslist-db: ^1.0.13 bin: browserslist: cli.js - checksum: 7188de936499e7a68234c740f10fd5167191d7a033964f572201d4df71919997c8ba1053027f066e8c01189df06840a1570b35e871796fd87fcb05141e8428f2 + checksum: 436f49e796782ca751ebab7edc010cfc9c29f68536f387666cd70ea22f7105563f04dd62c6ff89cb24cc3254d17cba385f979eeeb3484d43e012412ff7e75def + languageName: node + linkType: hard + +"bs-logger@npm:0.x": + version: 0.2.6 + resolution: "bs-logger@npm:0.2.6" + dependencies: + fast-json-stable-stringify: 2.x + checksum: d34bdaf68c64bd099ab97c3ea608c9ae7d3f5faa1178b3f3f345acd94e852e608b2d4f9103fb2e503f5e69780e98293df41691b84be909b41cf5045374d54606 languageName: node linkType: hard @@ -8124,20 +5933,45 @@ __metadata: languageName: node linkType: hard -"buffer-equal-constant-time@npm:^1.0.1": +"buffer-equal-constant-time@npm:1.0.1": version: 1.0.1 resolution: "buffer-equal-constant-time@npm:1.0.1" checksum: 80bb945f5d782a56f374b292770901065bad21420e34936ecbe949e57724b4a13874f735850dd1cc61f078773c4fb5493a41391e7bda40d1fa388d6bd80daaab languageName: node linkType: hard -"buffer-from@npm:^1.0.0": +"buffer-from@npm:1.x, buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" checksum: 0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb languageName: node linkType: hard +"buffer-indexof@npm:^1.0.0": + version: 1.1.1 + resolution: "buffer-indexof@npm:1.1.1" + checksum: 0967abc2981a8e7d776324c6b84811e4d84a7ead89b54a3bb8791437f0c4751afd060406b06db90a436f1cf771867331b5ecf5c4aca95b4ccb9f6cb146c22ebc + languageName: node + linkType: hard + +"buffer-xor@npm:^1.0.3": + version: 1.0.3 + resolution: "buffer-xor@npm:1.0.3" + checksum: 10c520df29d62fa6e785e2800e586a20fc4f6dfad84bcdbd12e1e8a83856de1cb75c7ebd7abe6d036bbfab738a6cf18a3ae9c8e5a2e2eb3167ca7399ce65373a + languageName: node + linkType: hard + +"buffer@npm:^4.3.0": + version: 4.9.2 + resolution: "buffer@npm:4.9.2" + dependencies: + base64-js: ^1.0.2 + ieee754: ^1.1.4 + isarray: ^1.0.0 + checksum: 8801bc1ba08539f3be70eee307a8b9db3d40f6afbfd3cf623ab7ef41dffff1d0a31de0addbe1e66e0ca5f7193eeb667bfb1ecad3647f8f1b0750de07c13295c3 + languageName: node + linkType: hard + "buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" @@ -8155,14 +5989,21 @@ __metadata: languageName: node linkType: hard -"bundle-require@npm:^4.0.4": - version: 4.2.1 - resolution: "bundle-require@npm:4.2.1" +"builtin-status-codes@npm:^3.0.0": + version: 3.0.0 + resolution: "builtin-status-codes@npm:3.0.0" + checksum: 1119429cf4b0d57bf76b248ad6f529167d343156ebbcc4d4e4ad600484f6bc63002595cbb61b67ad03ce55cd1d3c4711c03bbf198bf24653b8392420482f3773 + languageName: node + linkType: hard + +"bundle-require@npm:^3.0.4": + version: 3.1.2 + resolution: "bundle-require@npm:3.1.2" dependencies: - load-tsconfig: ^0.2.3 + load-tsconfig: ^0.2.0 peerDependencies: - esbuild: ">=0.17" - checksum: dcf97683772bd9b1461bde9ba83d2dc0f13c5d7aeecfc9d6e3678b21eeb859a03ee815db03ed14af9d7b1311f39e99ce0487d6f67f9244381436eecf478c9a2c + esbuild: ">=0.13" + checksum: 71f8cb81bcde97825317b0e516b7e479ec70bd2370f55a8f02795c0df6d541e6562c4b9ec0427cc7b5b835103a8dcf306da04e3846fa468146358471490fcf81 languageName: node linkType: hard @@ -8175,7 +6016,14 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.1.2, bytes@npm:^3.1.2": +"bytes@npm:3.0.0": + version: 3.0.0 + resolution: "bytes@npm:3.0.0" + checksum: a2b386dd8188849a5325f58eef69c3b73c51801c08ffc6963eddc9be244089ba32d19347caf6d145c86f315ae1b1fc7061a32b0c1aa6379e6a719090287ed101 + languageName: node + linkType: hard + +"bytes@npm:3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: e4bcd3948d289c5127591fbedf10c0b639ccbf00243504e4e127374a15c3bc8eed0d28d4aaab08ff6f1cf2abc0cce6ba3085ed32f4f90e82a5683ce0014e1b6e @@ -8189,11 +6037,60 @@ __metadata: languageName: node linkType: hard -"cacache@npm:^19.0.1": - version: 19.0.1 - resolution: "cacache@npm:19.0.1" +"cacache@npm:^12.0.2": + version: 12.0.4 + resolution: "cacache@npm:12.0.4" + dependencies: + bluebird: ^3.5.5 + chownr: ^1.1.1 + figgy-pudding: ^3.5.1 + glob: ^7.1.4 + graceful-fs: ^4.1.15 + infer-owner: ^1.0.3 + lru-cache: ^5.1.1 + mississippi: ^3.0.0 + mkdirp: ^0.5.1 + move-concurrently: ^1.0.1 + promise-inflight: ^1.0.1 + rimraf: ^2.6.3 + ssri: ^6.0.1 + unique-filename: ^1.1.1 + y18n: ^4.0.0 + checksum: c88a72f36939b2523533946ffb27828443db5bf5995d761b35ae17af1eb6c8e20ac55b00b74c2ca900b2e1e917f0afba6847bf8cc16bee05ccca6aa150e0830c + languageName: node + linkType: hard + +"cacache@npm:^15.0.5": + version: 15.3.0 + resolution: "cacache@npm:15.3.0" + dependencies: + "@npmcli/fs": ^1.0.0 + "@npmcli/move-file": ^1.0.1 + chownr: ^2.0.0 + fs-minipass: ^2.0.0 + glob: ^7.1.4 + infer-owner: ^1.0.4 + lru-cache: ^6.0.0 + minipass: ^3.1.1 + minipass-collect: ^1.0.2 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.2 + mkdirp: ^1.0.3 + p-map: ^4.0.0 + promise-inflight: ^1.0.1 + rimraf: ^3.0.2 + ssri: ^8.0.1 + tar: ^6.0.2 + unique-filename: ^1.1.1 + checksum: a07327c27a4152c04eb0a831c63c00390d90f94d51bb80624a66f4e14a6b6360bbf02a84421267bd4d00ca73ac9773287d8d7169e8d2eafe378d2ce140579db8 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.2 + resolution: "cacache@npm:18.0.2" dependencies: - "@npmcli/fs": ^4.0.0 + "@npmcli/fs": ^3.1.0 fs-minipass: ^3.0.0 glob: ^10.2.2 lru-cache: ^10.0.1 @@ -8201,43 +6098,66 @@ __metadata: 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 - checksum: e95684717de6881b4cdaa949fa7574e3171946421cd8291769dd3d2417dbf7abf4aa557d1f968cca83dcbc95bed2a281072b09abfc977c942413146ef7ed4525 + p-map: ^4.0.0 + ssri: ^10.0.0 + tar: ^6.1.11 + unique-filename: ^3.0.0 + checksum: 0250df80e1ad0c828c956744850c5f742c24244e9deb5b7dc81bca90f8c10e011e132ecc58b64497cc1cad9a98968676147fb6575f4f94722f7619757b17a11b languageName: node linkType: hard -"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": - version: 1.0.2 - resolution: "call-bind-apply-helpers@npm:1.0.2" +"cache-base@npm:^1.0.1": + version: 1.0.1 + resolution: "cache-base@npm:1.0.1" dependencies: - es-errors: ^1.3.0 - function-bind: ^1.1.2 - checksum: b2863d74fcf2a6948221f65d95b91b4b2d90cfe8927650b506141e669f7d5de65cea191bf788838bc40d13846b7886c5bc5c84ab96c3adbcf88ad69a72fcdc6b + collection-visit: ^1.0.0 + component-emitter: ^1.2.1 + get-value: ^2.0.6 + has-value: ^1.0.0 + isobject: ^3.0.1 + set-value: ^2.0.0 + to-object-path: ^0.3.0 + union-value: ^1.0.0 + unset-value: ^1.0.0 + checksum: 9114b8654fe2366eedc390bad0bcf534e2f01b239a888894e2928cb58cdc1e6ea23a73c6f3450dcfd2058aa73a8a981e723cd1e7c670c047bf11afdc65880107 languageName: node linkType: hard -"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": - version: 1.0.8 - resolution: "call-bind@npm:1.0.8" +"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" dependencies: - call-bind-apply-helpers: ^1.0.0 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.2 - checksum: aa2899bce917a5392fd73bd32e71799c37c0b7ab454e0ed13af7f6727549091182aade8bbb7b55f304a5bc436d543241c14090fb8a3137e9875e23f444f4f5a9 + set-function-length: ^1.2.1 + checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029 languageName: node linkType: hard -"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4": - version: 1.0.4 - resolution: "call-bound@npm:1.0.4" +"caller-callsite@npm:^2.0.0": + version: 2.0.0 + resolution: "caller-callsite@npm:2.0.0" + dependencies: + callsites: ^2.0.0 + checksum: b685e9d126d9247b320cfdfeb3bc8da0c4be28d8fb98c471a96bc51aab3130099898a2fe3bf0308f0fe048d64c37d6d09f563958b9afce1a1e5e63d879c128a2 + languageName: node + linkType: hard + +"caller-path@npm:^2.0.0": + version: 2.0.0 + resolution: "caller-path@npm:2.0.0" dependencies: - call-bind-apply-helpers: ^1.0.2 - get-intrinsic: ^1.3.0 - checksum: 2f6399488d1c272f56306ca60ff696575e2b7f31daf23bc11574798c84d9f2759dceb0cb1f471a85b77f28962a7ac6411f51d283ea2e45319009a19b6ccab3b2 + caller-callsite: ^2.0.0 + checksum: 3e12ccd0c71ec10a057aac69e3ec175b721ca858c640df021ef0d25999e22f7c1d864934b596b7d47038e9b56b7ec315add042abbd15caac882998b50102fb12 + languageName: node + linkType: hard + +"callsites@npm:^2.0.0": + version: 2.0.0 + resolution: "callsites@npm:2.0.0" + checksum: be2f67b247df913732b7dec1ec0bbfcdbaea263e5a95968b19ec7965affae9496b970e3024317e6d4baa8e28dc6ba0cec03f46fdddc2fdcc51396600e53c2623 languageName: node linkType: hard @@ -8248,7 +6168,7 @@ __metadata: languageName: node linkType: hard -"camel-case@npm:^4.1.2": +"camel-case@npm:^4.1.1, camel-case@npm:^4.1.2": version: 4.1.2 resolution: "camel-case@npm:4.1.2" dependencies: @@ -8258,21 +6178,14 @@ __metadata: languageName: node linkType: hard -"camelcase-css@npm:^2.0.1": - version: 2.0.1 - resolution: "camelcase-css@npm:2.0.1" - checksum: 1cec2b3b3dcb5026688a470b00299a8db7d904c4802845c353dbd12d9d248d3346949a814d83bfd988d4d2e5b9904c07efe76fecd195a1d4f05b543e7c0b56b1 - languageName: node - linkType: hard - -"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": +"camelcase@npm:5.3.1, camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" checksum: e6effce26b9404e3c0f301498184f243811c30dfe6d0b9051863bd8e4034d09c8c2923794f280d6827e5aa055f6c434115ff97864a16a963366fb35fd673024b languageName: node linkType: hard -"camelcase@npm:^6.2.0, camelcase@npm:^6.2.1": +"camelcase@npm:^6.0.0, camelcase@npm:^6.1.0, camelcase@npm:^6.2.0": version: 6.3.0 resolution: "camelcase@npm:6.3.0" checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d @@ -8291,21 +6204,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001741": - version: 1.0.30001741 - resolution: "caniuse-lite@npm:1.0.30001741" - checksum: 0f2e90e1418a0b35923735420a0a0f9d2aa91eb6e0e2ae955e386155b402892ed4aa9996aae644b9f0cf2cf6a2af52c9467d4f8fc1d1710e8e4c961f12bdec67 - languageName: node - linkType: hard - -"canvas@npm:^3.0.0-rc2": - version: 3.2.0 - resolution: "canvas@npm:3.2.0" - dependencies: - node-addon-api: ^7.0.0 - node-gyp: latest - prebuild-install: ^7.1.3 - checksum: 68c7fe3c0c79efb3358d4ab4b04586068fefe06c7137e6636111ae91e68122ac069f05d883fdf11eb7fd08eba841096cb700324d02efca7abbf92d3476c567e4 +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001125, caniuse-lite@npm:^1.0.30001587": + version: 1.0.30001612 + resolution: "caniuse-lite@npm:1.0.30001612" + checksum: 2b6ab6a19c72bdf8dccac824944e828a2a1fae52c6dfeb2d64ccecfd60d0466d2e5a392e996da2150d92850188a5034666dceed34a38d978177f6934e0bf106d languageName: node linkType: hard @@ -8320,34 +6222,59 @@ __metadata: languageName: node linkType: hard -"case-sensitive-paths-webpack-plugin@npm:^2.4.0": - version: 2.4.0 - resolution: "case-sensitive-paths-webpack-plugin@npm:2.4.0" - checksum: bcf469446eeee9ac0046e30860074ebb9aa4803aab9140e6bb72b600b23b1d70635690754be4504ce35cd99cdf05226bee8d894ba362a3f5485d5f6310fc6d02 +"capture-exit@npm:^2.0.0": + version: 2.0.0 + resolution: "capture-exit@npm:2.0.0" + dependencies: + rsvp: ^4.8.4 + checksum: 0b9f10daca09e521da9599f34c8e7af14ad879c336e2bdeb19955b375398ae1c5bcc91ac9f2429944343057ee9ed028b1b2fb28816c384e0e55d70c439b226f4 languageName: node linkType: hard -"ccount@npm:^2.0.0": - version: 2.0.1 - resolution: "ccount@npm:2.0.1" - checksum: 48193dada54c9e260e0acf57fc16171a225305548f9ad20d5471e0f7a8c026aedd8747091dccb0d900cde7df4e4ddbd235df0d8de4a64c71b12f0d3303eeafd4 +"case-sensitive-paths-webpack-plugin@npm:2.3.0": + version: 2.3.0 + resolution: "case-sensitive-paths-webpack-plugin@npm:2.3.0" + checksum: 2fa78f7a495d7e73e66d1f528eac5abde65df797c9487624eeae9815a409ba6d584d8fbfe8b6c89157292fbb08d0ee6cc3418fe7f8c75b83fb2c8e29c30f205d languageName: node linkType: hard -"chai@npm:^5.1.2, chai@npm:^5.2.0": - version: 5.3.3 - resolution: "chai@npm:5.3.3" +"chai@npm:^4.3.7": + version: 4.4.1 + resolution: "chai@npm:4.4.1" + dependencies: + assertion-error: ^1.1.0 + check-error: ^1.0.3 + deep-eql: ^4.1.3 + get-func-name: ^2.0.2 + loupe: ^2.3.6 + pathval: ^1.1.1 + type-detect: ^4.0.8 + checksum: 9ab84f36eb8e0b280c56c6c21ca4da5933132cd8a0c89c384f1497f77953640db0bc151edd47f81748240a9fab57b78f7d925edfeedc8e8fc98016d71f40c36e + languageName: node + linkType: hard + +"chalk@npm:2.4.2, chalk@npm:^2.4.1, chalk@npm:^2.4.2": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: ^3.2.1 + escape-string-regexp: ^1.0.5 + supports-color: ^5.3.0 + checksum: ec3661d38fe77f681200f878edbd9448821924e0f93a9cefc0e26a33b145f1027a2084bf19967160d11e1f03bfe4eaffcabf5493b89098b2782c3fe0b03d80c2 + languageName: node + linkType: hard + +"chalk@npm:4.1.1": + version: 4.1.1 + resolution: "chalk@npm:4.1.1" dependencies: - assertion-error: ^2.0.1 - check-error: ^2.1.1 - deep-eql: ^5.0.1 - loupe: ^3.1.0 - pathval: ^2.0.0 - checksum: bc4091f1cccfee63f6a3d02ce477fe847f5c57e747916a11bd72675c9459125084e2e55dc2363ee2b82b088a878039ee7ee27c75d6d90f7de9202bf1b12ce573 + ansi-styles: ^4.1.0 + supports-color: ^7.1.0 + checksum: 036e973e665ba1a32c975e291d5f3d549bceeb7b1b983320d4598fb75d70fe20c5db5d62971ec0fe76cdbce83985a00ee42372416abfc3a5584465005a7855ed languageName: node linkType: hard -"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2": +"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.1": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -8357,14 +6284,26 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^2.4.1, chalk@npm:^2.4.2": - version: 2.4.2 - resolution: "chalk@npm:2.4.2" +"chalk@npm:^1.1.3": + version: 1.1.3 + resolution: "chalk@npm:1.1.3" dependencies: - ansi-styles: ^3.2.1 - escape-string-regexp: ^1.0.5 - supports-color: ^5.3.0 - checksum: ec3661d38fe77f681200f878edbd9448821924e0f93a9cefc0e26a33b145f1027a2084bf19967160d11e1f03bfe4eaffcabf5493b89098b2782c3fe0b03d80c2 + ansi-styles: ^2.2.1 + escape-string-regexp: ^1.0.2 + has-ansi: ^2.0.0 + strip-ansi: ^3.0.0 + supports-color: ^2.0.0 + checksum: 9d2ea6b98fc2b7878829eec223abcf404622db6c48396a9b9257f6d0ead2acf18231ae368d6a664a83f272b0679158da12e97b5229f794939e555cc574478acd + languageName: node + linkType: hard + +"chalk@npm:^3.0.0": + version: 3.0.0 + resolution: "chalk@npm:3.0.0" + dependencies: + ansi-styles: ^4.1.0 + supports-color: ^7.1.0 + checksum: 8e3ddf3981c4da405ddbd7d9c8d91944ddf6e33d6837756979f7840a29272a69a5189ecae0ff84006750d6d1e92368d413335eab4db5476db6e6703a1d1e0505 languageName: node linkType: hard @@ -8395,63 +6334,40 @@ __metadata: languageName: node linkType: hard -"char-regex@npm:^2.0.0": - version: 2.0.2 - resolution: "char-regex@npm:2.0.2" - checksum: 4965154ccf32b39c0f31df79e17686ee22fb6ebea774b6128e1d020cf2b01a3319bb608bfa2dba53cd478bed2f1991ac5246bee5ff93d0217ff7514e404694ed - languageName: node - linkType: hard - -"character-entities-html4@npm:^2.0.0": - version: 2.1.0 - resolution: "character-entities-html4@npm:2.1.0" - checksum: 7034aa7c7fa90309667f6dd50499c8a760c3d3a6fb159adb4e0bada0107d194551cdbad0714302f62d06ce4ed68565c8c2e15fdef2e8f8764eb63fa92b34b11d +"character-entities-legacy@npm:^1.0.0": + version: 1.1.4 + resolution: "character-entities-legacy@npm:1.1.4" + checksum: fe03a82c154414da3a0c8ab3188e4237ec68006cbcd681cf23c7cfb9502a0e76cd30ab69a2e50857ca10d984d57de3b307680fff5328ccd427f400e559c3a811 languageName: node linkType: hard -"character-entities-legacy@npm:^3.0.0": - version: 3.0.0 - resolution: "character-entities-legacy@npm:3.0.0" - checksum: 7582af055cb488b626d364b7d7a4e46b06abd526fb63c0e4eb35bcb9c9799cc4f76b39f34fdccef2d1174ac95e53e9ab355aae83227c1a2505877893fce77731 +"character-entities@npm:^1.0.0": + version: 1.2.4 + resolution: "character-entities@npm:1.2.4" + checksum: e1545716571ead57beac008433c1ff69517cd8ca5b336889321c5b8ff4a99c29b65589a701e9c086cda8a5e346a67295e2684f6c7ea96819fe85cbf49bf8686d languageName: node linkType: hard -"character-entities@npm:^2.0.0": - version: 2.0.2 - resolution: "character-entities@npm:2.0.2" - checksum: cf1643814023697f725e47328fcec17923b8f1799102a8a79c1514e894815651794a2bffd84bb1b3a4b124b050154e4529ed6e81f7c8068a734aecf07a6d3def +"character-reference-invalid@npm:^1.0.0": + version: 1.1.4 + resolution: "character-reference-invalid@npm:1.1.4" + checksum: 20274574c70e05e2f81135f3b93285536bc8ff70f37f0809b0d17791a832838f1e49938382899ed4cb444e5bbd4314ca1415231344ba29f4222ce2ccf24fea0b languageName: node linkType: hard -"character-reference-invalid@npm:^2.0.0": - version: 2.0.1 - resolution: "character-reference-invalid@npm:2.0.1" - checksum: 98d3b1a52ae510b7329e6ee7f6210df14f1e318c5415975d4c9e7ee0ef4c07875d47c6e74230c64551f12f556b4a8ccc24d9f3691a2aa197019e72a95e9297ee +"chardet@npm:^0.7.0": + version: 0.7.0 + resolution: "chardet@npm:0.7.0" + checksum: 6fd5da1f5d18ff5712c1e0aed41da200d7c51c28f11b36ee3c7b483f3696dabc08927fc6b227735eb8f0e1215c9a8abd8154637f3eff8cada5959df7f58b024d languageName: node linkType: hard -"chart.js@npm:4.4.6": - version: 4.4.6 - resolution: "chart.js@npm:4.4.6" +"check-error@npm:^1.0.3": + version: 1.0.3 + resolution: "check-error@npm:1.0.3" dependencies: - "@kurkle/color": ^0.3.0 - checksum: 4dcf6aa20f41115bb9e848d3053960eb4eeaaa94272344cc2b9b8faba33316c43893311897e20cd2bcd5b7963333cb30b7805829b78918d1d8c14a9e772e0c87 - languageName: node - linkType: hard - -"chartjs-plugin-datalabels@npm:^2.2.0": - version: 2.2.0 - resolution: "chartjs-plugin-datalabels@npm:2.2.0" - peerDependencies: - chart.js: ">=3.0.0" - checksum: 26086a908a8e88507959b7aaf798b2d9794ea95f7a5889b8bb9f6b9f3437a7e2fdf18952d3ba403b2ff78e5b70452439fb323bd0dfe76e9d7d1dae1328dacb99 - languageName: node - linkType: hard - -"check-error@npm:^2.1.1": - version: 2.1.1 - resolution: "check-error@npm:2.1.1" - checksum: d785ed17b1d4a4796b6e75c765a9a290098cf52ff9728ce0756e8ffd4293d2e419dd30c67200aee34202463b474306913f2fcfaf1890641026d9fc6966fea27a + get-func-name: ^2.0.2 + checksum: e2131025cf059b21080f4813e55b3c480419256914601750b0fee3bd9b2b8315b531e551ef12560419b8b6d92a3636511322752b1ce905703239e7cc451b6399 languageName: node linkType: hard @@ -8462,7 +6378,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.4.2, chokidar@npm:^3.5.2, chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": +"chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.4.1, chokidar@npm:^3.4.2, chokidar@npm:^3.5.2, chokidar@npm:^3.5.3": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -8481,12 +6397,26 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^4.0.0": - version: 4.0.3 - resolution: "chokidar@npm:4.0.3" +"chokidar@npm:^2.1.8": + version: 2.1.8 + resolution: "chokidar@npm:2.1.8" dependencies: - readdirp: ^4.0.1 - checksum: a8765e452bbafd04f3f2fad79f04222dd65f43161488bb6014a41099e6ca18d166af613d59a90771908c1c823efa3f46ba36b86ac50b701c20c1b9908c5fe36e + anymatch: ^2.0.0 + async-each: ^1.0.1 + braces: ^2.3.2 + fsevents: ^1.2.7 + glob-parent: ^3.1.0 + inherits: ^2.0.3 + is-binary-path: ^1.0.0 + is-glob: ^4.0.0 + normalize-path: ^3.0.0 + path-is-absolute: ^1.0.0 + readdirp: ^2.2.1 + upath: ^1.1.1 + dependenciesMeta: + fsevents: + optional: true + checksum: 0c43e89cbf0268ef1e1f41ce8ec5233c7ba022c6f3282c2ef6530e351d42396d389a1148c5a040f291cf1f4083a4c6b2f51dad3f31c726442ea9a337de316bcf languageName: node linkType: hard @@ -8497,17 +6427,24 @@ __metadata: languageName: node linkType: hard -"chownr@npm:^3.0.0": - version: 3.0.0 - resolution: "chownr@npm:3.0.0" - checksum: fd73a4bab48b79e66903fe1cafbdc208956f41ea4f856df883d0c7277b7ab29fd33ee65f93b2ec9192fc0169238f2f8307b7735d27c155821d886b84aa97aa8d +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f languageName: node linkType: hard "chrome-trace-event@npm:^1.0.2": - version: 1.0.4 - resolution: "chrome-trace-event@npm:1.0.4" - checksum: fcbbd9dd0cd5b48444319007cc0c15870fd8612cc0df320908aa9d5e8a244084d48571eb28bf3c58c19327d2c5838f354c2d89fac3956d8e992273437401ac19 + version: 1.0.3 + resolution: "chrome-trace-event@npm:1.0.3" + checksum: cb8b1fc7e881aaef973bd0c4a43cd353c2ad8323fb471a041e64f7c2dd849cde4aad15f8b753331a32dda45c973f032c8a03b8177fc85d60eaa75e91e08bfb97 + languageName: node + linkType: hard + +"ci-info@npm:^2.0.0": + version: 2.0.0 + resolution: "ci-info@npm:2.0.0" + checksum: 3b374666a85ea3ca43fa49aa3a048d21c9b475c96eb13c133505d2324e7ae5efd6a454f41efe46a152269e9b6a00c9edbe63ec7fa1921957165aae16625acd67 languageName: node linkType: hard @@ -8518,10 +6455,32 @@ __metadata: languageName: node linkType: hard -"cjs-module-lexer@npm:^1.0.0": - version: 1.4.3 - resolution: "cjs-module-lexer@npm:1.4.3" - checksum: 221a1661a9ff4944b472c85ac7cd5029b2f2dc7f6c5f4ecf887f261503611110b43a48acb6c07f8f04109c772d1637fdb20b31252bf27058f35aa97bf5ad8b12 +"cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": + version: 1.0.4 + resolution: "cipher-base@npm:1.0.4" + dependencies: + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: 47d3568dbc17431a339bad1fe7dff83ac0891be8206911ace3d3b818fc695f376df809bea406e759cdea07fff4b454fa25f1013e648851bec790c1d75763032e + languageName: node + linkType: hard + +"cjs-module-lexer@npm:^0.6.0": + version: 0.6.0 + resolution: "cjs-module-lexer@npm:0.6.0" + checksum: 445b039607efd74561d7db8d0867031c8b6a69f25e83fdd861b0fa1fbc11f12de057ba1db80637f3c9016774354092af5325eebb90505d65ccc5389cae09d1fd + languageName: node + linkType: hard + +"class-utils@npm:^0.3.5": + version: 0.3.6 + resolution: "class-utils@npm:0.3.6" + dependencies: + arr-union: ^3.1.0 + define-property: ^0.2.5 + isobject: ^3.0.0 + static-extend: ^0.1.1 + checksum: be108900801e639e50f96a7e4bfa8867c753a7750a7603879f3981f8b0a89cba657497a2d5f40cd4ea557ff15d535a100818bb486baf6e26fe5d7872e75f1078 languageName: node linkType: hard @@ -8532,19 +6491,53 @@ __metadata: languageName: node linkType: hard -"clean-css@npm:^5.2.2": - version: 5.3.3 - resolution: "clean-css@npm:5.3.3" +"clean-css@npm:^4.2.3": + version: 4.2.4 + resolution: "clean-css@npm:4.2.4" dependencies: source-map: ~0.6.0 - checksum: 941987c14860dd7d346d5cf121a82fd2caf8344160b1565c5387f7ccca4bbcaf885bace961be37c4f4713ce2d8c488dd89483c1add47bb779790edbfdcc79cbc + checksum: 045ff6fcf4b5c76a084b24e1633e0c78a13b24080338fc8544565a9751559aa32ff4ee5886d9e52c18a644a6ff119bd8e37bc58e574377c05382a1fb7dbe39f8 languageName: node linkType: hard -"cli-width@npm:^4.1.0": - version: 4.1.0 - resolution: "cli-width@npm:4.1.0" - checksum: 0a79cff2dbf89ef530bcd54c713703ba94461457b11e5634bd024c78796ed21401e32349c004995954e06f442d82609287e7aabf6a5f02c919a1cf3b9b6854ff +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"cli-cursor@npm:^3.1.0": + version: 3.1.0 + resolution: "cli-cursor@npm:3.1.0" + dependencies: + restore-cursor: ^3.1.0 + checksum: 2692784c6cd2fd85cfdbd11f53aea73a463a6d64a77c3e098b2b4697a20443f430c220629e1ca3b195ea5ac4a97a74c2ee411f3807abf6df2b66211fec0c0a29 + languageName: node + linkType: hard + +"cli-spinners@npm:^2.5.0": + version: 2.9.2 + resolution: "cli-spinners@npm:2.9.2" + checksum: 1bd588289b28432e4676cb5d40505cfe3e53f2e4e10fbe05c8a710a154d6fe0ce7836844b00d6858f740f2ffe67cdc36e0fce9c7b6a8430e80e6388d5aa4956c + languageName: node + linkType: hard + +"cli-width@npm:^3.0.0": + version: 3.0.0 + resolution: "cli-width@npm:3.0.0" + checksum: 4c94af3769367a70e11ed69aa6095f1c600c0ff510f3921ab4045af961820d57c0233acfa8b6396037391f31b4c397e1f614d234294f979ff61430a6c166c3f6 + languageName: node + linkType: hard + +"cliui@npm:^5.0.0": + version: 5.0.0 + resolution: "cliui@npm:5.0.0" + dependencies: + string-width: ^3.1.0 + strip-ansi: ^5.2.0 + wrap-ansi: ^5.1.0 + checksum: 0bb8779efe299b8f3002a73619eaa8add4081eb8d1c17bc4fedc6240557fb4eacdc08fe87c39b002eacb6cfc117ce736b362dbfd8bf28d90da800e010ee97df4 languageName: node linkType: hard @@ -8559,17 +6552,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^7.0.2": - version: 7.0.4 - resolution: "cliui@npm:7.0.4" - dependencies: - string-width: ^4.2.0 - strip-ansi: ^6.0.0 - wrap-ansi: ^7.0.0 - checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f - languageName: node - linkType: hard - "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -8581,6 +6563,13 @@ __metadata: languageName: node linkType: hard +"clone@npm:^1.0.2": + version: 1.0.4 + resolution: "clone@npm:1.0.4" + checksum: d06418b7335897209e77bdd430d04f882189582e67bd1f75a04565f3f07f5b3f119a9d670c943b6697d0afb100f03b866b3b8a1f91d4d02d72c4ecf2bb64b5dd + languageName: node + linkType: hard + "clsx@npm:^1.2.1": version: 1.2.1 resolution: "clsx@npm:1.2.1" @@ -8588,7 +6577,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.0.0, clsx@npm:^2.1.1": +"clsx@npm:^2.0.0, clsx@npm:^2.1.0": version: 2.1.1 resolution: "clsx@npm:2.1.1" checksum: acd3e1ab9d8a433ecb3cc2f6a05ab95fe50b4a3cfc5ba47abb6cbf3754585fcb87b84e90c822a1f256c4198e3b41c7f6c391577ffc8678ad587fc0976b24fd57 @@ -8620,7 +6609,17 @@ __metadata: languageName: node linkType: hard -"color-convert@npm:^1.9.0": +"collection-visit@npm:^1.0.0": + version: 1.0.0 + resolution: "collection-visit@npm:1.0.0" + dependencies: + map-visit: ^1.0.0 + object-visit: ^1.0.0 + checksum: 15d9658fe6eb23594728346adad5433b86bb7a04fd51bbab337755158722f9313a5376ef479de5b35fbc54140764d0d39de89c339f5d25b959ed221466981da9 + languageName: node + linkType: hard + +"color-convert@npm:^1.9.0, color-convert@npm:^1.9.3": version: 1.9.3 resolution: "color-convert@npm:1.9.3" dependencies: @@ -8645,28 +6644,34 @@ __metadata: languageName: node linkType: hard -"color-name@npm:~1.1.4": +"color-name@npm:^1.0.0, color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 languageName: node linkType: hard -"colord@npm:^2.9.1": - version: 2.9.3 - resolution: "colord@npm:2.9.3" - checksum: 95d909bfbcfd8d5605cbb5af56f2d1ce2b323990258fd7c0d2eb0e6d3bb177254d7fb8213758db56bb4ede708964f78c6b992b326615f81a18a6aaf11d64c650 +"color-string@npm:^1.6.0": + version: 1.9.1 + resolution: "color-string@npm:1.9.1" + dependencies: + color-name: ^1.0.0 + simple-swizzle: ^0.2.2 + checksum: c13fe7cff7885f603f49105827d621ce87f4571d78ba28ef4a3f1a104304748f620615e6bf065ecd2145d0d9dad83a3553f52bb25ede7239d18e9f81622f1cc5 languageName: node linkType: hard -"colorette@npm:^2.0.10": - version: 2.0.20 - resolution: "colorette@npm:2.0.20" - checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d +"color@npm:^3.0.0": + version: 3.2.1 + resolution: "color@npm:3.2.1" + dependencies: + color-convert: ^1.9.3 + color-string: ^1.6.0 + checksum: f81220e8b774d35865c2561be921f5652117638dcda7ca4029262046e37fc2444ac7bbfdd110cf1fd9c074a4ee5eda8f85944ffbdda26186b602dd9bb05f6400 languageName: node linkType: hard -"combined-stream@npm:^1.0.8": +"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" dependencies: @@ -8675,10 +6680,10 @@ __metadata: languageName: node linkType: hard -"comma-separated-tokens@npm:^2.0.0": - version: 2.0.3 - resolution: "comma-separated-tokens@npm:2.0.3" - checksum: e3bf9e0332a5c45f49b90e79bcdb4a7a85f28d6a6f0876a94f1bb9b2bfbdbbb9292aac50e1e742d8c0db1e62a0229a106f57917e2d067fca951d81737651700d +"comma-separated-tokens@npm:^1.0.0": + version: 1.0.8 + resolution: "comma-separated-tokens@npm:1.0.8" + checksum: 0adcb07174fa4d08cf0f5c8e3aec40a36b5ff0c2c720e5e23f50fe02e6789d1d00a67036c80e0c1e1539f41d3e7f0101b074039dd833b4e4a59031b659d6ca0d languageName: node linkType: hard @@ -8689,27 +6694,13 @@ __metadata: languageName: node linkType: hard -"commander@npm:^4.0.0": +"commander@npm:^4.1.1": version: 4.1.1 resolution: "commander@npm:4.1.1" checksum: d7b9913ff92cae20cb577a4ac6fcc121bd6223319e54a40f51a14740a681ad5c574fd29a57da478a5f234a6fa6c52cbf0b7c641353e03c648b1ae85ba670b977 languageName: node linkType: hard -"commander@npm:^7.2.0": - version: 7.2.0 - resolution: "commander@npm:7.2.0" - checksum: 53501cbeee61d5157546c0bef0fedb6cdfc763a882136284bed9a07225f09a14b82d2a84e7637edfd1a679fb35ed9502fd58ef1d091e6287f60d790147f68ddc - languageName: node - linkType: hard - -"commander@npm:^8.3.0": - version: 8.3.0 - resolution: "commander@npm:8.3.0" - checksum: 0f82321821fc27b83bd409510bb9deeebcfa799ff0bf5d102128b500b7af22872c0c92cb6a0ebc5a4cf19c6b550fba9cedfa7329d18c6442a625f851377bacf0 - languageName: node - linkType: hard - "common-tags@npm:^1.8.0": version: 1.8.2 resolution: "common-tags@npm:1.8.2" @@ -8724,14 +6715,23 @@ __metadata: languageName: node linkType: hard -"component-emitter@npm:^1.3.0": +"component-emitter@npm:^1.2.1, component-emitter@npm:^1.3.0": version: 1.3.1 resolution: "component-emitter@npm:1.3.1" checksum: 94550aa462c7bd5a61c1bc480e28554aa306066930152d1b1844a0dd3845d4e5db7e261ddec62ae184913b3e59b55a2ad84093b9d3596a8f17c341514d6c483d languageName: node linkType: hard -"compressible@npm:~2.0.18": +"compose-function@npm:3.0.3": + version: 3.0.3 + resolution: "compose-function@npm:3.0.3" + dependencies: + arity-n: ^1.0.4 + checksum: 9f17d431e3ee4797c844f2870e13494079882ac3dbc54c143b7d99967b371908e0ce7ceb71c6aed61e2ecddbcd7bb437d91428a3d0e6569aee17a87fcbc7918f + languageName: node + linkType: hard + +"compressible@npm:~2.0.16": version: 2.0.18 resolution: "compressible@npm:2.0.18" dependencies: @@ -8741,17 +6741,17 @@ __metadata: linkType: hard "compression@npm:^1.7.4": - version: 1.8.1 - resolution: "compression@npm:1.8.1" + version: 1.7.4 + resolution: "compression@npm:1.7.4" dependencies: - bytes: 3.1.2 - compressible: ~2.0.18 + accepts: ~1.3.5 + bytes: 3.0.0 + compressible: ~2.0.16 debug: 2.6.9 - negotiator: ~0.6.4 - on-headers: ~1.1.0 - safe-buffer: 5.2.1 + on-headers: ~1.0.2 + safe-buffer: 5.1.2 vary: ~1.1.2 - checksum: 906325935180cd3507d30ed898fb129deccab03689383d55536245a94610f5003923bb14c95ee6adc8d658ee13be549407eb4346ef55169045f3e41e9969808e + checksum: 35c0f2eb1f28418978615dc1bc02075b34b1568f7f56c62d60f4214d4b7cc00d0f6d282b5f8a954f59872396bd770b6b15ffd8aa94c67d4bce9b8887b906999b languageName: node linkType: hard @@ -8762,7 +6762,7 @@ __metadata: languageName: node linkType: hard -"concat-stream@npm:^1.5.2": +"concat-stream@npm:^1.5.0, concat-stream@npm:^1.5.2": version: 1.6.2 resolution: "concat-stream@npm:1.6.2" dependencies: @@ -8786,34 +6786,50 @@ __metadata: languageName: node linkType: hard -"concurrently@npm:^9.1.0": - version: 9.2.1 - resolution: "concurrently@npm:9.2.1" +"concurrently@npm:^5.2.0": + version: 5.3.0 + resolution: "concurrently@npm:5.3.0" dependencies: - chalk: 4.1.2 - rxjs: 7.8.2 - shell-quote: 1.8.3 - supports-color: 8.1.1 - tree-kill: 1.2.2 - yargs: 17.7.2 + chalk: ^2.4.2 + date-fns: ^2.0.1 + lodash: ^4.17.15 + read-pkg: ^4.0.1 + rxjs: ^6.5.2 + spawn-command: ^0.0.2-1 + supports-color: ^6.1.0 + tree-kill: ^1.2.2 + yargs: ^13.3.0 bin: - conc: dist/bin/concurrently.js - concurrently: dist/bin/concurrently.js - checksum: 95c6cdde21b6304d53005d872318805f69e153d4cedfd4d720cc5776f56fbd073b38297cfe56bacfc8fbdba9b6c38ac1233739abd25b023761fd03b896a4cea5 + concurrently: bin/concurrently.js + checksum: e12f32eab48e50fc5b7752dc43db7c78f5b553efc625d3b8741c3dd3088ba0050cb8e506f008c8a5fe30d7980849639d12b359a5aea88fd16707a0161b05babb languageName: node linkType: hard -"confusing-browser-globals@npm:^1.0.11": +"confbox@npm:^0.1.7": + version: 0.1.7 + resolution: "confbox@npm:0.1.7" + checksum: bde836c26f5154a348b0c0a757f8a0138929e5737e0553be3c4f07a056abca618b861aa63ac3b22d344789b56be99a1382928933e08cd500df00213bf4d8fb43 + languageName: node + linkType: hard + +"confusing-browser-globals@npm:^1.0.10": version: 1.0.11 resolution: "confusing-browser-globals@npm:1.0.11" checksum: 3afc635abd37e566477f610e7978b15753f0e84025c25d49236f1f14d480117185516bdd40d2a2167e6bed8048641a9854964b9c067e3dcdfa6b5d0ad3c3a5ef languageName: node linkType: hard -"connect-history-api-fallback@npm:^2.0.0": - version: 2.0.0 - resolution: "connect-history-api-fallback@npm:2.0.0" - checksum: dc5368690f4a5c413889792f8df70d5941ca9da44523cde3f87af0745faee5ee16afb8195434550f0504726642734f2683d6c07f8b460f828a12c45fbd4c9a68 +"connect-history-api-fallback@npm:^1.6.0": + version: 1.6.0 + resolution: "connect-history-api-fallback@npm:1.6.0" + checksum: 804ca2be28c999032ecd37a9f71405e5d7b7a4b3defcebbe41077bb8c5a0a150d7b59f51dcc33b2de30bc7e217a31d10f8cfad27e8e74c2fc7655eeba82d6e7e + languageName: node + linkType: hard + +"console-browserify@npm:^1.1.0": + version: 1.2.0 + resolution: "console-browserify@npm:1.2.0" + checksum: 226591eeff8ed68e451dffb924c1fb750c654d54b9059b3b261d360f369d1f8f70650adecf2c7136656236a4bfeb55c39281b5d8a55d792ebbb99efd3d848d52 languageName: node linkType: hard @@ -8828,31 +6844,45 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:0.5.4": - version: 0.5.4 - resolution: "content-disposition@npm:0.5.4" - dependencies: - safe-buffer: 5.2.1 - checksum: afb9d545e296a5171d7574fcad634b2fdf698875f4006a9dd04a3e1333880c5c0c98d47b560d01216fb6505a54a2ba6a843ee3a02ec86d7e911e8315255f56c3 +"constants-browserify@npm:^1.0.0": + version: 1.0.0 + resolution: "constants-browserify@npm:1.0.0" + checksum: f7ac8c6d0b6e4e0c77340a1d47a3574e25abd580bfd99ad707b26ff7618596cf1a5e5ce9caf44715e9e01d4a5d12cb3b4edaf1176f34c19adb2874815a56e64f languageName: node linkType: hard -"content-disposition@npm:^1.0.0": - version: 1.0.0 - resolution: "content-disposition@npm:1.0.0" +"content-disposition@npm:0.5.4": + version: 0.5.4 + resolution: "content-disposition@npm:0.5.4" dependencies: safe-buffer: 5.2.1 - checksum: b27e2579fefe0ecf78238bb652fbc750671efce8344f0c6f05235b12433e6a965adb40906df1ac1fdde23e8f9f0e58385e44640e633165420f3f47d830ae0398 + checksum: afb9d545e296a5171d7574fcad634b2fdf698875f4006a9dd04a3e1333880c5c0c98d47b560d01216fb6505a54a2ba6a843ee3a02ec86d7e911e8315255f56c3 languageName: node linkType: hard -"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 566271e0a251642254cde0f845f9dd4f9856e52d988f4eb0d0dcffbb7a1f8ec98de7a5215fc628f3bce30fe2fb6fd2bc064b562d721658c59b544e2d34ea2766 languageName: node linkType: hard +"convert-source-map@npm:1.7.0": + version: 1.7.0 + resolution: "convert-source-map@npm:1.7.0" + dependencies: + safe-buffer: ~5.1.1 + checksum: bcd2e3ea7d37f96b85a6e362c8a89402ccc73757256e3ee53aa2c22fe915adb854c66b1f81111be815a3a6a6ce3c58e8001858e883c9d5b4fe08a853fa865967 + languageName: node + linkType: hard + +"convert-source-map@npm:^0.3.3": + version: 0.3.5 + resolution: "convert-source-map@npm:0.3.5" + checksum: 33b209aa8f33bcaa9a22f2dbf6bfb71f4a429d8e948068d61b6087304e3194c30016d1e02e842184e653b74442c7e2dd2e7db97532b67f556aded3d8b4377a2c + languageName: node + linkType: hard + "convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.5.0, convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0": version: 1.9.0 resolution: "convert-source-map@npm:1.9.0" @@ -8868,12 +6898,12 @@ __metadata: linkType: hard "cookie-parser@npm:^1.4.5": - version: 1.4.7 - resolution: "cookie-parser@npm:1.4.7" + version: 1.4.6 + resolution: "cookie-parser@npm:1.4.6" dependencies: - cookie: 0.7.2 + cookie: 0.4.1 cookie-signature: 1.0.6 - checksum: 243fa13f217e793d20a57675e6552beea08c5989fcc68495d543997a31646875335e0e82d687b42dcfd466df57891d22bae7f5ba6ab33b7705ed2dd6eb989105 + checksum: 1e5a63aa82e8eb4e02d2977c6902983dee87b02e87ec5ec43ac3cb1e72da354003716570cd5190c0ad9e8a454c9d3237f4ad6e2f16d0902205a96a1c72b77ba5 languageName: node linkType: hard @@ -8884,24 +6914,24 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:^1.2.1": - version: 1.2.2 - resolution: "cookie-signature@npm:1.2.2" - checksum: 1ad4f9b3907c9f3673a0f0a07c0a23da7909ac6c9204c5d80a0ec102fe50ccc45f27fdf496361840d6c132c5bb0037122c0a381f856d070183d1ebe3e5e041ff +"cookie@npm:0.4.1": + version: 0.4.1 + resolution: "cookie@npm:0.4.1" + checksum: bd7c47f5d94ab70ccdfe8210cde7d725880d2fcda06d8e375afbdd82de0c8d3b73541996e9ce57d35f67f672c4ee6d60208adec06b3c5fc94cebb85196084cf8 languageName: node linkType: hard -"cookie@npm:0.7.1": - version: 0.7.1 - resolution: "cookie@npm:0.7.1" - checksum: cec5e425549b3650eb5c3498a9ba3cde0b9cd419e3b36e4b92739d30b4d89e0b678b98c1ddc209ce7cf958cd3215671fd6ac47aec21f10c2a0cc68abd399d8a7 +"cookie@npm:0.6.0": + version: 0.6.0 + resolution: "cookie@npm:0.6.0" + checksum: f56a7d32a07db5458e79c726b77e3c2eff655c36792f2b6c58d351fb5f61531e5b1ab7f46987150136e366c65213cbe31729e02a3eaed630c3bf7334635fb410 languageName: node linkType: hard -"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:^0.7.2": - version: 0.7.2 - resolution: "cookie@npm:0.7.2" - checksum: 9bf8555e33530affd571ea37b615ccad9b9a34febbf2c950c86787088eb00a8973690833b0f8ebd6b69b753c62669ea60cec89178c1fb007bf0749abed74f93e +"cookie@npm:^0.4.2": + version: 0.4.2 + resolution: "cookie@npm:0.4.2" + checksum: a00833c998bedf8e787b4c342defe5fa419abd96b32f4464f718b91022586b8f1bafbddd499288e75c037642493c83083da426c6a9080d309e3bd90fd11baa9b languageName: node linkType: hard @@ -8912,26 +6942,54 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.43.0": - version: 3.45.1 - resolution: "core-js-compat@npm:3.45.1" +"copy-concurrently@npm:^1.0.0": + version: 1.0.5 + resolution: "copy-concurrently@npm:1.0.5" + dependencies: + aproba: ^1.1.1 + fs-write-stream-atomic: ^1.0.8 + iferr: ^0.1.5 + mkdirp: ^0.5.1 + rimraf: ^2.5.4 + run-queue: ^1.0.0 + checksum: 63c169f582e09445260988f697b2d07793d439dfc31e97c8999707bd188dd94d1c7f2ca3533c7786fb75f03a3f2f54ad1ee08055f95f61bb8d2e862498c1d460 + languageName: node + linkType: hard + +"copy-descriptor@npm:^0.1.0": + version: 0.1.1 + resolution: "copy-descriptor@npm:0.1.1" + checksum: d4b7b57b14f1d256bb9aa0b479241048afd7f5bcf22035fc7b94e8af757adeae247ea23c1a774fe44869fd5694efba4a969b88d966766c5245fdee59837fe45b + languageName: node + linkType: hard + +"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.36.1": + version: 3.37.0 + resolution: "core-js-compat@npm:3.37.0" dependencies: - browserslist: ^4.25.3 - checksum: 817286f6b7deb90278fd1f46131664fda36b74983e2fc4859a36ae85ef9361868b307964eea0e364251763e415eab7589e9abe2a4ec4d1672c2870f03c52b1ac + browserslist: ^4.23.0 + checksum: cab5078e98625f889fd9bbbb19e84cb408f31c87e68302d380db0d26ae8e35c1b38cde084358ff345d4aa461af5f3c60d8a913a5b30bff3a83b4b7859374db36 + languageName: node + linkType: hard + +"core-js-pure@npm:^3.30.2": + version: 3.37.0 + resolution: "core-js-pure@npm:3.37.0" + checksum: 206797d88046f4f5a62ecb9a7158bc6ba38127db2239bcbd1e85b2c8cf3cfb9bb3bbc6a312ecf0f87702f87659959d10625aeac74de6336a9303866f7010d364 languageName: node linkType: hard -"core-js-pure@npm:^3.23.3": - version: 3.45.1 - resolution: "core-js-pure@npm:3.45.1" - checksum: 7427bc4c8991acabc537bc30da5da9e7afb12754c7cf59d5271b01d1750d4b216c44e2ea298b4354efa83873eeeff62e71d858e5c9cd0a3a69fea933971a6a8d +"core-js@npm:^2.4.0": + version: 2.6.12 + resolution: "core-js@npm:2.6.12" + checksum: 44fa9934a85f8c78d61e0c8b7b22436330471ffe59ec5076fe7f324d6e8cf7f824b14b1c81ca73608b13bdb0fef035bd820989bf059767ad6fa13123bb8bd016 languageName: node linkType: hard -"core-js@npm:^3.19.2": - version: 3.45.1 - resolution: "core-js@npm:3.45.1" - checksum: 674c79e9c58ed923280cd4afbc3bc4c921b8b11bce70d269f1bd98db484e27f0ff436d1de34e198f27065a10386761b39f110309c471f329fe7376ab0fb32bf6 +"core-js@npm:^3.6.5": + version: 3.37.0 + resolution: "core-js@npm:3.37.0" + checksum: 212c3e9b3fc277dbb63739ef58a61c5709ccd0b36f09c3ce6946aa91fa180c60f57f976d4a5fdb9cda0c6cb55417379ba5a008fc3a1384ec94ec8ec61826469d languageName: node linkType: hard @@ -8952,16 +7010,15 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^6.0.0": - version: 6.0.0 - resolution: "cosmiconfig@npm:6.0.0" +"cosmiconfig@npm:^5.0.0": + version: 5.2.1 + resolution: "cosmiconfig@npm:5.2.1" dependencies: - "@types/parse-json": ^4.0.0 - import-fresh: ^3.1.0 - parse-json: ^5.0.0 - path-type: ^4.0.0 - yaml: ^1.7.2 - checksum: 8eed7c854b91643ecb820767d0deb038b50780ecc3d53b0b19e03ed8aabed4ae77271198d1ae3d49c3b110867edf679f5faad924820a8d1774144a87cb6f98fc + import-fresh: ^2.0.0 + is-directory: ^0.3.1 + js-yaml: ^3.13.1 + parse-json: ^4.0.0 + checksum: 8b6f1d3c8a5ffdf663a952f17af0761adf210b7a5933d0fe8988f3ca3a1f0e1e5cbbb74d5b419c15933dd2fdcaec31dbc5cc85cb8259a822342b93b529eff89c languageName: node linkType: hard @@ -8978,6 +7035,43 @@ __metadata: languageName: node linkType: hard +"create-ecdh@npm:^4.0.0": + version: 4.0.4 + resolution: "create-ecdh@npm:4.0.4" + dependencies: + bn.js: ^4.1.0 + elliptic: ^6.5.3 + checksum: 0dd7fca9711d09e152375b79acf1e3f306d1a25ba87b8ff14c2fd8e68b83aafe0a7dd6c4e540c9ffbdd227a5fa1ad9b81eca1f233c38bb47770597ba247e614b + languageName: node + linkType: hard + +"create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": + version: 1.2.0 + resolution: "create-hash@npm:1.2.0" + dependencies: + cipher-base: ^1.0.1 + inherits: ^2.0.1 + md5.js: ^1.3.4 + ripemd160: ^2.0.1 + sha.js: ^2.4.0 + checksum: 02a6ae3bb9cd4afee3fabd846c1d8426a0e6b495560a977ba46120c473cb283be6aa1cace76b5f927cf4e499c6146fb798253e48e83d522feba807d6b722eaa9 + languageName: node + linkType: hard + +"create-hmac@npm:^1.1.0, create-hmac@npm:^1.1.4, create-hmac@npm:^1.1.7": + version: 1.1.7 + resolution: "create-hmac@npm:1.1.7" + dependencies: + cipher-base: ^1.0.3 + create-hash: ^1.1.0 + inherits: ^2.0.1 + ripemd160: ^2.0.0 + safe-buffer: ^5.0.1 + sha.js: ^2.4.8 + checksum: ba12bb2257b585a0396108c72830e85f882ab659c3320c83584b1037f8ab72415095167ced80dc4ce8e446a8ecc4b2acf36d87befe0707d73b26cf9dc77440ed + languageName: node + linkType: hard + "create-require@npm:^1.1.0": version: 1.1.1 resolution: "create-require@npm:1.1.1" @@ -8985,125 +7079,140 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": - version: 7.0.6 - resolution: "cross-spawn@npm:7.0.6" +"cross-spawn@npm:7.0.3, cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" dependencies: path-key: ^3.1.0 shebang-command: ^2.0.0 which: ^2.0.1 - checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b + checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 languageName: node linkType: hard -"crypto-random-string@npm:^2.0.0": - version: 2.0.0 - resolution: "crypto-random-string@npm:2.0.0" - checksum: 0283879f55e7c16fdceacc181f87a0a65c53bc16ffe1d58b9d19a6277adcd71900d02bb2c4843dd55e78c51e30e89b0fec618a7f170ebcc95b33182c28f05fd6 +"cross-spawn@npm:^6.0.0": + version: 6.0.5 + resolution: "cross-spawn@npm:6.0.5" + dependencies: + nice-try: ^1.0.4 + path-key: ^2.0.1 + semver: ^5.5.0 + shebang-command: ^1.2.0 + which: ^1.2.9 + checksum: f893bb0d96cd3d5751d04e67145bdddf25f99449531a72e82dcbbd42796bbc8268c1076c6b3ea51d4d455839902804b94bc45dfb37ecbb32ea8e54a6741c3ab9 languageName: node linkType: hard -"css-blank-pseudo@npm:^3.0.3": - version: 3.0.3 - resolution: "css-blank-pseudo@npm:3.0.3" +"crypto-browserify@npm:^3.11.0": + version: 3.12.0 + resolution: "crypto-browserify@npm:3.12.0" dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 - bin: - css-blank-pseudo: dist/cli.cjs - checksum: 9be0a13885a99d8ba9e1f45ea66e801d4da75b58c1c3c516a40772fa3a93ef9952b15dcac0418acbb6c89daaae0572819647701b8e553a02972826e33d4cd67f + browserify-cipher: ^1.0.0 + browserify-sign: ^4.0.0 + create-ecdh: ^4.0.0 + create-hash: ^1.1.0 + create-hmac: ^1.1.0 + diffie-hellman: ^5.0.0 + inherits: ^2.0.1 + pbkdf2: ^3.0.3 + public-encrypt: ^4.0.0 + randombytes: ^2.0.0 + randomfill: ^1.0.3 + checksum: c1609af82605474262f3eaa07daa0b2140026bd264ab316d4bf1170272570dbe02f0c49e29407fe0d3634f96c507c27a19a6765fb856fed854a625f9d15618e2 languageName: node linkType: hard -"css-box-model@npm:^1.2.1": - version: 1.2.1 - resolution: "css-box-model@npm:1.2.1" +"crypto-random-string@npm:^1.0.0": + version: 1.0.0 + resolution: "crypto-random-string@npm:1.0.0" + checksum: 6fc61a46c18547b49a93da24f4559c4a1c859f4ee730ecc9533c1ba89fa2a9e9d81f390c2789467afbbd0d1c55a6e96a71e4716b6cd3e77736ed5fced7a2df9a + languageName: node + linkType: hard + +"css-blank-pseudo@npm:^0.1.4": + version: 0.1.4 + resolution: "css-blank-pseudo@npm:0.1.4" dependencies: - tiny-invariant: ^1.0.6 - checksum: 4d113f26fed6b9150e2c314502d00dabe06f12ae43a01a7e9b6e57f3de49b4281dbb0dc46a1158a7349618f8f34d9250af57cb43d7337e9485e73e6b821e470e + postcss: ^7.0.5 + bin: + css-blank-pseudo: cli.js + checksum: f995a6ca5dbb867af4b30c3dc872a8f0b27ad120442c34796eef7f9c4dcf014249522aaa0a2da3c101c4afa5d7d376436bb978ae1b2c02deddec283fad30c998 languageName: node linkType: hard -"css-declaration-sorter@npm:^6.3.1": - version: 6.4.1 - resolution: "css-declaration-sorter@npm:6.4.1" - peerDependencies: - postcss: ^8.0.9 - checksum: cbdc9e0d481011b1a28fd5b60d4eb55fe204391d31a0b1b490b2cecf4baa85810f9b8c48adab4df644f4718104ed3ed72c64a9745e3216173767bf4aeca7f9b8 +"css-color-names@npm:0.0.4, css-color-names@npm:^0.0.4": + version: 0.0.4 + resolution: "css-color-names@npm:0.0.4" + checksum: 9c6106320430a9da3a13daab8d8b4def39113edbfb68042444585d9a214af5fd5cb384b9be45124bc75f88261d461b517e00e278f4d2e0ab5a619b182f9f0e2d languageName: node linkType: hard -"css-has-pseudo@npm:^3.0.4": - version: 3.0.4 - resolution: "css-has-pseudo@npm:3.0.4" +"css-declaration-sorter@npm:^4.0.1": + version: 4.0.1 + resolution: "css-declaration-sorter@npm:4.0.1" dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 + postcss: ^7.0.1 + timsort: ^0.3.0 + checksum: c38c00245c6706bd1127a6a2807bbdea3a2621c1f4e4bcb4710f6736c15c4ec414e02213adeab2171623351616090cb96374f683b90ec2aad18903066c4526d7 + languageName: node + linkType: hard + +"css-has-pseudo@npm:^0.10.0": + version: 0.10.0 + resolution: "css-has-pseudo@npm:0.10.0" + dependencies: + postcss: ^7.0.6 + postcss-selector-parser: ^5.0.0-rc.4 bin: - css-has-pseudo: dist/cli.cjs - checksum: 8f165d68f6621891d9fa1d874794916a52ed8847dfbec591523ad68774650cc1eae062ba08f59514666e04aeba27be72c9b211892f3a187c5ba6e287bd4260e7 + css-has-pseudo: cli.js + checksum: 88d891ba18f821e8a94d821ecdd723c606019462664c7d86e7d8731622bd26f9d55582e494bcc2a62f9399cc7b89049ddc8a9d1e8f1bf1a133c2427739d2d334 languageName: node linkType: hard -"css-loader@npm:^6.5.1": - version: 6.11.0 - resolution: "css-loader@npm:6.11.0" - 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 +"css-loader@npm:4.3.0": + version: 4.3.0 + resolution: "css-loader@npm:4.3.0" + dependencies: + camelcase: ^6.0.0 + cssesc: ^3.0.0 + icss-utils: ^4.1.1 + loader-utils: ^2.0.0 + postcss: ^7.0.32 + postcss-modules-extract-imports: ^2.0.0 + postcss-modules-local-by-default: ^3.0.3 + postcss-modules-scope: ^2.2.0 + postcss-modules-values: ^3.0.0 + postcss-value-parser: ^4.1.0 + schema-utils: ^2.7.1 + semver: ^7.3.2 peerDependencies: - "@rspack/core": 0.x || 1.x - webpack: ^5.0.0 - peerDependenciesMeta: - "@rspack/core": - optional: true - webpack: - optional: true - checksum: 5c8d35975a7121334905394e88e28f05df72f037dbed2fb8fec4be5f0b313ae73a13894ba791867d4a4190c35896da84a7fd0c54fb426db55d85ba5e714edbe3 + webpack: ^4.27.0 || ^5.0.0 + checksum: 697a8838f0975f86c634e7a920572604879a9738128fcc01e5393fae5ac9a7a1a925c0d14ebb6ed67fa7e14bd17849eec152a99e3299cc92f422f6b0cd4eff73 languageName: node linkType: hard -"css-minimizer-webpack-plugin@npm:^3.2.0": - version: 3.4.1 - resolution: "css-minimizer-webpack-plugin@npm:3.4.1" +"css-modules-loader-core@npm:^1.1.0": + version: 1.1.0 + resolution: "css-modules-loader-core@npm:1.1.0" dependencies: - cssnano: ^5.0.6 - jest-worker: ^27.0.2 - postcss: ^8.3.5 - schema-utils: ^4.0.0 - serialize-javascript: ^6.0.0 - source-map: ^0.6.1 - peerDependencies: - webpack: ^5.0.0 - peerDependenciesMeta: - "@parcel/css": - optional: true - clean-css: - optional: true - csso: - optional: true - esbuild: - optional: true - checksum: 065c6c1eadb7c99267db5d04d6f3909e9968b73c4cb79ab9e4502a5fbf1a3d564cfe6f8e0bff8e4ab00d4ed233e9c3c76a4ebe0ee89150b3d9ecb064ddf1e5e9 + icss-replace-symbols: 1.1.0 + postcss: 6.0.1 + postcss-modules-extract-imports: 1.1.0 + postcss-modules-local-by-default: 1.2.0 + postcss-modules-scope: 1.1.0 + postcss-modules-values: 1.3.0 + checksum: e2d513cee6a407b46806e50b3eec9d9034355b6ee14f2f7303353ab0853b8dba9600cffc83ec46cebd3efd68fe2b2aa31808a1c906d043f1c405568fd484eaf5 languageName: node linkType: hard -"css-prefers-color-scheme@npm:^6.0.3": - version: 6.0.3 - resolution: "css-prefers-color-scheme@npm:6.0.3" - peerDependencies: - postcss: ^8.4 +"css-prefers-color-scheme@npm:^3.1.1": + version: 3.1.1 + resolution: "css-prefers-color-scheme@npm:3.1.1" + dependencies: + postcss: ^7.0.5 bin: - css-prefers-color-scheme: dist/cli.cjs - checksum: 3a2b02f0454adda68861cdcaf6a0d11f462eadf165301cba61c5ec7c5f229ac261c5baa54c377d9b811ec5f21b30d72a02bc032cdad2415b3a566f08a0c47b3a + css-prefers-color-scheme: cli.js + checksum: ba69a86b006818ffe3548bcbeb5e4e8139b8b6cf45815a3b3dddd12cd9acf3d8ac3b94e63fe0abd34e0683cf43ed8c2344e3bd472bbf02a6eb40c7bbf565d587 languageName: node linkType: hard @@ -9139,6 +7248,16 @@ __metadata: languageName: node linkType: hard +"css-selector-tokenizer@npm:^0.7.0": + version: 0.7.3 + resolution: "css-selector-tokenizer@npm:0.7.3" + dependencies: + cssesc: ^3.0.0 + fastparse: ^1.1.2 + checksum: 92560a9616a8bc073b88c678aa04f22c599ac23c5f8587e60f4861069e2d5aeb37b722af581ae3c5fbce453bed7a893d9c3e06830912e6d28badc3b8b99acd24 + languageName: node + linkType: hard + "css-tree@npm:1.0.0-alpha.37": version: 1.0.0-alpha.37 resolution: "css-tree@npm:1.0.0-alpha.37" @@ -9149,7 +7268,7 @@ __metadata: languageName: node linkType: hard -"css-tree@npm:^1.1.2, css-tree@npm:^1.1.3": +"css-tree@npm:^1.1.2": version: 1.1.3 resolution: "css-tree@npm:1.1.3" dependencies: @@ -9167,9 +7286,9 @@ __metadata: linkType: hard "css-what@npm:^6.0.1": - version: 6.2.2 - resolution: "css-what@npm:6.2.2" - checksum: 4d1f07b348a638e1f8b4c72804a1e93881f35e0f541256aec5ac0497c5855df7db7ab02da030de950d4813044f6d029a14ca657e0f92c3987e4b604246235b2b + version: 6.1.0 + resolution: "css-what@npm:6.1.0" + checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe languageName: node linkType: hard @@ -9180,10 +7299,31 @@ __metadata: languageName: node linkType: hard -"cssdb@npm:^7.1.0": - version: 7.11.2 - resolution: "cssdb@npm:7.11.2" - checksum: 79b2c3b6de1d80c7f3e40f28c06138b7f1ca27fe5d9173195cc781d8acc0261c2bdeccdf141bd035b13709655cf724c8ad4757ddf12a3d21b6d002368c9cb027 +"css@npm:^2.0.0": + version: 2.2.4 + resolution: "css@npm:2.2.4" + dependencies: + inherits: ^2.0.3 + source-map: ^0.6.1 + source-map-resolve: ^0.5.2 + urix: ^0.1.0 + checksum: a35d483c5ccc04bcde3b1e7393d58ad3eee1dd6956df0f152de38e46a17c0ee193c30eec6b1e59831ad0e74599385732000e95987fcc9cb2b16c6d951bae49e1 + languageName: node + linkType: hard + +"cssdb@npm:^4.4.0": + version: 4.4.0 + resolution: "cssdb@npm:4.4.0" + checksum: 521dd2135da1ab93612a4161eb1024cfc7b155a35d95f9867d328cc88ad57fdd959aa88ea8f4e6cea3a82bca91b76570dc1abb18bfd902c6889973956a03e497 + languageName: node + linkType: hard + +"cssesc@npm:^2.0.0": + version: 2.0.0 + resolution: "cssesc@npm:2.0.0" + bin: + cssesc: bin/cssesc + checksum: 5e50886c2aca3f492fe808dbd146d30eb1c6f31fbe6093979a8376e39d171d989279199f6f3f1a42464109e082e0e42bc33eeff9467fb69bf346f5ba5853c3c6 languageName: node linkType: hard @@ -9196,68 +7336,87 @@ __metadata: languageName: node linkType: hard -"cssnano-preset-default@npm:^5.2.14": - version: 5.2.14 - resolution: "cssnano-preset-default@npm:5.2.14" - dependencies: - css-declaration-sorter: ^6.3.1 - cssnano-utils: ^3.1.0 - postcss-calc: ^8.2.3 - postcss-colormin: ^5.3.1 - postcss-convert-values: ^5.1.3 - postcss-discard-comments: ^5.1.2 - postcss-discard-duplicates: ^5.1.0 - postcss-discard-empty: ^5.1.1 - postcss-discard-overridden: ^5.1.0 - postcss-merge-longhand: ^5.1.7 - postcss-merge-rules: ^5.1.4 - postcss-minify-font-values: ^5.1.0 - postcss-minify-gradients: ^5.1.1 - postcss-minify-params: ^5.1.4 - postcss-minify-selectors: ^5.2.1 - postcss-normalize-charset: ^5.1.0 - postcss-normalize-display-values: ^5.1.0 - postcss-normalize-positions: ^5.1.1 - postcss-normalize-repeat-style: ^5.1.1 - postcss-normalize-string: ^5.1.0 - postcss-normalize-timing-functions: ^5.1.0 - postcss-normalize-unicode: ^5.1.1 - postcss-normalize-url: ^5.1.0 - postcss-normalize-whitespace: ^5.1.1 - postcss-ordered-values: ^5.1.3 - postcss-reduce-initial: ^5.1.2 - postcss-reduce-transforms: ^5.1.0 - postcss-svgo: ^5.1.0 - postcss-unique-selectors: ^5.1.1 - peerDependencies: - postcss: ^8.2.15 - checksum: d3bbbe3d50c6174afb28d0bdb65b511fdab33952ec84810aef58b87189f3891c34aaa8b6a6101acd5314f8acded839b43513e39a75f91a698ddc985a1b1d9e95 +"cssnano-preset-default@npm:^4.0.8": + version: 4.0.8 + resolution: "cssnano-preset-default@npm:4.0.8" + dependencies: + css-declaration-sorter: ^4.0.1 + cssnano-util-raw-cache: ^4.0.1 + postcss: ^7.0.0 + postcss-calc: ^7.0.1 + postcss-colormin: ^4.0.3 + postcss-convert-values: ^4.0.1 + postcss-discard-comments: ^4.0.2 + postcss-discard-duplicates: ^4.0.2 + postcss-discard-empty: ^4.0.1 + postcss-discard-overridden: ^4.0.1 + postcss-merge-longhand: ^4.0.11 + postcss-merge-rules: ^4.0.3 + postcss-minify-font-values: ^4.0.2 + postcss-minify-gradients: ^4.0.2 + postcss-minify-params: ^4.0.2 + postcss-minify-selectors: ^4.0.2 + postcss-normalize-charset: ^4.0.1 + postcss-normalize-display-values: ^4.0.2 + postcss-normalize-positions: ^4.0.2 + postcss-normalize-repeat-style: ^4.0.2 + postcss-normalize-string: ^4.0.2 + postcss-normalize-timing-functions: ^4.0.2 + postcss-normalize-unicode: ^4.0.1 + postcss-normalize-url: ^4.0.1 + postcss-normalize-whitespace: ^4.0.2 + postcss-ordered-values: ^4.1.2 + postcss-reduce-initial: ^4.0.3 + postcss-reduce-transforms: ^4.0.2 + postcss-svgo: ^4.0.3 + postcss-unique-selectors: ^4.0.1 + checksum: eb32c9fdd8bd4683e33d62284b6a9c4eb705b745235f4bb51a5571e1eb6738f636958fc9a6218fb51de43e0e2f74386a705b4c7ff2d1dcc611647953ba6ce159 + languageName: node + linkType: hard + +"cssnano-util-get-arguments@npm:^4.0.0": + version: 4.0.0 + resolution: "cssnano-util-get-arguments@npm:4.0.0" + checksum: 34222a1e848d573b74892eda7d7560c5422efa56f87d2b5242f9791593c6aa4ddc9d55e8e1708fb2f0d6f87c456314b78d93d3eec97d946ff756c63b09b72222 languageName: node linkType: hard -"cssnano-utils@npm:^3.1.0": - version: 3.1.0 - resolution: "cssnano-utils@npm:3.1.0" - peerDependencies: - postcss: ^8.2.15 - checksum: 975c84ce9174cf23bb1da1e9faed8421954607e9ea76440cd3bb0c1bea7e17e490d800fca5ae2812d1d9e9d5524eef23ede0a3f52497d7ccc628e5d7321536f2 +"cssnano-util-get-match@npm:^4.0.0": + version: 4.0.0 + resolution: "cssnano-util-get-match@npm:4.0.0" + checksum: 56eacea0eb3d923359c9714ab25edde5eb4859e495954615d5529e81cdfabc2d41b57055c7f6a2f08e7d89df3a2794ef659306b539505d7f4e7202b897396fc2 languageName: node linkType: hard -"cssnano@npm:^5.0.6": - version: 5.1.15 - resolution: "cssnano@npm:5.1.15" +"cssnano-util-raw-cache@npm:^4.0.1": + version: 4.0.1 + resolution: "cssnano-util-raw-cache@npm:4.0.1" dependencies: - cssnano-preset-default: ^5.2.14 - lilconfig: ^2.0.3 - yaml: ^1.10.2 - peerDependencies: - postcss: ^8.2.15 - checksum: ca9e1922178617c66c2f1548824b2c7af2ecf69cc3a187fc96bf8d29251c2e84d9e4966c69cf64a2a6a057a37dff7d6d057bc8a2a0957e6ea382e452ae9d0bbb + postcss: ^7.0.0 + checksum: 66a23e5e5255ff65d0f49f135d0ddfdb96433aeceb2708a31e4b4a652110755f103f6c91e0f439c8f3052818eb2b04ebf6334680a810296290e2c3467c14202b + languageName: node + linkType: hard + +"cssnano-util-same-parent@npm:^4.0.0": + version: 4.0.1 + resolution: "cssnano-util-same-parent@npm:4.0.1" + checksum: 97c6b3f670ee9d1d6342b6a1daf9867d5c08644365dc146bd76defd356069112148e382ca86fc3e6c55adf0687974f03535bba34df95efb468b266d2319c7b66 + languageName: node + linkType: hard + +"cssnano@npm:^4.1.10": + version: 4.1.11 + resolution: "cssnano@npm:4.1.11" + dependencies: + cosmiconfig: ^5.0.0 + cssnano-preset-default: ^4.0.8 + is-resolvable: ^1.0.0 + postcss: ^7.0.0 + checksum: 2453fbe9f9f9e2ffe87dc5c718578f1b801fc7b82eaad12f5564c84bb0faf1774ea52e01874ecd29d1782aa7d0d84f0dbc95001eed9866ebd9bc523638999c9b languageName: node linkType: hard -"csso@npm:^4.0.2, csso@npm:^4.2.0": +"csso@npm:^4.0.2": version: 4.2.0 resolution: "csso@npm:4.2.0" dependencies: @@ -9296,105 +7455,29 @@ __metadata: languageName: node linkType: hard -"customize-cra@npm:^1.0.0": - version: 1.0.0 - resolution: "customize-cra@npm:1.0.0" +"customize-cra@npm:^0.9.1": + version: 0.9.1 + resolution: "customize-cra@npm:0.9.1" dependencies: lodash.flow: ^3.5.0 - checksum: b38c48a607efc2321e6f2f12a3b53f3497b2f9b0008b48242524a92a1f26f8ae50bd73c97526e7d89c32b51f53711948e0da8f7e3618c9875087227a11a5feeb - languageName: node - linkType: hard - -"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6": - version: 3.2.4 - resolution: "d3-array@npm:3.2.4" - dependencies: - internmap: 1 - 2 - checksum: a5976a6d6205f69208478bb44920dd7ce3e788c9dceb86b304dbe401a4bfb42ecc8b04c20facde486e9adcb488b5d1800d49393a3f81a23902b68158e12cddd0 - languageName: node - linkType: hard - -"d3-color@npm:1 - 3": - version: 3.1.0 - resolution: "d3-color@npm:3.1.0" - checksum: 4931fbfda5d7c4b5cfa283a13c91a954f86e3b69d75ce588d06cde6c3628cebfc3af2069ccf225e982e8987c612aa7948b3932163ce15eb3c11cd7c003f3ee3b - languageName: node - linkType: hard - -"d3-ease@npm:^3.0.1": - version: 3.0.1 - resolution: "d3-ease@npm:3.0.1" - checksum: 06e2ee5326d1e3545eab4e2c0f84046a123dcd3b612e68858219aa034da1160333d9ce3da20a1d3486d98cb5c2a06f7d233eee1bc19ce42d1533458bd85dedcd - languageName: node - linkType: hard - -"d3-format@npm:1 - 3": - version: 3.1.0 - resolution: "d3-format@npm:3.1.0" - checksum: f345ec3b8ad3cab19bff5dead395bd9f5590628eb97a389b1dd89f0b204c7c4fc1d9520f13231c2c7cf14b7c9a8cf10f8ef15bde2befbab41454a569bd706ca2 - languageName: node - linkType: hard - -"d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:^3.0.1": - version: 3.0.1 - resolution: "d3-interpolate@npm:3.0.1" - dependencies: - d3-color: 1 - 3 - checksum: a42ba314e295e95e5365eff0f604834e67e4a3b3c7102458781c477bd67e9b24b6bb9d8e41ff5521050a3f2c7c0c4bbbb6e187fd586daa3980943095b267e78b - languageName: node - linkType: hard - -"d3-path@npm:^3.1.0": - version: 3.1.0 - resolution: "d3-path@npm:3.1.0" - checksum: 2306f1bd9191e1eac895ec13e3064f732a85f243d6e627d242a313f9777756838a2215ea11562f0c7630c7c3b16a19ec1fe0948b1c82f3317fac55882f6ee5d8 - languageName: node - linkType: hard - -"d3-scale@npm:^4.0.2": - version: 4.0.2 - resolution: "d3-scale@npm:4.0.2" - dependencies: - d3-array: 2.10.0 - 3 - d3-format: 1 - 3 - d3-interpolate: 1.2.0 - 3 - d3-time: 2.1.1 - 3 - d3-time-format: 2 - 4 - checksum: a9c770d283162c3bd11477c3d9d485d07f8db2071665f1a4ad23eec3e515e2cefbd369059ec677c9ac849877d1a765494e90e92051d4f21111aa56791c98729e - languageName: node - linkType: hard - -"d3-shape@npm:^3.1.0": - version: 3.2.0 - resolution: "d3-shape@npm:3.2.0" - dependencies: - d3-path: ^3.1.0 - checksum: de2af5fc9a93036a7b68581ca0bfc4aca2d5a328aa7ba7064c11aedd44d24f310c20c40157cb654359d4c15c3ef369f95ee53d71221017276e34172c7b719cfa + checksum: d616e4c21f231860b7cad445a52ec5c2b658c4fba9db35f4f60d943d00caeecb140562f89f4ef901b6ef4d6b16f3b6bddff3802358389ae1ab0f0eef936a66ab languageName: node linkType: hard -"d3-time-format@npm:2 - 4": - version: 4.1.0 - resolution: "d3-time-format@npm:4.1.0" - dependencies: - d3-time: 1 - 3 - checksum: 7342bce28355378152bbd4db4e275405439cabba082d9cd01946d40581140481c8328456d91740b0fe513c51ec4a467f4471ffa390c7e0e30ea30e9ec98fcdf4 +"cyclist@npm:^1.0.1": + version: 1.0.2 + resolution: "cyclist@npm:1.0.2" + checksum: d7c0336565b9b72ee72347831cbd05fadcc59cc9ab89dcf38293b1a64c2c5fb777c9ce44967390dabe8235f9898f5cb222cd6672f4920b757da8861310082716 languageName: node linkType: hard -"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:^3.0.0": - version: 3.1.0 - resolution: "d3-time@npm:3.1.0" +"d@npm:1, d@npm:^1.0.1, d@npm:^1.0.2": + version: 1.0.2 + resolution: "d@npm:1.0.2" dependencies: - d3-array: 2 - 3 - checksum: 613b435352a78d9f31b7f68540788186d8c331b63feca60ad21c88e9db1989fe888f97f242322ebd6365e45ec3fb206a4324cd4ca0dfffa1d9b5feb856ba00a7 - languageName: node - linkType: hard - -"d3-timer@npm:^3.0.1": - version: 3.0.1 - resolution: "d3-timer@npm:3.0.1" - checksum: 1cfddf86d7bca22f73f2c427f52dfa35c49f50d64e187eb788dcad6e927625c636aa18ae4edd44d084eb9d1f81d8ca4ec305dae7f733c15846a824575b789d73 + es5-ext: ^0.10.64 + type: ^2.7.2 + checksum: 775db1e8ced6707cddf64a5840522fcf5475d38ef49a5d615be0ac47f86ef64d15f5a73de1522b09327cc466d4dc35ea83dbfeed456f7a0fdcab138deb800355 languageName: node linkType: hard @@ -9416,54 +7499,63 @@ __metadata: languageName: node linkType: hard -"data-view-buffer@npm:^1.0.2": - version: 1.0.2 - resolution: "data-view-buffer@npm:1.0.2" +"data-view-buffer@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-buffer@npm:1.0.1" dependencies: - call-bound: ^1.0.3 + call-bind: ^1.0.6 es-errors: ^1.3.0 - is-data-view: ^1.0.2 - checksum: 1e1cd509c3037ac0f8ba320da3d1f8bf1a9f09b0be09394b5e40781b8cc15ff9834967ba7c9f843a425b34f9fe14ce44cf055af6662c44263424c1eb8d65659b + is-data-view: ^1.0.1 + checksum: ce24348f3c6231223b216da92e7e6a57a12b4af81a23f27eff8feabdf06acfb16c00639c8b705ca4d167f761cfc756e27e5f065d0a1f840c10b907fdaf8b988c languageName: node linkType: hard -"data-view-byte-length@npm:^1.0.2": - version: 1.0.2 - resolution: "data-view-byte-length@npm:1.0.2" +"data-view-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-length@npm:1.0.1" dependencies: - call-bound: ^1.0.3 + call-bind: ^1.0.7 es-errors: ^1.3.0 - is-data-view: ^1.0.2 - checksum: 3600c91ced1cfa935f19ef2abae11029e01738de8d229354d3b2a172bf0d7e4ed08ff8f53294b715569fdf72dfeaa96aa7652f479c0f60570878d88e7e8bddf6 + is-data-view: ^1.0.1 + checksum: dbb3200edcb7c1ef0d68979834f81d64fd8cab2f7691b3a4c6b97e67f22182f3ec2c8602efd7b76997b55af6ff8bce485829c1feda4fa2165a6b71fb7baa4269 languageName: node linkType: hard -"data-view-byte-offset@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-byte-offset@npm:1.0.1" +"data-view-byte-offset@npm:^1.0.0": + version: 1.0.0 + resolution: "data-view-byte-offset@npm:1.0.0" dependencies: - call-bound: ^1.0.2 + call-bind: ^1.0.6 es-errors: ^1.3.0 is-data-view: ^1.0.1 - checksum: 8dd492cd51d19970876626b5b5169fbb67ca31ec1d1d3238ee6a71820ca8b80cafb141c485999db1ee1ef02f2cc3b99424c5eda8d59e852d9ebb79ab290eb5ee + checksum: 7f0bf8720b7414ca719eedf1846aeec392f2054d7af707c5dc9a753cc77eb8625f067fa901e0b5127e831f9da9056138d894b9c2be79c27a21f6db5824f009c2 languageName: node linkType: hard -"date-fns@npm:^4.1.0": - version: 4.1.0 - resolution: "date-fns@npm:4.1.0" - checksum: fb681b242cccabed45494468f64282a7d375ea970e0adbcc5dcc92dcb7aba49b2081c2c9739d41bf71ce89ed68dd73bebfe06ca35129490704775d091895710b +"date-fns@npm:^2.0.1": + version: 2.30.0 + resolution: "date-fns@npm:2.30.0" + dependencies: + "@babel/runtime": ^7.21.0 + checksum: f7be01523282e9bb06c0cd2693d34f245247a29098527d4420628966a2d9aad154bd0e90a6b1cf66d37adcb769cd108cf8a7bd49d76db0fb119af5cdd13644f4 languageName: node linkType: hard "dayjs@npm:^1.11.10": - version: 1.11.18 - resolution: "dayjs@npm:1.11.18" - checksum: cc90054bad30ab011417a7a474b2ffa70e7a28ca6f834d7e86fe53a408a40a14c174f26155072628670e9eda4c48c4ed0d847d2edf83d47c0bfb78be15bbf2dd + version: 1.11.10 + resolution: "dayjs@npm:1.11.10" + checksum: a6b5a3813b8884f5cd557e2e6b7fa569f4c5d0c97aca9558e38534af4f2d60daafd3ff8c2000fed3435cfcec9e805bcebd99f90130c6d1c5ef524084ced588c4 + languageName: node + linkType: hard + +"debounce@npm:^1.2.1": + version: 1.2.1 + resolution: "debounce@npm:1.2.1" + checksum: 682a89506d9e54fb109526f4da255c5546102fbb8e3ae75eef3b04effaf5d4853756aee97475cd4650641869794e44f410eeb20ace2b18ea592287ab2038519e languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.6.0, debug@npm:^2.6.1": +"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -9472,15 +7564,15 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": - version: 4.4.3 - resolution: "debug@npm:4.4.3" +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" dependencies: - ms: ^2.1.3 + ms: 2.1.2 peerDependenciesMeta: supports-color: optional: true - checksum: 4805abd570e601acdca85b6aa3757186084a45cff9b2fa6eee1f3b173caa776b45f478b2a71a572d616d2010cea9211d0ac4a02a610e4c18ac4324bde3760834 + checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 languageName: node linkType: hard @@ -9500,35 +7592,17 @@ __metadata: languageName: node linkType: hard -"decimal.js-light@npm:^2.4.1": - version: 2.5.1 - resolution: "decimal.js-light@npm:2.5.1" - checksum: f5a2c7eac1c4541c8ab8a5c8abea64fc1761cefc7794bd5f8afd57a8a78d1b51785e0c4e4f85f4895a043eaa90ddca1edc3981d1263eb6ddce60f32bf5fe66c9 - languageName: node - linkType: hard - "decimal.js@npm:^10.2.1, decimal.js@npm:^10.4.3": - version: 10.6.0 - resolution: "decimal.js@npm:10.6.0" - checksum: 9302b990cd6f4da1c7602200002e40e15d15660374432963421d3cd6d81cc6e27e0a488356b030fee64650947e32e78bdbea245d596dadfeeeb02e146d485999 - languageName: node - linkType: hard - -"decode-named-character-reference@npm:^1.0.0": - version: 1.2.0 - resolution: "decode-named-character-reference@npm:1.2.0" - dependencies: - character-entities: ^2.0.0 - checksum: f26b23046c1a137c0b41fa51e3ce07ba8364640322c742a31570999784abc8572fc24cb108a76b14ff72ddb75d35aad3d14b10d7743639112145a2664b9d1864 + version: 10.4.3 + resolution: "decimal.js@npm:10.4.3" + checksum: 796404dcfa9d1dbfdc48870229d57f788b48c21c603c3f6554a1c17c10195fc1024de338b0cf9e1efe0c7c167eeb18f04548979bcc5fdfabebb7cc0ae3287bae languageName: node linkType: hard -"decompress-response@npm:^6.0.0": - version: 6.0.0 - resolution: "decompress-response@npm:6.0.0" - dependencies: - mimic-response: ^3.1.0 - checksum: d377cf47e02d805e283866c3f50d3d21578b779731e8c5072d6ce8c13cc31493db1c2f6784da9d1d5250822120cefa44f1deab112d5981015f2e17444b763812 +"decode-uri-component@npm:^0.2.0": + version: 0.2.2 + resolution: "decode-uri-component@npm:0.2.2" + checksum: 95476a7d28f267292ce745eac3524a9079058bbb35767b76e3ee87d42e34cd0275d2eb19d9d08c3e167f97556e8a2872747f5e65cbebcac8b0c98d83e285f139 languageName: node linkType: hard @@ -9539,17 +7613,52 @@ __metadata: languageName: node linkType: hard -"deep-eql@npm:^5.0.1": - version: 5.0.2 - resolution: "deep-eql@npm:5.0.2" - checksum: 6aaaadb4c19cbce42e26b2bbe5bd92875f599d2602635dc97f0294bae48da79e89470aedee05f449e0ca8c65e9fd7e7872624d1933a1db02713d99c2ca8d1f24 +"deep-eql@npm:^4.1.3": + version: 4.1.3 + resolution: "deep-eql@npm:4.1.3" + dependencies: + type-detect: ^4.0.0 + checksum: 7f6d30cb41c713973dc07eaadded848b2ab0b835e518a88b91bea72f34e08c4c71d167a722a6f302d3a6108f05afd8e6d7650689a84d5d29ec7fe6220420397f languageName: node linkType: hard -"deep-extend@npm:^0.6.0": - version: 0.6.0 - resolution: "deep-extend@npm:0.6.0" - checksum: 7be7e5a8d468d6b10e6a67c3de828f55001b6eb515d014f7aeb9066ce36bd5717161eb47d6a0f7bed8a9083935b465bc163ee2581c8b128d29bf61092fdf57a7 +"deep-equal@npm:^1.0.1": + version: 1.1.2 + resolution: "deep-equal@npm:1.1.2" + dependencies: + is-arguments: ^1.1.1 + is-date-object: ^1.0.5 + is-regex: ^1.1.4 + object-is: ^1.1.5 + object-keys: ^1.1.1 + regexp.prototype.flags: ^1.5.1 + checksum: 2d50f27fff785fb272cdef038ee5365ee5a30ab1aab053976e6a6add44cc60abd99b38179a46a01ac52c5e54ebb220e8f1a3a1954da20678b79c46ef4d97c9db + languageName: node + linkType: hard + +"deep-equal@npm:^2.0.5": + version: 2.2.3 + resolution: "deep-equal@npm:2.2.3" + dependencies: + array-buffer-byte-length: ^1.0.0 + call-bind: ^1.0.5 + es-get-iterator: ^1.1.3 + get-intrinsic: ^1.2.2 + is-arguments: ^1.1.1 + is-array-buffer: ^3.0.2 + is-date-object: ^1.0.5 + is-regex: ^1.1.4 + is-shared-array-buffer: ^1.0.2 + isarray: ^2.0.5 + object-is: ^1.1.5 + object-keys: ^1.1.1 + object.assign: ^4.1.4 + regexp.prototype.flags: ^1.5.1 + side-channel: ^1.0.4 + which-boxed-primitive: ^1.0.2 + which-collection: ^1.0.1 + which-typed-array: ^1.1.13 + checksum: ee8852f23e4d20a5626c13b02f415ba443a1b30b4b3d39eaf366d59c4a85e6545d7ec917db44d476a85ae5a86064f7e5f7af7479f38f113995ba869f3a1ddc53 languageName: node linkType: hard @@ -9567,12 +7676,22 @@ __metadata: languageName: node linkType: hard -"default-gateway@npm:^6.0.3": - version: 6.0.3 - resolution: "default-gateway@npm:6.0.3" +"default-gateway@npm:^4.2.0": + version: 4.2.0 + resolution: "default-gateway@npm:4.2.0" + dependencies: + execa: ^1.0.0 + ip-regex: ^2.1.0 + checksum: 1f5be765471689c6bab33e0c8b87363c3e2485cc1ab78904d383a8a8293a79f684da2a3303744b112503f986af4ea87d917c63a468ed913e9b0c31588c02d6a4 + languageName: node + linkType: hard + +"defaults@npm:^1.0.3": + version: 1.0.4 + resolution: "defaults@npm:1.0.4" dependencies: - execa: ^5.0.0 - checksum: 126f8273ecac8ee9ff91ea778e8784f6cd732d77c3157e8c5bdd6ed03651b5291f71446d05bc02d04073b1e67583604db5394ea3cf992ede0088c70ea15b7378 + clone: ^1.0.2 + checksum: 3a88b7a587fc076b84e60affad8b85245c01f60f38fc1d259e7ac1d89eb9ce6abb19e27215de46b98568dd5bc48471730b327637e6f20b0f1bc85cf00440c80a languageName: node linkType: hard @@ -9587,14 +7706,7 @@ __metadata: languageName: node linkType: hard -"define-lazy-prop@npm:^2.0.0": - version: 2.0.0 - resolution: "define-lazy-prop@npm:2.0.0" - checksum: 0115fdb065e0490918ba271d7339c42453d209d4cb619dfe635870d906731eff3e1ade8028bb461ea27ce8264ec5e22c6980612d332895977e89c1bbc80fcee2 - languageName: node - linkType: hard - -"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": +"define-properties@npm:^1.1.2, define-properties@npm:^1.1.3, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" dependencies: @@ -9605,6 +7717,49 @@ __metadata: languageName: node linkType: hard +"define-property@npm:^0.2.5": + version: 0.2.5 + resolution: "define-property@npm:0.2.5" + dependencies: + is-descriptor: ^0.1.0 + checksum: 85af107072b04973b13f9e4128ab74ddfda48ec7ad2e54b193c0ffb57067c4ce5b7786a7b4ae1f24bd03e87c5d18766b094571810b314d7540f86d4354dbd394 + languageName: node + linkType: hard + +"define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "define-property@npm:1.0.0" + dependencies: + is-descriptor: ^1.0.0 + checksum: 5fbed11dace44dd22914035ba9ae83ad06008532ca814d7936a53a09e897838acdad5b108dd0688cc8d2a7cf0681acbe00ee4136cf36743f680d10517379350a + languageName: node + linkType: hard + +"define-property@npm:^2.0.2": + version: 2.0.2 + resolution: "define-property@npm:2.0.2" + dependencies: + is-descriptor: ^1.0.2 + isobject: ^3.0.1 + checksum: 3217ed53fc9eed06ba8da6f4d33e28c68a82e2f2a8ab4d562c4920d8169a166fe7271453675e6c69301466f36a65d7f47edf0cf7f474b9aa52a5ead9c1b13c99 + languageName: node + linkType: hard + +"del@npm:^4.1.1": + version: 4.1.1 + resolution: "del@npm:4.1.1" + dependencies: + "@types/glob": ^7.1.1 + globby: ^6.1.0 + is-path-cwd: ^2.0.0 + is-path-in-cwd: ^2.0.0 + p-map: ^2.0.0 + pify: ^4.0.1 + rimraf: ^2.6.3 + checksum: 521f7da44bd79da841c06d573923d1f64f423aee8b8219c973478d3150ce1dcc024d03ad605929292adbff56d6448bca60d96dcdd2d8a53b46dbcb27e265c94b + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -9612,7 +7767,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:2.0.0, depd@npm:^2.0.0": +"depd@npm:2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: abbe19c768c97ee2eed6282d8ce3031126662252c58d711f646921c9623f9052e3e1906443066beec1095832f534e57c523b7333f8e7e0d93051ab6baef5ab3a @@ -9626,13 +7781,23 @@ __metadata: languageName: node linkType: hard -"dequal@npm:^2.0.0, dequal@npm:^2.0.3": +"dequal@npm:^2.0.3": version: 2.0.3 resolution: "dequal@npm:2.0.3" checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 languageName: node linkType: hard +"des.js@npm:^1.0.0": + version: 1.1.0 + resolution: "des.js@npm:1.1.0" + dependencies: + inherits: ^2.0.1 + minimalistic-assert: ^1.0.0 + checksum: 0e9c1584b70d31e20f20a613fc9ef60fbc6a147dfec9e448a168794a4b97ac04d8dc47ea008f1fa93b0f8aaf7c1ead632a5e59ce1913a6079d2d244c9f5ebe33 + languageName: node + linkType: hard + "destroy@npm:1.2.0": version: 1.2.0 resolution: "destroy@npm:1.2.0" @@ -9640,22 +7805,6 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^1.0.3": - version: 1.0.3 - resolution: "detect-libc@npm:1.0.3" - bin: - detect-libc: ./bin/detect-libc.js - checksum: daaaed925ffa7889bd91d56e9624e6c8033911bb60f3a50a74a87500680652969dbaab9526d1e200a4c94acf80fc862a22131841145a0a8482d60a99c24f4a3e - languageName: node - linkType: hard - -"detect-libc@npm:^2.0.0": - version: 2.0.4 - resolution: "detect-libc@npm:2.0.4" - checksum: 3d186b7d4e16965e10e21db596c78a4e131f9eee69c0081d13b85e6a61d7448d3ba23fe7997648022bdfa3b0eb4cc3c289a44c8188df949445a20852689abef6 - languageName: node - linkType: hard - "detect-newline@npm:^3.0.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -9670,7 +7819,7 @@ __metadata: languageName: node linkType: hard -"detect-port-alt@npm:^1.1.6": +"detect-port-alt@npm:1.1.6": version: 1.1.6 resolution: "detect-port-alt@npm:1.1.6" dependencies: @@ -9683,15 +7832,6 @@ __metadata: languageName: node linkType: hard -"devlop@npm:^1.0.0, devlop@npm:^1.1.0": - version: 1.1.0 - resolution: "devlop@npm:1.1.0" - dependencies: - dequal: ^2.0.0 - checksum: d2ff650bac0bb6ef08c48f3ba98640bb5fec5cce81e9957eb620408d1bab1204d382a45b785c6b3314dc867bb0684936b84c6867820da6db97cbb5d3c15dd185 - languageName: node - linkType: hard - "dezalgo@npm:^1.0.4": version: 1.0.4 resolution: "dezalgo@npm:1.0.4" @@ -9702,21 +7842,21 @@ __metadata: languageName: node linkType: hard -"didyoumean@npm:^1.2.2": - version: 1.2.2 - resolution: "didyoumean@npm:1.2.2" - checksum: d5d98719d58b3c2fa59663c4c42ba9716f1fd01245c31d5fce31915bd3aa26e6aac149788e007358f778ebbd68a2256eb5973e8ca6f221df221ba060115acf2e +"diff-sequences@npm:^26.6.2": + version: 26.6.2 + resolution: "diff-sequences@npm:26.6.2" + checksum: 79af871776ef149a7ff3345d6b1bf37fe6e81f68632aa5542787851f6f60fba19b0be22fdd1e06046f56ae7382763ccfe94a982c39ee72bd107aef435ecbc0cf languageName: node linkType: hard -"diff-sequences@npm:^27.5.1": - version: 27.5.1 - resolution: "diff-sequences@npm:27.5.1" - checksum: a00db5554c9da7da225db2d2638d85f8e41124eccbd56cbaefb3b276dcbb1c1c2ad851c32defe2055a54a4806f030656cbf6638105fd6ce97bb87b90b32a33ca +"diff-sequences@npm:^28.1.1": + version: 28.1.1 + resolution: "diff-sequences@npm:28.1.1" + checksum: e2529036505567c7ca5a2dea86b6bcd1ca0e3ae63bf8ebf529b8a99cfa915bbf194b7021dc1c57361a4017a6d95578d4ceb29fabc3232a4f4cb866a2726c7690 languageName: node linkType: hard -"diff-sequences@npm:^29.6.3": +"diff-sequences@npm:^29.4.3, diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" checksum: f4914158e1f2276343d98ff5b31fc004e7304f5470bf0f1adb2ac6955d85a531a6458d33e87667f98f6ae52ebd3891bb47d420bb48a5bd8b7a27ee25b20e33aa @@ -9730,6 +7870,17 @@ __metadata: languageName: node linkType: hard +"diffie-hellman@npm:^5.0.0": + version: 5.0.3 + resolution: "diffie-hellman@npm:5.0.3" + dependencies: + bn.js: ^4.1.0 + miller-rabin: ^4.0.0 + randombytes: ^2.0.0 + checksum: 0e620f322170c41076e70181dd1c24e23b08b47dbb92a22a644f3b89b6d3834b0f8ee19e37916164e5eb1ee26d2aa836d6129f92723995267250a0b541811065 + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -9739,19 +7890,29 @@ __metadata: languageName: node linkType: hard -"dlv@npm:^1.1.3": - version: 1.1.3 - resolution: "dlv@npm:1.1.3" - checksum: d7381bca22ed11933a1ccf376db7a94bee2c57aa61e490f680124fa2d1cd27e94eba641d9f45be57caab4f9a6579de0983466f620a2cd6230d7ec93312105ae7 +"dns-equal@npm:^1.0.0": + version: 1.0.0 + resolution: "dns-equal@npm:1.0.0" + checksum: a8471ac849c7c13824f053babea1bc26e2f359394dd5a460f8340d8abd13434be01e3327a5c59d212f8c8997817450efd3f3ac77bec709b21979cf0235644524 + languageName: node + linkType: hard + +"dns-packet@npm:^1.3.1": + version: 1.3.4 + resolution: "dns-packet@npm:1.3.4" + dependencies: + ip: ^1.1.0 + safe-buffer: ^5.0.1 + checksum: 7dd87f85cb4f9d1a99c03470730e3d9385e67dc94f6c13868c4034424a5378631e492f9f1fbc43d3c42f319fbbfe18b6488bb9527c32d34692c52bf1f5eedf69 languageName: node linkType: hard -"dns-packet@npm:^5.2.2": - version: 5.6.1 - resolution: "dns-packet@npm:5.6.1" +"dns-txt@npm:^2.0.2": + version: 2.0.2 + resolution: "dns-txt@npm:2.0.2" dependencies: - "@leichtgewicht/ip-codec": ^2.0.1 - checksum: 64c06457f0c6e143f7a0946e0aeb8de1c5f752217cfa143ef527467c00a6d78db1835cfdb6bb68333d9f9a4963cf23f410439b5262a8935cce1236f45e344b81 + buffer-indexof: ^1.0.0 + checksum: 80130b665379ecd991687ae079fbee25d091e03e4c4cef41e7643b977849ac48c2f56bfcb3727e53594d29029b833749811110d9f3fbee1b26a6e6f8096a5cef languageName: node linkType: hard @@ -9773,20 +7934,13 @@ __metadata: languageName: node linkType: hard -"dom-accessibility-api@npm:^0.5.9": +"dom-accessibility-api@npm:^0.5.6, dom-accessibility-api@npm:^0.5.9": version: 0.5.16 resolution: "dom-accessibility-api@npm:0.5.16" checksum: 005eb283caef57fc1adec4d5df4dd49189b628f2f575af45decb210e04d634459e3f1ee64f18b41e2dcf200c844bc1d9279d80807e686a30d69a4756151ad248 languageName: node linkType: hard -"dom-accessibility-api@npm:^0.6.3": - version: 0.6.3 - resolution: "dom-accessibility-api@npm:0.6.3" - checksum: c325b5144bb406df23f4affecffc117dbaec9af03daad9ee6b510c5be647b14d28ef0a4ea5ca06d696d8ab40bb777e5fed98b985976fdef9d8790178fa1d573f - languageName: node - linkType: hard - "dom-converter@npm:^0.2.0": version: 0.2.0 resolution: "dom-converter@npm:0.2.0" @@ -9827,6 +7981,13 @@ __metadata: languageName: node linkType: hard +"domain-browser@npm:^1.1.1": + version: 1.2.0 + resolution: "domain-browser@npm:1.2.0" + checksum: 8f1235c7f49326fb762f4675795246a6295e7dd566b4697abec24afdba2460daa7dfbd1a73d31efbf5606b3b7deadb06ce47cf06f0a476e706153d62a4ff2b90 + languageName: node + linkType: hard + "domelementtype@npm:1": version: 1.3.1 resolution: "domelementtype@npm:1.3.1" @@ -9890,45 +8051,55 @@ __metadata: languageName: node linkType: hard -"dotenv-expand@npm:^5.1.0": +"dot-prop@npm:^5.2.0": + version: 5.3.0 + resolution: "dot-prop@npm:5.3.0" + dependencies: + is-obj: ^2.0.0 + checksum: d5775790093c234ef4bfd5fbe40884ff7e6c87573e5339432870616331189f7f5d86575c5b5af2dcf0f61172990f4f734d07844b1f23482fff09e3c4bead05ea + languageName: node + linkType: hard + +"dotenv-expand@npm:5.1.0": version: 5.1.0 resolution: "dotenv-expand@npm:5.1.0" checksum: 8017675b7f254384915d55f9eb6388e577cf0a1231a28d54b0ca03b782be9501b0ac90ac57338636d395fa59051e6209e9b44b8ddf169ce6076dffb5dea227d3 languageName: node linkType: hard -"dotenv@npm:^10.0.0": - version: 10.0.0 - resolution: "dotenv@npm:10.0.0" - checksum: f412c5fe8c24fbe313d302d2500e247ba8a1946492db405a4de4d30dd0eb186a88a43f13c958c5a7de303938949c4231c56994f97d05c4bc1f22478d631b4005 +"dotenv@npm:8.2.0": + version: 8.2.0 + resolution: "dotenv@npm:8.2.0" + checksum: ad4c8e0df3e24b4811c8e93377d048a10a9b213dcd9f062483b4a2d3168f08f10ec9c618c23f5639060d230ccdb174c08761479e9baa29610aa978e1ee66df76 languageName: node linkType: hard "dotenv@npm:^16.0.1": - version: 16.6.1 - resolution: "dotenv@npm:16.6.1" - checksum: e8bd63c9a37f57934f7938a9cf35de698097fadf980cb6edb61d33b3e424ceccfe4d10f37130b904a973b9038627c2646a3365a904b4406514ea94d7f1816b69 - languageName: node - linkType: hard - -"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": - version: 1.0.1 - resolution: "dunder-proto@npm:1.0.1" - dependencies: - call-bind-apply-helpers: ^1.0.1 - es-errors: ^1.3.0 - gopd: ^1.2.0 - checksum: 149207e36f07bd4941921b0ca929e3a28f1da7bd6b6ff8ff7f4e2f2e460675af4576eeba359c635723dc189b64cdd4787e0255897d5b135ccc5d15cb8685fc90 + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 301a12c3d44fd49888b74eb9ccf9f07a1f5df43f489e7fcb89647a2edcd84c42d6bc349dc8df099cd18f07c35c7b04685c1a4f3e6a6a9e6b30f8d48c15b7f49c languageName: node linkType: hard -"duplexer@npm:^0.1.2": +"duplexer@npm:^0.1.1": version: 0.1.2 resolution: "duplexer@npm:0.1.2" checksum: 62ba61a830c56801db28ff6305c7d289b6dc9f859054e8c982abd8ee0b0a14d2e9a8e7d086ffee12e868d43e2bbe8a964be55ddbd8c8957714c87373c7a4f9b0 languageName: node linkType: hard +"duplexify@npm:^3.4.2, duplexify@npm:^3.6.0": + version: 3.7.1 + resolution: "duplexify@npm:3.7.1" + dependencies: + end-of-stream: ^1.0.0 + inherits: ^2.0.1 + readable-stream: ^2.0.0 + stream-shift: ^1.0.0 + checksum: 3c2ed2223d956a5da713dae12ba8295acb61d9acd966ccbba938090d04f4574ca4dca75cca089b5077c2d7e66101f32e6ea9b36a78ca213eff574e7a8b8accf2 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -9952,35 +8123,46 @@ __metadata: languageName: node linkType: hard -"ejs@npm:^3.1.6": - version: 3.1.10 - resolution: "ejs@npm:3.1.10" - dependencies: - jake: ^10.8.5 - bin: - ejs: bin/cli.js - checksum: ce90637e9c7538663ae023b8a7a380b2ef7cc4096de70be85abf5a3b9641912dde65353211d05e24d56b1f242d71185c6d00e02cb8860701d571786d92c71f05 +"ejs@npm:^2.6.1": + version: 2.7.4 + resolution: "ejs@npm:2.7.4" + checksum: a1d2bfc7d1f0b39e99ae19b20c9469a25aeddba1ffc225db098110b18d566f73772fcdcc740b108cfda7452276f67d7b64eb359f90285414c942f4ae70713371 languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.218": - version: 1.5.218 - resolution: "electron-to-chromium@npm:1.5.218" - checksum: 869953636f9d7ff865c827a65e3a8e5f2b4162f1ba58389d93e19f2c945001a2e5925d2c29b49af57c2ddbbf75c6205d01d472bf0d54085c42d606b97fd76eab +"electron-to-chromium@npm:^1.3.564, electron-to-chromium@npm:^1.4.668": + version: 1.4.747 + resolution: "electron-to-chromium@npm:1.4.747" + checksum: 6d302c2fbe71390ca666544017de5f8614ba8632ee02fd612d423439e813d72df09cbd8f614122a2ee07c8ffc2b3788882a5c5bb99363f162b9257f34c0eb31f languageName: node linkType: hard -"emittery@npm:^0.10.2": - version: 0.10.2 - resolution: "emittery@npm:0.10.2" - checksum: ee3e21788b043b90885b18ea756ec3105c1cedc50b29709c92b01e239c7e55345d4bb6d3aef4ddbaf528eef448a40b3bb831bad9ee0fc9c25cbf1367ab1ab5ac +"elliptic@npm:^6.5.3, elliptic@npm:^6.5.5": + version: 6.5.5 + resolution: "elliptic@npm:6.5.5" + dependencies: + bn.js: ^4.11.9 + brorand: ^1.1.0 + hash.js: ^1.0.0 + hmac-drbg: ^1.0.1 + inherits: ^2.0.4 + minimalistic-assert: ^1.0.1 + minimalistic-crypto-utils: ^1.0.1 + checksum: ec9105e4469eb3b32b0ee2579756c888ddf3f99d259aa0d65fccb906ee877768aaf8880caae73e3e669c9a4adeb3eb1945703aa974ec5000d2d33a239f4567eb languageName: node linkType: hard -"emittery@npm:^0.8.1": - version: 0.8.1 - resolution: "emittery@npm:0.8.1" - checksum: 2457e8c7b0688bb006126f2c025b2655abe682f66b184954122a8a065b5277f9813d49d627896a10b076b81c513ec5f491fd9c14fbd42c04b95ca3c9f3c365ee +"emittery@npm:^0.7.1": + version: 0.7.2 + resolution: "emittery@npm:0.7.2" + checksum: 908cd933d48a9bcb58ddf39e9a7d4ba1e049de392ccbef010102539a636e03cea2b28218331b7ede41de8165d9ed7f148851c5112ebd2e943117c0f61eff5f10 + languageName: node + linkType: hard + +"emoji-regex@npm:^7.0.1": + version: 7.0.3 + resolution: "emoji-regex@npm:7.0.3" + checksum: 9159b2228b1511f2870ac5920f394c7e041715429a68459ebe531601555f11ea782a8e1718f969df2711d38c66268174407cbca57ce36485544f695c2dfdc96e languageName: node linkType: hard @@ -10005,13 +8187,6 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": - version: 2.0.0 - resolution: "encodeurl@npm:2.0.0" - checksum: abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe - languageName: node - linkType: hard - "encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" @@ -10028,505 +8203,516 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": - version: 1.4.5 - resolution: "end-of-stream@npm:1.4.5" - dependencies: - once: ^1.4.0 - checksum: 1e0cfa6e7f49887544e03314f9dfc56a8cb6dde910cbb445983ecc2ff426fc05946df9d75d8a21a3a64f2cecfe1bf88f773952029f46756b2ed64a24e95b1fb8 +"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0": + version: 1.4.4 + resolution: "end-of-stream@npm:1.4.4" + dependencies: + once: ^1.4.0 + checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b + languageName: node + linkType: hard + +"enhanced-resolve@npm:^4.3.0": + version: 4.5.0 + resolution: "enhanced-resolve@npm:4.5.0" + dependencies: + graceful-fs: ^4.1.2 + memory-fs: ^0.5.0 + tapable: ^1.0.0 + checksum: 4d87488584c4d67d356ef4ba04978af4b2d4d18190cb859efac8e8475a34d5d6c069df33faa5a0a22920b0586dbf330f6a08d52bb15a8771a9ce4d70a2da74ba + languageName: node + linkType: hard + +"enquirer@npm:^2.3.5": + version: 2.4.1 + resolution: "enquirer@npm:2.4.1" + dependencies: + ansi-colors: ^4.1.1 + strip-ansi: ^6.0.1 + checksum: f080f11a74209647dbf347a7c6a83c8a47ae1ebf1e75073a808bc1088eb780aa54075bfecd1bcdb3e3c724520edb8e6ee05da031529436b421b71066fcc48cb5 + languageName: node + linkType: hard + +"entities@npm:^2.0.0": + version: 2.2.0 + resolution: "entities@npm:2.2.0" + checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 + languageName: node + linkType: hard + +"errno@npm:^0.1.3, errno@npm:~0.1.7": + version: 0.1.8 + resolution: "errno@npm:0.1.8" + dependencies: + prr: ~1.0.1 + bin: + errno: cli.js + checksum: 1271f7b9fbb3bcbec76ffde932485d1e3561856d21d847ec613a9722ee924cdd4e523a62dc71a44174d91e898fe21fdc8d5b50823f4b5e0ce8c35c8271e6ef4a + languageName: node + linkType: hard + +"error-ex@npm:^1.3.1": + version: 1.3.2 + resolution: "error-ex@npm:1.3.2" + dependencies: + is-arrayish: ^0.2.1 + checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001 + languageName: node + linkType: hard + +"error-stack-parser@npm:^2.0.6": + version: 2.1.4 + resolution: "error-stack-parser@npm:2.1.4" + dependencies: + stackframe: ^1.3.4 + checksum: 3b916d2d14c6682f287c8bfa28e14672f47eafe832701080e420e7cdbaebb2c50293868256a95706ac2330fe078cf5664713158b49bc30d7a5f2ac229ded0e18 + languageName: node + linkType: hard + +"es-abstract@npm:^1.17.2, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.1, es-abstract@npm:^1.23.2": + version: 1.23.3 + resolution: "es-abstract@npm:1.23.3" + dependencies: + array-buffer-byte-length: ^1.0.1 + arraybuffer.prototype.slice: ^1.0.3 + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.7 + data-view-buffer: ^1.0.1 + data-view-byte-length: ^1.0.1 + data-view-byte-offset: ^1.0.0 + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + es-set-tostringtag: ^2.0.3 + es-to-primitive: ^1.2.1 + function.prototype.name: ^1.1.6 + get-intrinsic: ^1.2.4 + get-symbol-description: ^1.0.2 + globalthis: ^1.0.3 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + has-proto: ^1.0.3 + has-symbols: ^1.0.3 + hasown: ^2.0.2 + internal-slot: ^1.0.7 + is-array-buffer: ^3.0.4 + is-callable: ^1.2.7 + is-data-view: ^1.0.1 + is-negative-zero: ^2.0.3 + is-regex: ^1.1.4 + is-shared-array-buffer: ^1.0.3 + is-string: ^1.0.7 + is-typed-array: ^1.1.13 + is-weakref: ^1.0.2 + object-inspect: ^1.13.1 + object-keys: ^1.1.1 + object.assign: ^4.1.5 + regexp.prototype.flags: ^1.5.2 + safe-array-concat: ^1.1.2 + safe-regex-test: ^1.0.3 + string.prototype.trim: ^1.2.9 + string.prototype.trimend: ^1.0.8 + string.prototype.trimstart: ^1.0.8 + typed-array-buffer: ^1.0.2 + typed-array-byte-length: ^1.0.1 + typed-array-byte-offset: ^1.0.2 + typed-array-length: ^1.0.6 + unbox-primitive: ^1.0.2 + which-typed-array: ^1.1.15 + checksum: f840cf161224252512f9527306b57117192696571e07920f777cb893454e32999206198b4f075516112af6459daca282826d1735c450528470356d09eff3a9ae + languageName: node + linkType: hard + +"es-array-method-boxes-properly@npm:^1.0.0": + version: 1.0.0 + resolution: "es-array-method-boxes-properly@npm:1.0.0" + checksum: 2537fcd1cecf187083890bc6f5236d3a26bf39237433587e5bf63392e88faae929dbba78ff0120681a3f6f81c23fe3816122982c160d63b38c95c830b633b826 + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: ^1.2.4 + checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + +"es-get-iterator@npm:^1.1.3": + version: 1.1.3 + resolution: "es-get-iterator@npm:1.1.3" + dependencies: + call-bind: ^1.0.2 + get-intrinsic: ^1.1.3 + has-symbols: ^1.0.3 + is-arguments: ^1.1.1 + is-map: ^2.0.2 + is-set: ^2.0.2 + is-string: ^1.0.7 + isarray: ^2.0.5 + stop-iteration-iterator: ^1.0.0 + checksum: 8fa118da42667a01a7c7529f8a8cca514feeff243feec1ce0bb73baaa3514560bd09d2b3438873cf8a5aaec5d52da248131de153b28e2638a061b6e4df13267d + languageName: node + linkType: hard + +"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.17": + version: 1.0.18 + resolution: "es-iterator-helpers@npm:1.0.18" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.0 + es-errors: ^1.3.0 + es-set-tostringtag: ^2.0.3 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + globalthis: ^1.0.3 + has-property-descriptors: ^1.0.2 + has-proto: ^1.0.3 + has-symbols: ^1.0.3 + internal-slot: ^1.0.7 + iterator.prototype: ^1.1.2 + safe-array-concat: ^1.1.2 + checksum: 1594324ff3ca8890fe30c98b2419d3007d2b14b35f9773f188114408ff973e13c526f6045d88209e932f58dc0c55fc9a4ae1554636f8938ed7d926ffc27d3e1a + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0": + version: 1.0.0 + resolution: "es-object-atoms@npm:1.0.0" + dependencies: + es-errors: ^1.3.0 + checksum: 26f0ff78ab93b63394e8403c353842b2272836968de4eafe97656adfb8a7c84b9099bf0fe96ed58f4a4cddc860f6e34c77f91649a58a5daa4a9c40b902744e3c + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.0.3": + version: 2.0.3 + resolution: "es-set-tostringtag@npm:2.0.3" + dependencies: + get-intrinsic: ^1.2.4 + has-tostringtag: ^1.0.2 + hasown: ^2.0.1 + checksum: 7227fa48a41c0ce83e0377b11130d324ac797390688135b8da5c28994c0165be8b252e15cd1de41e1325e5a5412511586960213e88f9ab4a5e7d028895db5129 + languageName: node + linkType: hard + +"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": + version: 1.0.2 + resolution: "es-shim-unscopables@npm:1.0.2" + dependencies: + hasown: ^2.0.0 + checksum: 432bd527c62065da09ed1d37a3f8e623c423683285e6188108286f4a1e8e164a5bcbfbc0051557c7d14633cd2a41ce24c7048e6bbb66a985413fd32f1be72626 + languageName: node + linkType: hard + +"es-to-primitive@npm:^1.2.1": + version: 1.2.1 + resolution: "es-to-primitive@npm:1.2.1" + dependencies: + is-callable: ^1.1.4 + is-date-object: ^1.0.1 + is-symbol: ^1.0.2 + checksum: 4ead6671a2c1402619bdd77f3503991232ca15e17e46222b0a41a5d81aebc8740a77822f5b3c965008e631153e9ef0580540007744521e72de8e33599fca2eed + languageName: node + linkType: hard + +"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.62, es5-ext@npm:^0.10.64, es5-ext@npm:~0.10.14": + version: 0.10.64 + resolution: "es5-ext@npm:0.10.64" + dependencies: + es6-iterator: ^2.0.3 + es6-symbol: ^3.1.3 + esniff: ^2.0.1 + next-tick: ^1.1.0 + checksum: 01179fab0769fdbef213062222f99d0346724dbaccf04b87c0e6ee7f0c97edabf14be647ca1321f0497425ea7145de0fd278d1b3f3478864b8933e7136a5c645 + languageName: node + linkType: hard + +"es6-iterator@npm:2.0.3, es6-iterator@npm:^2.0.3": + version: 2.0.3 + resolution: "es6-iterator@npm:2.0.3" + dependencies: + d: 1 + es5-ext: ^0.10.35 + es6-symbol: ^3.1.1 + checksum: 6e48b1c2d962c21dee604b3d9f0bc3889f11ed5a8b33689155a2065d20e3107e2a69cc63a71bd125aeee3a589182f8bbcb5c8a05b6a8f38fa4205671b6d09697 + languageName: node + linkType: hard + +"es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": + version: 3.1.4 + resolution: "es6-symbol@npm:3.1.4" + dependencies: + d: ^1.0.2 + ext: ^1.7.0 + checksum: 52125ec4b5d1b6b93b8d3d42830bb19f8da21080ffcf45253b614bc6ff3e31349be202fb745d4d1af6778cdf5e38fea30e0c7e7dc37e2aecd44acc43502055f9 + languageName: node + linkType: hard + +"esbuild-android-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-android-64@npm:0.14.54" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"esbuild-android-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-android-arm64@npm:0.14.54" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"esbuild-darwin-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-darwin-64@npm:0.14.54" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"esbuild-darwin-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-darwin-arm64@npm:0.14.54" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"enhanced-resolve@npm:^5.17.3": - version: 5.18.3 - resolution: "enhanced-resolve@npm:5.18.3" - dependencies: - graceful-fs: ^4.2.4 - tapable: ^2.2.0 - checksum: e2b2188a7f9b68616984b5ce1f43b97bef3c5fde4d193c24ea4cfdb4eb784a700093f049f14155733a3cb3ae1204550590aa37dda7e742022c8f447f618a4816 +"esbuild-freebsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-freebsd-64@npm:0.14.54" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"enquirer@npm:^2.3.5": - version: 2.4.1 - resolution: "enquirer@npm:2.4.1" - dependencies: - ansi-colors: ^4.1.1 - strip-ansi: ^6.0.1 - checksum: f080f11a74209647dbf347a7c6a83c8a47ae1ebf1e75073a808bc1088eb780aa54075bfecd1bcdb3e3c724520edb8e6ee05da031529436b421b71066fcc48cb5 +"esbuild-freebsd-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-freebsd-arm64@npm:0.14.54" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"entities@npm:^2.0.0": - version: 2.2.0 - resolution: "entities@npm:2.2.0" - checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3 +"esbuild-linux-32@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-32@npm:0.14.54" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"env-paths@npm:^2.2.0": - version: 2.2.1 - resolution: "env-paths@npm:2.2.1" - checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e +"esbuild-linux-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-64@npm:0.14.54" + conditions: os=linux & cpu=x64 languageName: node linkType: hard -"err-code@npm:^2.0.2": - version: 2.0.3 - resolution: "err-code@npm:2.0.3" - checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 +"esbuild-linux-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-arm64@npm:0.14.54" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"error-ex@npm:^1.3.1": - version: 1.3.2 - resolution: "error-ex@npm:1.3.2" - dependencies: - is-arrayish: ^0.2.1 - checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001 +"esbuild-linux-arm@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-arm@npm:0.14.54" + conditions: os=linux & cpu=arm languageName: node linkType: hard -"error-stack-parser@npm:^2.0.6": - version: 2.1.4 - resolution: "error-stack-parser@npm:2.1.4" - dependencies: - stackframe: ^1.3.4 - checksum: 3b916d2d14c6682f287c8bfa28e14672f47eafe832701080e420e7cdbaebb2c50293868256a95706ac2330fe078cf5664713158b49bc30d7a5f2ac229ded0e18 +"esbuild-linux-mips64le@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-mips64le@npm:0.14.54" + conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"es-abstract@npm:^1.17.2, es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0": - version: 1.24.0 - resolution: "es-abstract@npm:1.24.0" - dependencies: - array-buffer-byte-length: ^1.0.2 - arraybuffer.prototype.slice: ^1.0.4 - available-typed-arrays: ^1.0.7 - call-bind: ^1.0.8 - call-bound: ^1.0.4 - data-view-buffer: ^1.0.2 - data-view-byte-length: ^1.0.2 - data-view-byte-offset: ^1.0.1 - es-define-property: ^1.0.1 - es-errors: ^1.3.0 - es-object-atoms: ^1.1.1 - es-set-tostringtag: ^2.1.0 - es-to-primitive: ^1.3.0 - function.prototype.name: ^1.1.8 - get-intrinsic: ^1.3.0 - get-proto: ^1.0.1 - get-symbol-description: ^1.1.0 - globalthis: ^1.0.4 - gopd: ^1.2.0 - has-property-descriptors: ^1.0.2 - has-proto: ^1.2.0 - has-symbols: ^1.1.0 - hasown: ^2.0.2 - internal-slot: ^1.1.0 - is-array-buffer: ^3.0.5 - is-callable: ^1.2.7 - is-data-view: ^1.0.2 - is-negative-zero: ^2.0.3 - is-regex: ^1.2.1 - is-set: ^2.0.3 - is-shared-array-buffer: ^1.0.4 - is-string: ^1.1.1 - is-typed-array: ^1.1.15 - is-weakref: ^1.1.1 - math-intrinsics: ^1.1.0 - object-inspect: ^1.13.4 - object-keys: ^1.1.1 - object.assign: ^4.1.7 - own-keys: ^1.0.1 - regexp.prototype.flags: ^1.5.4 - safe-array-concat: ^1.1.3 - safe-push-apply: ^1.0.0 - safe-regex-test: ^1.1.0 - set-proto: ^1.0.0 - stop-iteration-iterator: ^1.1.0 - string.prototype.trim: ^1.2.10 - string.prototype.trimend: ^1.0.9 - string.prototype.trimstart: ^1.0.8 - typed-array-buffer: ^1.0.3 - typed-array-byte-length: ^1.0.3 - typed-array-byte-offset: ^1.0.4 - typed-array-length: ^1.0.7 - unbox-primitive: ^1.1.0 - which-typed-array: ^1.1.19 - checksum: 06b3d605e56e3da9d16d4db2629a42dac1ca31f2961a41d15c860422a266115e865b43e82d6b9da81a0fabbbb65ebc12fb68b0b755bc9dbddacb6bf7450e96df +"esbuild-linux-ppc64le@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-ppc64le@npm:0.14.54" + conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"es-array-method-boxes-properly@npm:^1.0.0": - version: 1.0.0 - resolution: "es-array-method-boxes-properly@npm:1.0.0" - checksum: 2537fcd1cecf187083890bc6f5236d3a26bf39237433587e5bf63392e88faae929dbba78ff0120681a3f6f81c23fe3816122982c160d63b38c95c830b633b826 +"esbuild-linux-riscv64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-riscv64@npm:0.14.54" + conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": - version: 1.0.1 - resolution: "es-define-property@npm:1.0.1" - checksum: 0512f4e5d564021c9e3a644437b0155af2679d10d80f21adaf868e64d30efdfbd321631956f20f42d655fedb2e3a027da479fad3fa6048f768eb453a80a5f80a +"esbuild-linux-s390x@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-linux-s390x@npm:0.14.54" + conditions: os=linux & cpu=s390x languageName: node linkType: hard -"es-errors@npm:^1.3.0": - version: 1.3.0 - resolution: "es-errors@npm:1.3.0" - checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 +"esbuild-netbsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-netbsd-64@npm:0.14.54" + conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"es-iterator-helpers@npm:^1.2.1": - version: 1.2.1 - resolution: "es-iterator-helpers@npm:1.2.1" - dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.3 - define-properties: ^1.2.1 - es-abstract: ^1.23.6 - es-errors: ^1.3.0 - es-set-tostringtag: ^2.0.3 - function-bind: ^1.1.2 - get-intrinsic: ^1.2.6 - globalthis: ^1.0.4 - gopd: ^1.2.0 - has-property-descriptors: ^1.0.2 - has-proto: ^1.2.0 - has-symbols: ^1.1.0 - internal-slot: ^1.1.0 - iterator.prototype: ^1.1.4 - safe-array-concat: ^1.1.3 - checksum: 952808dd1df3643d67ec7adf20c30b36e5eecadfbf36354e6f39ed3266c8e0acf3446ce9bc465e38723d613cb1d915c1c07c140df65bdce85da012a6e7bda62b +"esbuild-openbsd-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-openbsd-64@npm:0.14.54" + conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"es-module-lexer@npm:^1.2.1, es-module-lexer@npm:^1.5.4, es-module-lexer@npm:^1.7.0": - version: 1.7.0 - resolution: "es-module-lexer@npm:1.7.0" - checksum: 7858bb76ae387fdbf8a6fccc951bf18919768309850587553eca34698b9193fbc65fab03d3d9f69163d860321fbf66adf89d5821e7f4148c7cb7d7b997259211 +"esbuild-sunos-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-sunos-64@npm:0.14.54" + conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": - version: 1.1.1 - resolution: "es-object-atoms@npm:1.1.1" - dependencies: - es-errors: ^1.3.0 - checksum: 214d3767287b12f36d3d7267ef342bbbe1e89f899cfd67040309fc65032372a8e60201410a99a1645f2f90c1912c8c49c8668066f6bdd954bcd614dda2e3da97 +"esbuild-windows-32@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-32@npm:0.14.54" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"es-set-tostringtag@npm:^2.0.3, es-set-tostringtag@npm:^2.1.0": - version: 2.1.0 - resolution: "es-set-tostringtag@npm:2.1.0" - dependencies: - es-errors: ^1.3.0 - get-intrinsic: ^1.2.6 - has-tostringtag: ^1.0.2 - hasown: ^2.0.2 - checksum: 789f35de4be3dc8d11fdcb91bc26af4ae3e6d602caa93299a8c45cf05d36cc5081454ae2a6d3afa09cceca214b76c046e4f8151e092e6fc7feeb5efb9e794fc6 +"esbuild-windows-64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-64@npm:0.14.54" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": - version: 1.1.0 - resolution: "es-shim-unscopables@npm:1.1.0" - dependencies: - hasown: ^2.0.2 - checksum: 33cfb1ebcb2f869f0bf528be1a8660b4fe8b6cec8fc641f330e508db2284b58ee2980fad6d0828882d22858c759c0806076427a3673b6daa60f753e3b558ee15 +"esbuild-windows-arm64@npm:0.14.54": + version: 0.14.54 + resolution: "esbuild-windows-arm64@npm:0.14.54" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"es-to-primitive@npm:^1.3.0": - version: 1.3.0 - resolution: "es-to-primitive@npm:1.3.0" - dependencies: - is-callable: ^1.2.7 - is-date-object: ^1.0.5 - is-symbol: ^1.0.4 - checksum: 966965880356486cd4d1fe9a523deda2084c81b3702d951212c098f5f2ee93605d1b7c1840062efb48a07d892641c7ed1bc194db563645c0dd2b919cb6d65b93 - languageName: node - linkType: hard - -"esbuild@npm:^0.17.0": - version: 0.17.19 - resolution: "esbuild@npm:0.17.19" - dependencies: - "@esbuild/android-arm": 0.17.19 - "@esbuild/android-arm64": 0.17.19 - "@esbuild/android-x64": 0.17.19 - "@esbuild/darwin-arm64": 0.17.19 - "@esbuild/darwin-x64": 0.17.19 - "@esbuild/freebsd-arm64": 0.17.19 - "@esbuild/freebsd-x64": 0.17.19 - "@esbuild/linux-arm": 0.17.19 - "@esbuild/linux-arm64": 0.17.19 - "@esbuild/linux-ia32": 0.17.19 - "@esbuild/linux-loong64": 0.17.19 - "@esbuild/linux-mips64el": 0.17.19 - "@esbuild/linux-ppc64": 0.17.19 - "@esbuild/linux-riscv64": 0.17.19 - "@esbuild/linux-s390x": 0.17.19 - "@esbuild/linux-x64": 0.17.19 - "@esbuild/netbsd-x64": 0.17.19 - "@esbuild/openbsd-x64": 0.17.19 - "@esbuild/sunos-x64": 0.17.19 - "@esbuild/win32-arm64": 0.17.19 - "@esbuild/win32-ia32": 0.17.19 - "@esbuild/win32-x64": 0.17.19 - dependenciesMeta: - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: ac11b1a5a6008e4e37ccffbd6c2c054746fc58d0ed4a2f9ee643bd030cfcea9a33a235087bc777def8420f2eaafb3486e76adb7bdb7241a9143b43a69a10afd8 - languageName: node - linkType: hard - -"esbuild@npm:^0.21.3": - version: 0.21.5 - resolution: "esbuild@npm:0.21.5" - dependencies: - "@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 +"esbuild@npm:^0.14.21": + version: 0.14.54 + resolution: "esbuild@npm:0.14.54" + dependencies: + "@esbuild/linux-loong64": 0.14.54 + esbuild-android-64: 0.14.54 + esbuild-android-arm64: 0.14.54 + esbuild-darwin-64: 0.14.54 + esbuild-darwin-arm64: 0.14.54 + esbuild-freebsd-64: 0.14.54 + esbuild-freebsd-arm64: 0.14.54 + esbuild-linux-32: 0.14.54 + esbuild-linux-64: 0.14.54 + esbuild-linux-arm: 0.14.54 + esbuild-linux-arm64: 0.14.54 + esbuild-linux-mips64le: 0.14.54 + esbuild-linux-ppc64le: 0.14.54 + esbuild-linux-riscv64: 0.14.54 + esbuild-linux-s390x: 0.14.54 + esbuild-netbsd-64: 0.14.54 + esbuild-openbsd-64: 0.14.54 + esbuild-sunos-64: 0.14.54 + esbuild-windows-32: 0.14.54 + esbuild-windows-64: 0.14.54 + esbuild-windows-arm64: 0.14.54 dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true "@esbuild/linux-loong64": optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 2911c7b50b23a9df59a7d6d4cdd3a4f85855787f374dce751148dbb13305e0ce7e880dde1608c2ab7a927fc6cec3587b80995f7fc87a64b455f8b70b55fd8ec1 - languageName: node - linkType: hard - -"esbuild@npm:^0.24.2": - version: 0.24.2 - resolution: "esbuild@npm:0.24.2" - dependencies: - "@esbuild/aix-ppc64": 0.24.2 - "@esbuild/android-arm": 0.24.2 - "@esbuild/android-arm64": 0.24.2 - "@esbuild/android-x64": 0.24.2 - "@esbuild/darwin-arm64": 0.24.2 - "@esbuild/darwin-x64": 0.24.2 - "@esbuild/freebsd-arm64": 0.24.2 - "@esbuild/freebsd-x64": 0.24.2 - "@esbuild/linux-arm": 0.24.2 - "@esbuild/linux-arm64": 0.24.2 - "@esbuild/linux-ia32": 0.24.2 - "@esbuild/linux-loong64": 0.24.2 - "@esbuild/linux-mips64el": 0.24.2 - "@esbuild/linux-ppc64": 0.24.2 - "@esbuild/linux-riscv64": 0.24.2 - "@esbuild/linux-s390x": 0.24.2 - "@esbuild/linux-x64": 0.24.2 - "@esbuild/netbsd-arm64": 0.24.2 - "@esbuild/netbsd-x64": 0.24.2 - "@esbuild/openbsd-arm64": 0.24.2 - "@esbuild/openbsd-x64": 0.24.2 - "@esbuild/sunos-x64": 0.24.2 - "@esbuild/win32-arm64": 0.24.2 - "@esbuild/win32-ia32": 0.24.2 - "@esbuild/win32-x64": 0.24.2 - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": + esbuild-android-64: optional: true - "@esbuild/freebsd-arm64": + esbuild-android-arm64: optional: true - "@esbuild/freebsd-x64": + esbuild-darwin-64: optional: true - "@esbuild/linux-arm": + esbuild-darwin-arm64: optional: true - "@esbuild/linux-arm64": + esbuild-freebsd-64: optional: true - "@esbuild/linux-ia32": + esbuild-freebsd-arm64: optional: true - "@esbuild/linux-loong64": + esbuild-linux-32: optional: true - "@esbuild/linux-mips64el": + esbuild-linux-64: optional: true - "@esbuild/linux-ppc64": + esbuild-linux-arm: optional: true - "@esbuild/linux-riscv64": + esbuild-linux-arm64: optional: true - "@esbuild/linux-s390x": + esbuild-linux-mips64le: optional: true - "@esbuild/linux-x64": + esbuild-linux-ppc64le: optional: true - "@esbuild/netbsd-arm64": + esbuild-linux-riscv64: optional: true - "@esbuild/netbsd-x64": + esbuild-linux-s390x: optional: true - "@esbuild/openbsd-arm64": + esbuild-netbsd-64: optional: true - "@esbuild/openbsd-x64": + esbuild-openbsd-64: optional: true - "@esbuild/sunos-x64": + esbuild-sunos-64: optional: true - "@esbuild/win32-arm64": + esbuild-windows-32: optional: true - "@esbuild/win32-ia32": + esbuild-windows-64: optional: true - "@esbuild/win32-x64": + esbuild-windows-arm64: optional: true bin: esbuild: bin/esbuild - checksum: e2303f8331887e31330b5a972fb9640ad93dfc5af76cb2156faa9eaa32bac5c403244096cbdafc45622829913e63664dfd88410987e3468df4354492f908a094 - languageName: node - linkType: hard - -"esbuild@npm:^0.25.0": - version: 0.25.9 - resolution: "esbuild@npm:0.25.9" - dependencies: - "@esbuild/aix-ppc64": 0.25.9 - "@esbuild/android-arm": 0.25.9 - "@esbuild/android-arm64": 0.25.9 - "@esbuild/android-x64": 0.25.9 - "@esbuild/darwin-arm64": 0.25.9 - "@esbuild/darwin-x64": 0.25.9 - "@esbuild/freebsd-arm64": 0.25.9 - "@esbuild/freebsd-x64": 0.25.9 - "@esbuild/linux-arm": 0.25.9 - "@esbuild/linux-arm64": 0.25.9 - "@esbuild/linux-ia32": 0.25.9 - "@esbuild/linux-loong64": 0.25.9 - "@esbuild/linux-mips64el": 0.25.9 - "@esbuild/linux-ppc64": 0.25.9 - "@esbuild/linux-riscv64": 0.25.9 - "@esbuild/linux-s390x": 0.25.9 - "@esbuild/linux-x64": 0.25.9 - "@esbuild/netbsd-arm64": 0.25.9 - "@esbuild/netbsd-x64": 0.25.9 - "@esbuild/openbsd-arm64": 0.25.9 - "@esbuild/openbsd-x64": 0.25.9 - "@esbuild/openharmony-arm64": 0.25.9 - "@esbuild/sunos-x64": 0.25.9 - "@esbuild/win32-arm64": 0.25.9 - "@esbuild/win32-ia32": 0.25.9 - "@esbuild/win32-x64": 0.25.9 + checksum: 49e360b1185c797f5ca3a7f5f0a75121494d97ddf691f65ed1796e6257d318f928342a97f559bb8eced6a90cf604dd22db4a30e0dbbf15edd9dbf22459b639af + languageName: node + linkType: hard + +"esbuild@npm:^0.18.10": + version: 0.18.20 + resolution: "esbuild@npm:0.18.20" + dependencies: + "@esbuild/android-arm": 0.18.20 + "@esbuild/android-arm64": 0.18.20 + "@esbuild/android-x64": 0.18.20 + "@esbuild/darwin-arm64": 0.18.20 + "@esbuild/darwin-x64": 0.18.20 + "@esbuild/freebsd-arm64": 0.18.20 + "@esbuild/freebsd-x64": 0.18.20 + "@esbuild/linux-arm": 0.18.20 + "@esbuild/linux-arm64": 0.18.20 + "@esbuild/linux-ia32": 0.18.20 + "@esbuild/linux-loong64": 0.18.20 + "@esbuild/linux-mips64el": 0.18.20 + "@esbuild/linux-ppc64": 0.18.20 + "@esbuild/linux-riscv64": 0.18.20 + "@esbuild/linux-s390x": 0.18.20 + "@esbuild/linux-x64": 0.18.20 + "@esbuild/netbsd-x64": 0.18.20 + "@esbuild/openbsd-x64": 0.18.20 + "@esbuild/sunos-x64": 0.18.20 + "@esbuild/win32-arm64": 0.18.20 + "@esbuild/win32-ia32": 0.18.20 + "@esbuild/win32-x64": 0.18.20 dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true "@esbuild/android-arm": optional: true "@esbuild/android-arm64": @@ -10559,16 +8745,10 @@ __metadata: optional: true "@esbuild/linux-x64": optional: true - "@esbuild/netbsd-arm64": - optional: true "@esbuild/netbsd-x64": optional: true - "@esbuild/openbsd-arm64": - optional: true "@esbuild/openbsd-x64": optional: true - "@esbuild/openharmony-arm64": - optional: true "@esbuild/sunos-x64": optional: true "@esbuild/win32-arm64": @@ -10579,38 +8759,38 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 718bc15016266da5b4675c2226923cadfe014b119e5c7a9240a6fe826c01ec2e7d5492af052e1c8a03b511778187f234cef2e994e6195287945ce0a824b79974 + checksum: 5d253614e50cdb6ec22095afd0c414f15688e7278a7eb4f3720a6dd1306b0909cf431e7b9437a90d065a31b1c57be60130f63fe3e8d0083b588571f31ee6ec7b languageName: node linkType: hard -"escalade@npm:^3.1.1, escalade@npm:^3.2.0": - version: 3.2.0 - resolution: "escalade@npm:3.2.0" - checksum: 47b029c83de01b0d17ad99ed766347b974b0d628e848de404018f3abee728e987da0d2d370ad4574aa3d5b5bfc368754fd085d69a30f8e75903486ec4b5b709e +"escalade@npm:^3.0.2, escalade@npm:^3.1.1": + version: 3.1.2 + resolution: "escalade@npm:3.1.2" + checksum: 1ec0977aa2772075493002bdbd549d595ff6e9393b1cb0d7d6fcaf78c750da0c158f180938365486f75cb69fba20294351caddfce1b46552a7b6c3cde52eaa02 languageName: node linkType: hard -"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": +"escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" checksum: 6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 languageName: node linkType: hard -"escape-string-regexp@npm:^1.0.5": - version: 1.0.5 - resolution: "escape-string-regexp@npm:1.0.5" - checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 - languageName: node - linkType: hard - -"escape-string-regexp@npm:^2.0.0": +"escape-string-regexp@npm:2.0.0, escape-string-regexp@npm:^2.0.0": version: 2.0.0 resolution: "escape-string-regexp@npm:2.0.0" checksum: 9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395 languageName: node linkType: hard +"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": + version: 1.0.5 + resolution: "escape-string-regexp@npm:1.0.5" + checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 + languageName: node + linkType: hard + "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -10655,38 +8835,40 @@ __metadata: languageName: node linkType: hard -"eslint-config-prettier@npm:^10.0.1": - version: 10.1.8 - resolution: "eslint-config-prettier@npm:10.1.8" +"eslint-config-prettier@npm:^8.5.0": + version: 8.10.0 + resolution: "eslint-config-prettier@npm:8.10.0" peerDependencies: eslint: ">=7.0.0" bin: eslint-config-prettier: bin/cli.js - checksum: 9140e19f78f0dbc888b160bb72b85f8043bada7b12a548faa56cea0ba74f8ef16653250ffd014d85d9a376a88c4941c96a3cdc9d39a07eb3def6967166635bd8 + checksum: 153266badd477e49b0759816246b2132f1dbdb6c7f313ca60a9af5822fd1071c2bc5684a3720d78b725452bbac04bb130878b2513aea5e72b1b792de5a69fec8 languageName: node linkType: hard -"eslint-config-react-app@npm:^7.0.1": - version: 7.0.1 - resolution: "eslint-config-react-app@npm:7.0.1" - dependencies: - "@babel/core": ^7.16.0 - "@babel/eslint-parser": ^7.16.3 - "@rushstack/eslint-patch": ^1.1.0 - "@typescript-eslint/eslint-plugin": ^5.5.0 - "@typescript-eslint/parser": ^5.5.0 - babel-preset-react-app: ^10.0.1 - confusing-browser-globals: ^1.0.11 - eslint-plugin-flowtype: ^8.0.3 - eslint-plugin-import: ^2.25.3 - eslint-plugin-jest: ^25.3.0 - eslint-plugin-jsx-a11y: ^6.5.1 - eslint-plugin-react: ^7.27.1 - eslint-plugin-react-hooks: ^4.3.0 - eslint-plugin-testing-library: ^5.0.1 - peerDependencies: - eslint: ^8.0.0 - checksum: a67e0821809e62308d6e419753fa2acfc7cd353659fab08cf34735f59c6c66910c0b6fda0471c4ec0d712ce762d65efc6431b39569f8d575e2d9bdfc384e0824 +"eslint-config-react-app@npm:^6.0.0": + version: 6.0.0 + resolution: "eslint-config-react-app@npm:6.0.0" + dependencies: + confusing-browser-globals: ^1.0.10 + peerDependencies: + "@typescript-eslint/eslint-plugin": ^4.0.0 + "@typescript-eslint/parser": ^4.0.0 + babel-eslint: ^10.0.0 + eslint: ^7.5.0 + eslint-plugin-flowtype: ^5.2.0 + eslint-plugin-import: ^2.22.0 + eslint-plugin-jest: ^24.0.0 + eslint-plugin-jsx-a11y: ^6.3.1 + eslint-plugin-react: ^7.20.3 + eslint-plugin-react-hooks: ^4.0.8 + eslint-plugin-testing-library: ^3.9.0 + peerDependenciesMeta: + eslint-plugin-jest: + optional: true + eslint-plugin-testing-library: + optional: true + checksum: b265852455b1c10e9c5f0cebe199306fffc7f8e1b6548fcb0bccdc4415c288dfee8ab10717122a32275b91130dfb482dcbbc87d2fb79d8728d4c2bfa889f0915 languageName: node linkType: hard @@ -10701,203 +8883,182 @@ __metadata: languageName: node linkType: hard -"eslint-module-utils@npm:^2.12.1": - version: 2.12.1 - resolution: "eslint-module-utils@npm:2.12.1" +"eslint-module-utils@npm:^2.8.0": + version: 2.8.1 + resolution: "eslint-module-utils@npm:2.8.1" dependencies: debug: ^3.2.7 peerDependenciesMeta: eslint: optional: true - checksum: 2f074670d8c934687820a83140048776b28bbaf35fc37f35623f63cc9c438d496d11f0683b4feabb9a120435435d4a69604b1c6c567f118be2c9a0aba6760fc1 + checksum: 3cecd99b6baf45ffc269167da0f95dcb75e5aa67b93d73a3bab63e2a7eedd9cdd6f188eed048e2f57c1b77db82c9cbf2adac20b512fa70e597d863dd3720170d languageName: node linkType: hard -"eslint-plugin-cypress@npm:4.3.0": - version: 4.3.0 - resolution: "eslint-plugin-cypress@npm:4.3.0" - dependencies: - globals: ^15.15.0 - peerDependencies: - eslint: ">=9" - checksum: 6e385e0111bce47b81defe04bf07bb81646e7a96266564e4b3835a9c7e768fd30871461ce2dfdcacdcded09b5e03cce9e47dea392557dfaa96dd5bf1138f1de8 - languageName: node - linkType: hard - -"eslint-plugin-flowtype@npm:^8.0.3": - version: 8.0.3 - resolution: "eslint-plugin-flowtype@npm:8.0.3" +"eslint-plugin-flowtype@npm:^5.2.0": + version: 5.10.0 + resolution: "eslint-plugin-flowtype@npm:5.10.0" dependencies: - lodash: ^4.17.21 + lodash: ^4.17.15 string-natural-compare: ^3.0.1 peerDependencies: - "@babel/plugin-syntax-flow": ^7.14.5 - "@babel/plugin-transform-react-jsx": ^7.14.9 - eslint: ^8.1.0 - checksum: 30e63c5357b0b5571f39afed51e59c140084f4aa53c106b1fd04f26da42b268908466daa6020b92943e71409bdaee1c67202515ed9012404d027cc92cb03cefa + eslint: ^7.1.0 + checksum: 791cd53c886bf819d52d6353cdfb4d49276dcd8a14f564a85d275d5017d81c7b1cc1921013ac9749f69c3f1bc4d23f36182137aab42bc059c2ae3f9773dd7740 languageName: node linkType: hard -"eslint-plugin-import@npm:^2.25.3": - version: 2.32.0 - resolution: "eslint-plugin-import@npm:2.32.0" +"eslint-plugin-import@npm:^2.22.1": + version: 2.29.1 + resolution: "eslint-plugin-import@npm:2.29.1" dependencies: - "@rtsao/scc": ^1.1.0 - array-includes: ^3.1.9 - array.prototype.findlastindex: ^1.2.6 - array.prototype.flat: ^1.3.3 - array.prototype.flatmap: ^1.3.3 + array-includes: ^3.1.7 + array.prototype.findlastindex: ^1.2.3 + array.prototype.flat: ^1.3.2 + array.prototype.flatmap: ^1.3.2 debug: ^3.2.7 doctrine: ^2.1.0 eslint-import-resolver-node: ^0.3.9 - eslint-module-utils: ^2.12.1 - hasown: ^2.0.2 - is-core-module: ^2.16.1 + eslint-module-utils: ^2.8.0 + hasown: ^2.0.0 + is-core-module: ^2.13.1 is-glob: ^4.0.3 minimatch: ^3.1.2 - object.fromentries: ^2.0.8 - object.groupby: ^1.0.3 - object.values: ^1.2.1 + object.fromentries: ^2.0.7 + object.groupby: ^1.0.1 + object.values: ^1.1.7 semver: ^6.3.1 - string.prototype.trimend: ^1.0.9 tsconfig-paths: ^3.15.0 peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - checksum: 8cd40595b5e4346d3698eb577014b4b6d0ba57b7b9edf975be4f052a89330ec202d0cc5c3861d37ebeafa151b6264821410243889b0c31710911a6b625bcf76b + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + checksum: e65159aef808136d26d029b71c8c6e4cb5c628e65e5de77f1eb4c13a379315ae55c9c3afa847f43f4ff9df7e54515c77ffc6489c6a6f81f7dd7359267577468c languageName: node linkType: hard -"eslint-plugin-jest@npm:^25.3.0": - version: 25.7.0 - resolution: "eslint-plugin-jest@npm:25.7.0" +"eslint-plugin-jest@npm:^24.1.0": + version: 24.7.0 + resolution: "eslint-plugin-jest@npm:24.7.0" dependencies: - "@typescript-eslint/experimental-utils": ^5.0.0 + "@typescript-eslint/experimental-utils": ^4.0.1 peerDependencies: - "@typescript-eslint/eslint-plugin": ^4.0.0 || ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + "@typescript-eslint/eslint-plugin": ">= 4" + eslint: ">=5" peerDependenciesMeta: "@typescript-eslint/eslint-plugin": optional: true - jest: - optional: true - checksum: fc6da96131f4cbf33d15ef911ec8e600ccd71deb97d73c0ca340427cef7b01ff41a797e2e7d1e351abf97321a46ed0c0acff5ee8eeedac94961dd6dad1f718a9 + checksum: a4056582825ab3359d2e0e3aae50518f6f867d1cfb3240496605247d3ff9c84b4164f1a7e1f7087d5a2eae1343d738ada1ba74c422b13ad20b737601dc47ae08 languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:^6.5.1": - version: 6.10.2 - resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" +"eslint-plugin-jsx-a11y@npm:^6.3.1": + version: 6.8.0 + resolution: "eslint-plugin-jsx-a11y@npm:6.8.0" dependencies: - aria-query: ^5.3.2 - array-includes: ^3.1.8 + "@babel/runtime": ^7.23.2 + aria-query: ^5.3.0 + array-includes: ^3.1.7 array.prototype.flatmap: ^1.3.2 ast-types-flow: ^0.0.8 - axe-core: ^4.10.0 - axobject-query: ^4.1.0 + axe-core: =4.7.0 + axobject-query: ^3.2.1 damerau-levenshtein: ^1.0.8 emoji-regex: ^9.2.2 - hasown: ^2.0.2 + es-iterator-helpers: ^1.0.15 + hasown: ^2.0.0 jsx-ast-utils: ^3.3.5 language-tags: ^1.0.9 minimatch: ^3.1.2 - object.fromentries: ^2.0.8 - safe-regex-test: ^1.0.3 - string.prototype.includes: ^2.0.1 + object.entries: ^1.1.7 + object.fromentries: ^2.0.7 peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - checksum: 0cc861398fa26ada61ed5703eef5b335495fcb96253263dcd5e399488ff019a2636372021baacc040e3560d1a34bfcd5d5ad9f1754f44cd0509c956f7df94050 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + checksum: 3dec00e2a3089c4c61ac062e4196a70985fb7eda1fd67fe035363d92578debde92fdb8ed2e472321fc0d71e75f4a1e8888c6a3218c14dd93c8e8d19eb6f51554 languageName: node linkType: hard -"eslint-plugin-prettier@npm:^5.2.2": - version: 5.5.4 - resolution: "eslint-plugin-prettier@npm:5.5.4" +"eslint-plugin-prettier@npm:^4.2.1": + version: 4.2.1 + resolution: "eslint-plugin-prettier@npm:4.2.1" dependencies: prettier-linter-helpers: ^1.0.0 - synckit: ^0.11.7 peerDependencies: - "@types/eslint": ">=8.0.0" - eslint: ">=8.0.0" - eslint-config-prettier: ">= 7.0.0 <10.0.0 || >=10.1.0" - prettier: ">=3.0.0" + eslint: ">=7.28.0" + prettier: ">=2.0.0" peerDependenciesMeta: - "@types/eslint": - optional: true eslint-config-prettier: optional: true - checksum: 0dd05ed85018ab0e98da80325b7bd4c4ab6dd684398f1270a7c8cf4261df714dd4502ba4c7f85f651aade9989da0a7d2adda03af8873b73b52014141abf385de + checksum: b9e839d2334ad8ec7a5589c5cb0f219bded260839a857d7a486997f9870e95106aa59b8756ff3f37202085ebab658de382b0267cae44c3a7f0eb0bcc03a4f6d6 languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^4.3.0": - version: 4.6.2 - resolution: "eslint-plugin-react-hooks@npm:4.6.2" +"eslint-plugin-react-hooks@npm:^4.2.0": + version: 4.6.0 + resolution: "eslint-plugin-react-hooks@npm:4.6.0" peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 395c433610f59577cfcf3f2e42bcb130436c8a0b3777ac64f441d88c5275f4fcfc89094cedab270f2822daf29af1079151a7a6579a8e9ea8cee66540ba0384c4 + checksum: 23001801f14c1d16bf0a837ca7970d9dd94e7b560384b41db378b49b6e32dc43d6e2790de1bd737a652a86f81a08d6a91f402525061b47719328f586a57e86c3 languageName: node linkType: hard -"eslint-plugin-react@npm:^7.27.1": - version: 7.37.5 - resolution: "eslint-plugin-react@npm:7.37.5" +"eslint-plugin-react@npm:^7.21.5": + version: 7.34.1 + resolution: "eslint-plugin-react@npm:7.34.1" dependencies: - array-includes: ^3.1.8 - array.prototype.findlast: ^1.2.5 - array.prototype.flatmap: ^1.3.3 - array.prototype.tosorted: ^1.1.4 + array-includes: ^3.1.7 + array.prototype.findlast: ^1.2.4 + array.prototype.flatmap: ^1.3.2 + array.prototype.toreversed: ^1.1.2 + array.prototype.tosorted: ^1.1.3 doctrine: ^2.1.0 - es-iterator-helpers: ^1.2.1 + es-iterator-helpers: ^1.0.17 estraverse: ^5.3.0 - hasown: ^2.0.2 jsx-ast-utils: ^2.4.1 || ^3.0.0 minimatch: ^3.1.2 - object.entries: ^1.1.9 - object.fromentries: ^2.0.8 - object.values: ^1.2.1 + object.entries: ^1.1.7 + object.fromentries: ^2.0.7 + object.hasown: ^1.1.3 + object.values: ^1.1.7 prop-types: ^15.8.1 resolve: ^2.0.0-next.5 semver: ^6.3.1 - string.prototype.matchall: ^4.0.12 - string.prototype.repeat: ^1.0.0 + string.prototype.matchall: ^4.0.10 peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - checksum: 8675e7558e646e3c2fcb04bb60cfe416000b831ef0b363f0117838f5bfc799156113cb06058ad4d4b39fc730903b7360b05038da11093064ca37caf76b7cf2ca + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + checksum: 82f391c5a093235c3bc2f664c54e009c49460778ee7d1b86c1536df9ac4d2a80d1dedc9241ac797df4a9dced936e955d9c89042fb3ac8d017b5359d1320d3c0f languageName: node linkType: hard -"eslint-plugin-testing-library@npm:^5.0.1": - version: 5.11.1 - resolution: "eslint-plugin-testing-library@npm:5.11.1" +"eslint-plugin-testing-library@npm:^3.9.2": + version: 3.10.2 + resolution: "eslint-plugin-testing-library@npm:3.10.2" dependencies: - "@typescript-eslint/utils": ^5.58.0 + "@typescript-eslint/experimental-utils": ^3.10.1 peerDependencies: - eslint: ^7.5.0 || ^8.0.0 - checksum: 9f3fc68ef9f13016a4381b33ab5dbffcc189e5de3eaeba184bcf7d2771faa7f54e59c04b652162fb1c0f83fb52428dd909db5450a25508b94be59eba69fcc990 + eslint: ^5 || ^6 || ^7 + checksum: 3859d4a4816b130cfefc3b45bc7d303aff19b8d4e83a5e35ca3d634de9f3c4aa1b4340cb4f41e2d1bfe70b173562b9882c58ac48be4e07ddf6a1f88659e2604d languageName: node linkType: hard -"eslint-scope@npm:5.1.1, eslint-scope@npm:^5.1.1": - version: 5.1.1 - resolution: "eslint-scope@npm:5.1.1" +"eslint-scope@npm:^4.0.3": + version: 4.0.3 + resolution: "eslint-scope@npm:4.0.3" dependencies: - esrecurse: ^4.3.0 + esrecurse: ^4.1.0 estraverse: ^4.1.1 - checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb + checksum: c5f835f681884469991fe58d76a554688d9c9e50811299ccd4a8f79993a039f5bcb0ee6e8de2b0017d97c794b5832ef3b21c9aac66228e3aa0f7a0485bcfb65b languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-scope@npm:^5.0.0, eslint-scope@npm:^5.1.1": + version: 5.1.1 + resolution: "eslint-scope@npm:5.1.1" dependencies: esrecurse: ^4.3.0 - estraverse: ^5.2.0 - checksum: ec97dbf5fb04b94e8f4c5a91a7f0a6dd3c55e46bfc7bbcd0e3138c3a76977570e02ed89a1810c778dcd72072ff0e9621ba1379b4babe53921d71e2e4486fda3e + estraverse: ^4.1.1 + checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb languageName: node linkType: hard -"eslint-utils@npm:^2.1.0": +"eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0": version: 2.1.0 resolution: "eslint-utils@npm:2.1.0" dependencies: @@ -10906,51 +9067,49 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^1.1.0, eslint-visitor-keys@npm:^1.3.0": +"eslint-utils@npm:^3.0.0": + version: 3.0.0 + resolution: "eslint-utils@npm:3.0.0" + dependencies: + eslint-visitor-keys: ^2.0.0 + peerDependencies: + eslint: ">=5" + checksum: 0668fe02f5adab2e5a367eee5089f4c39033af20499df88fe4e6aba2015c20720404d8c3d6349b6f716b08fdf91b9da4e5d5481f265049278099c4c836ccb619 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^1.0.0, eslint-visitor-keys@npm:^1.1.0, eslint-visitor-keys@npm:^1.3.0": version: 1.3.0 resolution: "eslint-visitor-keys@npm:1.3.0" checksum: 37a19b712f42f4c9027e8ba98c2b06031c17e0c0a4c696cd429bd9ee04eb43889c446f2cd545e1ff51bef9593fcec94ecd2c2ef89129fcbbf3adadbef520376a languageName: node linkType: hard -"eslint-visitor-keys@npm:^2.0.0, eslint-visitor-keys@npm:^2.1.0": +"eslint-visitor-keys@npm:^2.0.0": version: 2.1.0 resolution: "eslint-visitor-keys@npm:2.1.0" checksum: e3081d7dd2611a35f0388bbdc2f5da60b3a3c5b8b6e928daffff7391146b434d691577aa95064c8b7faad0b8a680266bcda0a42439c18c717b80e6718d7e267d languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": - version: 3.4.3 - resolution: "eslint-visitor-keys@npm:3.4.3" - checksum: 36e9ef87fca698b6fd7ca5ca35d7b2b6eeaaf106572e2f7fd31c12d3bfdaccdb587bba6d3621067e5aece31c8c3a348b93922ab8f7b2cbc6aaab5e1d89040c60 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^4.2.0": - version: 4.2.1 - resolution: "eslint-visitor-keys@npm:4.2.1" - checksum: 3a77e3f99a49109f6fb2c5b7784bc78f9743b834d238cdba4d66c602c6b52f19ed7bcd0a5c5dbbeae3a8689fd785e76c001799f53d2228b278282cf9f699fff5 - languageName: node - linkType: hard - -"eslint-webpack-plugin@npm:^3.1.1": - version: 3.2.0 - resolution: "eslint-webpack-plugin@npm:3.2.0" +"eslint-webpack-plugin@npm:^2.5.2": + version: 2.7.0 + resolution: "eslint-webpack-plugin@npm:2.7.0" dependencies: - "@types/eslint": ^7.29.0 || ^8.4.1 - jest-worker: ^28.0.2 + "@types/eslint": ^7.29.0 + arrify: ^2.0.1 + jest-worker: ^27.5.1 micromatch: ^4.0.5 normalize-path: ^3.0.0 - schema-utils: ^4.0.0 + schema-utils: ^3.1.1 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - webpack: ^5.0.0 - checksum: 095034c35e773fdb21ec7e597ae1f8a6899679c290db29d8568ca94619e8c7f4971f0f9edccc8a965322ab8af9286c87205985a38f4fdcf17654aee7cd8bb7b5 + webpack: ^4.0.0 || ^5.0.0 + checksum: b6fd7cf4c49078b345a908b82b0bee06bc82ab0cec214ddd5fe5bb18b065765d52a07ad4077f6bba5830ba2f55f37d8f2208a52d11f34ee29df81153e3124d9c languageName: node linkType: hard -"eslint@npm:^7.0.0": +"eslint@npm:^7.0.0, eslint@npm:^7.11.0": version: 7.32.0 resolution: "eslint@npm:7.32.0" dependencies: @@ -11000,51 +9159,15 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.3.0": - version: 8.57.1 - resolution: "eslint@npm:8.57.1" +"esniff@npm:^2.0.1": + version: 2.0.1 + resolution: "esniff@npm:2.0.1" dependencies: - "@eslint-community/eslint-utils": ^4.2.0 - "@eslint-community/regexpp": ^4.6.1 - "@eslint/eslintrc": ^2.1.4 - "@eslint/js": 8.57.1 - "@humanwhocodes/config-array": ^0.13.0 - "@humanwhocodes/module-importer": ^1.0.1 - "@nodelib/fs.walk": ^1.2.8 - "@ungap/structured-clone": ^1.2.0 - ajv: ^6.12.4 - chalk: ^4.0.0 - cross-spawn: ^7.0.2 - debug: ^4.3.2 - doctrine: ^3.0.0 - escape-string-regexp: ^4.0.0 - eslint-scope: ^7.2.2 - eslint-visitor-keys: ^3.4.3 - espree: ^9.6.1 - esquery: ^1.4.2 - esutils: ^2.0.2 - fast-deep-equal: ^3.1.3 - file-entry-cache: ^6.0.1 - find-up: ^5.0.0 - glob-parent: ^6.0.2 - globals: ^13.19.0 - graphemer: ^1.4.0 - ignore: ^5.2.0 - imurmurhash: ^0.1.4 - is-glob: ^4.0.0 - is-path-inside: ^3.0.3 - js-yaml: ^4.1.0 - json-stable-stringify-without-jsonify: ^1.0.1 - levn: ^0.4.1 - lodash.merge: ^4.6.2 - minimatch: ^3.1.2 - natural-compare: ^1.4.0 - optionator: ^0.9.3 - strip-ansi: ^6.0.1 - text-table: ^0.2.0 - bin: - eslint: bin/eslint.js - checksum: e2489bb7f86dd2011967759a09164e65744ef7688c310bc990612fc26953f34cc391872807486b15c06833bdff737726a23e9b4cdba5de144c311377dc41d91b + d: ^1.0.1 + es5-ext: ^0.10.62 + event-emitter: ^0.3.5 + type: ^2.7.2 + checksum: d814c0e5c39bce9925b2e65b6d8767af72c9b54f35a65f9f3d6e8c606dce9aebe35a9599d30f15b0807743f88689f445163cfb577a425de4fb8c3c5bc16710cc languageName: node linkType: hard @@ -11059,17 +9182,6 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" - dependencies: - acorn: ^8.9.0 - acorn-jsx: ^5.3.2 - eslint-visitor-keys: ^3.4.1 - checksum: eb8c149c7a2a77b3f33a5af80c10875c3abd65450f60b8af6db1bfcfa8f101e21c1e56a561c6dc13b848e18148d43469e7cd208506238554fb5395a9ea5a1ab9 - languageName: node - linkType: hard - "esprima@npm:1.2.2": version: 1.2.2 resolution: "esprima@npm:1.2.2" @@ -11090,16 +9202,16 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.0, esquery@npm:^1.4.2": - version: 1.6.0 - resolution: "esquery@npm:1.6.0" +"esquery@npm:^1.4.0": + version: 1.5.0 + resolution: "esquery@npm:1.5.0" dependencies: estraverse: ^5.1.0 - checksum: 08ec4fe446d9ab27186da274d979558557fbdbbd10968fa9758552482720c54152a5640e08b9009e5a30706b66aba510692054d4129d32d0e12e05bbc0b96fb2 + checksum: aefb0d2596c230118656cd4ec7532d447333a410a48834d80ea648b1e7b5c9bc9ed8b5e33a89cb04e487b60d622f44cf5713bf4abed7c97343edefdc84a35900 languageName: node linkType: hard -"esrecurse@npm:^4.3.0": +"esrecurse@npm:^4.1.0, esrecurse@npm:^4.3.0": version: 4.3.0 resolution: "esrecurse@npm:4.3.0" dependencies: @@ -11122,10 +9234,10 @@ __metadata: languageName: node linkType: hard -"estree-util-is-identifier-name@npm:^3.0.0": - version: 3.0.0 - resolution: "estree-util-is-identifier-name@npm:3.0.0" - checksum: ea3909f0188ea164af0aadeca87c087e3e5da78d76da5ae9c7954ff1340ea3e4679c4653bbf4299ffb70caa9b322218cc1128db2541f3d2976eb9704f9857787 +"estree-walker@npm:^0.6.1": + version: 0.6.1 + resolution: "estree-walker@npm:0.6.1" + checksum: 9d6f82a4921f11eec18f8089fb3cce6e53bcf45a8e545c42a2674d02d055fb30f25f90495f8be60803df6c39680c80dcee7f944526867eb7aa1fc9254883b23d languageName: node linkType: hard @@ -11136,15 +9248,6 @@ __metadata: languageName: node linkType: hard -"estree-walker@npm:^3.0.3": - version: 3.0.3 - resolution: "estree-walker@npm:3.0.3" - dependencies: - "@types/estree": ^1.0.0 - checksum: a65728d5727b71de172c5df323385755a16c0fdab8234dc756c3854cfee343261ddfbb72a809a5660fac8c75d960bb3e21aa898c2d7e9b19bb298482ca58a3af - languageName: node - linkType: hard - "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -11152,48 +9255,98 @@ __metadata: languageName: node linkType: hard -"etag@npm:^1.8.1, etag@npm:~1.8.1": +"etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff languageName: node linkType: hard -"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.1, eventemitter3@npm:^4.0.4": - version: 4.0.7 - resolution: "eventemitter3@npm:4.0.7" - checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 +"event-emitter@npm:^0.3.5": + version: 0.3.5 + resolution: "event-emitter@npm:0.3.5" + dependencies: + d: 1 + es5-ext: ~0.10.14 + checksum: 27c1399557d9cd7e0aa0b366c37c38a4c17293e3a10258e8b692a847dd5ba9fb90429c3a5a1eeff96f31f6fa03ccbd31d8ad15e00540b22b22f01557be706030 languageName: node linkType: hard -"eventemitter3@npm:^5.0.1": - version: 5.0.1 - resolution: "eventemitter3@npm:5.0.1" - checksum: 543d6c858ab699303c3c32e0f0f47fc64d360bf73c3daf0ac0b5079710e340d6fe9f15487f94e66c629f5f82cd1a8678d692f3dbb6f6fcd1190e1b97fcad36f8 +"eventemitter3@npm:^3.1.0": + version: 3.1.2 + resolution: "eventemitter3@npm:3.1.2" + checksum: 81e4e82b8418f5cfd986d2b4a2fa5397ac4eb8134e09bcb47005545e22fdf8e9e61d5c053d34651112245aae411bdfe6d0ad5511da0400743fef5fc38bfcfbe3 + languageName: node + linkType: hard + +"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.4": + version: 4.0.7 + resolution: "eventemitter3@npm:4.0.7" + checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 languageName: node linkType: hard -"events@npm:^3.2.0": +"events@npm:^3.0.0, events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780 languageName: node linkType: hard -"execa@npm:^5.0.0": - version: 5.1.1 - resolution: "execa@npm:5.1.1" +"eventsource@npm:^2.0.2": + version: 2.0.2 + resolution: "eventsource@npm:2.0.2" + checksum: c0072d972753e10c705d9b2285b559184bf29d011bc208973dde9c8b6b8b7b6fdad4ef0846cecb249f7b1585e860fdf324cbd2ac854a76bc53649e797496e99a + languageName: node + linkType: hard + +"evp_bytestokey@npm:^1.0.0, evp_bytestokey@npm:^1.0.3": + version: 1.0.3 + resolution: "evp_bytestokey@npm:1.0.3" + dependencies: + md5.js: ^1.3.4 + node-gyp: latest + safe-buffer: ^5.1.1 + checksum: ad4e1577f1a6b721c7800dcc7c733fe01f6c310732bb5bf2240245c2a5b45a38518b91d8be2c610611623160b9d1c0e91f1ce96d639f8b53e8894625cf20fa45 + languageName: node + linkType: hard + +"exec-sh@npm:^0.3.2": + version: 0.3.6 + resolution: "exec-sh@npm:0.3.6" + checksum: 0be4f06929c8e4834ea4812f29fe59e2dfcc1bc3fc4b4bb71acb38a500c3b394628a05ef7ba432520bc6c5ec4fadab00cc9c513c4ff6a32104965af302e998e0 + languageName: node + linkType: hard + +"execa@npm:^1.0.0": + version: 1.0.0 + resolution: "execa@npm:1.0.0" dependencies: - cross-spawn: ^7.0.3 - get-stream: ^6.0.0 - human-signals: ^2.1.0 + cross-spawn: ^6.0.0 + get-stream: ^4.0.0 + is-stream: ^1.1.0 + npm-run-path: ^2.0.0 + p-finally: ^1.0.0 + signal-exit: ^3.0.0 + strip-eof: ^1.0.0 + checksum: ddf1342c1c7d02dd93b41364cd847640f6163350d9439071abf70bf4ceb1b9b2b2e37f54babb1d8dc1df8e0d8def32d0e81e74a2e62c3e1d70c303eb4c306bc4 + languageName: node + linkType: hard + +"execa@npm:^4.0.0": + version: 4.1.0 + resolution: "execa@npm:4.1.0" + dependencies: + cross-spawn: ^7.0.0 + get-stream: ^5.0.0 + human-signals: ^1.1.1 is-stream: ^2.0.0 merge-stream: ^2.0.0 - npm-run-path: ^4.0.1 - onetime: ^5.1.2 - signal-exit: ^3.0.3 + npm-run-path: ^4.0.0 + onetime: ^5.1.0 + signal-exit: ^3.0.2 strip-final-newline: ^2.0.0 - checksum: fba9022c8c8c15ed862847e94c252b3d946036d7547af310e344a527e59021fd8b6bb0723883ea87044dc4f0201f949046993124a42ccb0855cae5bf8c786343 + checksum: e30d298934d9c52f90f3847704fd8224e849a081ab2b517bbc02f5f7732c24e56a21f14cb96a08256deffeb2d12b2b7cb7e2b014a12fb36f8d3357e06417ed55 languageName: node linkType: hard @@ -11204,29 +9357,45 @@ __metadata: languageName: node linkType: hard -"expand-template@npm:^2.0.3": - version: 2.0.3 - resolution: "expand-template@npm:2.0.3" - checksum: 588c19847216421ed92befb521767b7018dc88f88b0576df98cb242f20961425e96a92cbece525ef28cc5becceae5d544ae0f5b9b5e2aa05acb13716ca5b3099 +"expand-brackets@npm:^2.1.4": + version: 2.1.4 + resolution: "expand-brackets@npm:2.1.4" + dependencies: + debug: ^2.3.3 + define-property: ^0.2.5 + extend-shallow: ^2.0.1 + posix-character-classes: ^0.1.0 + regex-not: ^1.0.0 + snapdragon: ^0.8.1 + to-regex: ^3.0.1 + checksum: 1781d422e7edfa20009e2abda673cadb040a6037f0bd30fcd7357304f4f0c284afd420d7622722ca4a016f39b6d091841ab57b401c1f7e2e5131ac65b9f14fa1 languageName: node linkType: hard -"expect-type@npm:^1.1.0, expect-type@npm:^1.2.1": - version: 1.2.2 - resolution: "expect-type@npm:1.2.2" - checksum: dc347e853b059f95f3c897db2a6f5eab37662e7a0c3c9fcf014f25afa90fca76e5235246fd37e08f2c0535901b52f66b8ace1e0ee236673c4f70c36724bd3f42 +"expect@npm:^26.6.0, expect@npm:^26.6.2": + version: 26.6.2 + resolution: "expect@npm:26.6.2" + dependencies: + "@jest/types": ^26.6.2 + ansi-styles: ^4.0.0 + jest-get-type: ^26.3.0 + jest-matcher-utils: ^26.6.2 + jest-message-util: ^26.6.2 + jest-regex-util: ^26.0.0 + checksum: 79a9b888c5c6d37d11f2cb76def6cf1dc8ff098d38662ee20c9f2ee0da67e9a93435f2327854b2e7554732153870621843e7f83e8cefb1250447ee2bc39883a4 languageName: node linkType: hard -"expect@npm:^27.5.1": - version: 27.5.1 - resolution: "expect@npm:27.5.1" +"expect@npm:^28.0.0": + version: 28.1.3 + resolution: "expect@npm:28.1.3" dependencies: - "@jest/types": ^27.5.1 - jest-get-type: ^27.5.1 - jest-matcher-utils: ^27.5.1 - jest-message-util: ^27.5.1 - checksum: b2c66beb52de53ef1872165aace40224e722bca3c2274c54cfa74b6d617d55cf0ccdbf36783ccd64dbea501b280098ed33fd0b207d4f15bc03cd3c7a24364a6a + "@jest/expect-utils": ^28.1.3 + jest-get-type: ^28.0.2 + jest-matcher-utils: ^28.1.3 + jest-message-util: ^28.1.3 + jest-util: ^28.1.3 + checksum: 101e0090de300bcafedb7dbfd19223368a2251ce5fe0105bbb6de5720100b89fb6b64290ebfb42febc048324c76d6a4979cdc4b61eb77747857daf7a5de9b03d languageName: node linkType: hard @@ -11244,20 +9413,20 @@ __metadata: linkType: hard "exponential-backoff@npm:^3.1.1": - version: 3.1.2 - resolution: "exponential-backoff@npm:3.1.2" - checksum: 7e191e3dd6edd8c56c88f2c8037c98fbb8034fe48778be53ed8cb30ccef371a061a4e999a469aab939b92f8f12698f3b426d52f4f76b7a20da5f9f98c3cbc862 + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 3d21519a4f8207c99f7457287291316306255a328770d320b401114ec8481986e4e467e854cb9914dd965e0a1ca810a23ccb559c642c88f4c7f55c55778a9b48 languageName: node linkType: hard "express-jwt@npm:^7.7.5": - version: 7.7.8 - resolution: "express-jwt@npm:7.7.8" + version: 7.7.7 + resolution: "express-jwt@npm:7.7.7" dependencies: "@types/jsonwebtoken": ^8.5.8 express-unless: ^2.1.3 - jsonwebtoken: ^9.0.2 - checksum: 88ea57e7c033bafd5918cdbddd67f469a3e70f9ae3c5c973b370ef0b9f86e3499ea132fb15d9ecdddcc97d8305dec1f759a1fdf4dfc8a1a9e6642e166188e28b + jsonwebtoken: ^8.5.1 + checksum: b3aec510ce490cd8d449604c82ce1debf9b8c215fb0220f78d07e86c555fb06ca93b4199da135c00e62bb98c67a47fac8c1fdcc6ea74f2047f4e2defbc4578fe languageName: node linkType: hard @@ -11278,77 +9447,70 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.0.0, express@npm:^4.17.3": - version: 4.21.2 - resolution: "express@npm:4.21.2" +"express@npm:^4.17.1": + version: 4.19.2 + resolution: "express@npm:4.19.2" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.3 + body-parser: 1.20.2 content-disposition: 0.5.4 content-type: ~1.0.4 - cookie: 0.7.1 + cookie: 0.6.0 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: ~2.0.0 + encodeurl: ~1.0.2 escape-html: ~1.0.3 etag: ~1.8.1 - finalhandler: 1.3.1 + finalhandler: 1.2.0 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.3 + merge-descriptors: 1.0.1 methods: ~1.1.2 on-finished: 2.4.1 parseurl: ~1.3.3 - path-to-regexp: 0.1.12 + path-to-regexp: 0.1.7 proxy-addr: ~2.0.7 - qs: 6.13.0 + qs: 6.11.0 range-parser: ~1.2.1 safe-buffer: 5.2.1 - send: 0.19.0 - serve-static: 1.16.2 + send: 0.18.0 + serve-static: 1.15.0 setprototypeof: 1.2.0 statuses: 2.0.1 type-is: ~1.6.18 utils-merge: 1.0.1 vary: ~1.1.2 - checksum: 3aef1d355622732e20b8f3a7c112d4391d44e2131f4f449e1f273a309752a41abfad714e881f177645517cbe29b3ccdc10b35e7e25c13506114244a5b72f549d + checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 languageName: node linkType: hard -"express@npm:^5.0.0": - version: 5.1.0 - resolution: "express@npm:5.1.0" - dependencies: - accepts: ^2.0.0 - body-parser: ^2.2.0 - content-disposition: ^1.0.0 - content-type: ^1.0.5 - cookie: ^0.7.1 - cookie-signature: ^1.2.1 - debug: ^4.4.0 - encodeurl: ^2.0.0 - escape-html: ^1.0.3 - etag: ^1.8.1 - finalhandler: ^2.1.0 - fresh: ^2.0.0 - http-errors: ^2.0.0 - merge-descriptors: ^2.0.0 - mime-types: ^3.0.0 - on-finished: ^2.4.1 - once: ^1.4.0 - parseurl: ^1.3.3 - proxy-addr: ^2.0.7 - qs: ^6.14.0 - range-parser: ^1.2.1 - router: ^2.2.0 - send: ^1.1.0 - serve-static: ^2.2.0 - statuses: ^2.0.1 - type-is: ^2.0.1 - vary: ^1.1.2 - checksum: 06e6141780c6c4780111f971ce062c83d4cf4862c40b43caf1d95afcbb58d7422c560503b8c9d04c7271511525d09cbdbe940bcaad63970fd4c1b9f6fd713bdb +"ext@npm:^1.7.0": + version: 1.7.0 + resolution: "ext@npm:1.7.0" + dependencies: + type: ^2.7.2 + checksum: ef481f9ef45434d8c867cfd09d0393b60945b7c8a1798bedc4514cb35aac342ccb8d8ecb66a513e6a2b4ec1e294a338e3124c49b29736f8e7c735721af352c31 + languageName: node + linkType: hard + +"extend-shallow@npm:^2.0.1": + version: 2.0.1 + resolution: "extend-shallow@npm:2.0.1" + dependencies: + is-extendable: ^0.1.0 + checksum: 8fb58d9d7a511f4baf78d383e637bd7d2e80843bd9cd0853649108ea835208fb614da502a553acc30208e1325240bb7cc4a68473021612496bb89725483656d8 + languageName: node + linkType: hard + +"extend-shallow@npm:^3.0.0, extend-shallow@npm:^3.0.2": + version: 3.0.2 + resolution: "extend-shallow@npm:3.0.2" + dependencies: + assign-symbols: ^1.0.0 + is-extendable: ^1.0.1 + checksum: a920b0cd5838a9995ace31dfd11ab5e79bf6e295aa566910ce53dff19f4b1c0fda2ef21f26b28586c7a2450ca2b42d97bd8c0f5cec9351a819222bf861e02461 languageName: node linkType: hard @@ -11359,6 +9521,33 @@ __metadata: languageName: node linkType: hard +"external-editor@npm:^3.0.3": + version: 3.1.0 + resolution: "external-editor@npm:3.1.0" + dependencies: + chardet: ^0.7.0 + iconv-lite: ^0.4.24 + tmp: ^0.0.33 + checksum: 1c2a616a73f1b3435ce04030261bed0e22d4737e14b090bb48e58865da92529c9f2b05b893de650738d55e692d071819b45e1669259b2b354bc3154d27a698c7 + languageName: node + linkType: hard + +"extglob@npm:^2.0.4": + version: 2.0.4 + resolution: "extglob@npm:2.0.4" + dependencies: + array-unique: ^0.3.2 + define-property: ^1.0.0 + expand-brackets: ^2.1.4 + extend-shallow: ^2.0.1 + fragment-cache: ^0.2.1 + regex-not: ^1.0.0 + snapdragon: ^0.8.1 + to-regex: ^3.0.1 + checksum: a41531b8934735b684cef5e8c5a01d0f298d7d384500ceca38793a9ce098125aab04ee73e2d75d5b2901bc5dddd2b64e1b5e3bf19139ea48bac52af4a92f1d00 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -11373,27 +9562,20 @@ __metadata: languageName: node linkType: hard -"fast-equals@npm:^5.0.1": - version: 5.2.2 - resolution: "fast-equals@npm:5.2.2" - checksum: 7156bcade0be5ee4dc335969d255a5815348d57080e1876fa1584451eafd0c92588de5f5840e55f81841b6d907ade2a49a46e4ec33e6f7a283a209c0fd8f8a59 - languageName: node - linkType: hard - -"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": - version: 3.3.3 - resolution: "fast-glob@npm:3.3.3" +"fast-glob@npm:^3.1.1, fast-glob@npm:^3.2.9": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" dependencies: "@nodelib/fs.stat": ^2.0.2 "@nodelib/fs.walk": ^1.2.3 glob-parent: ^5.1.2 merge2: ^1.3.0 - micromatch: ^4.0.8 - checksum: 0704d7b85c0305fd2cef37777337dfa26230fdd072dce9fb5c82a4b03156f3ffb8ed3e636033e65d45d2a5805a4e475825369a27404c0307f2db0c8eb3366fbd + micromatch: ^4.0.4 + checksum: 900e4979f4dbc3313840078419245621259f349950411ca2fa445a2f9a1a6d98c3b5e7e0660c5ccd563aa61abe133a21765c6c0dec8e57da1ba71d8000b05ec1 languageName: node linkType: hard -"fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": +"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: b191531e36c607977e5b1c47811158733c34ccb3bfde92c44798929e9b4154884378536d26ad90dfecd32e1ffc09c545d23535ad91b3161a27ddbb8ebe0cbecb @@ -11421,34 +9603,23 @@ __metadata: languageName: node linkType: hard -"fast-uri@npm:^3.0.1": - version: 3.1.0 - resolution: "fast-uri@npm:3.1.0" - checksum: daab0efd3548cc53d0db38ecc764d125773f8bd70c34552ff21abdc6530f26fa4cb1771f944222ca5e61a0a1a85d01a104848ff88c61736de445d97bd616ea7e - languageName: node - linkType: hard - -"fast-xml-parser@npm:5.2.5": - version: 5.2.5 - resolution: "fast-xml-parser@npm:5.2.5" - dependencies: - strnum: ^2.1.0 - bin: - fxparser: src/cli/cli.js - checksum: b12daa933bc226bd7df1e1ecbd305e561c83fd6e4a234b5e2728901deca25a9b9522b9d3ebafde41b1f4d87ab814e3efe18c636638580795fdbe4670a556be88 +"fastparse@npm:^1.1.2": + version: 1.1.2 + resolution: "fastparse@npm:1.1.2" + checksum: c4d199809dc4e8acafeb786be49481cc9144de296e2d54df4540ccfd868d0df73afc649aba70a748925eb32bbc4208b723d6288adf92382275031a8c7e10c0aa languageName: node linkType: hard "fastq@npm:^1.6.0": - version: 1.19.1 - resolution: "fastq@npm:1.19.1" + version: 1.17.1 + resolution: "fastq@npm:1.17.1" dependencies: reusify: ^1.0.4 - checksum: 7691d1794fb84ad0ec2a185f10e00f0e1713b894e2c9c4d42f0bc0ba5f8c00e6e655a202074ca0b91b9c3d977aab7c30c41a8dc069fb5368576ac0054870a0e6 + checksum: a8c5b26788d5a1763f88bae56a8ddeee579f935a831c5fe7a8268cea5b0a91fbfe705f612209e02d639b881d7b48e461a50da4a10cfaa40da5ca7cc9da098d88 languageName: node linkType: hard -"faye-websocket@npm:^0.11.3": +"faye-websocket@npm:^0.11.3, faye-websocket@npm:^0.11.4": version: 0.11.4 resolution: "faye-websocket@npm:0.11.4" dependencies: @@ -11466,15 +9637,19 @@ __metadata: languageName: node linkType: hard -"fdir@npm:^6.5.0": - version: 6.5.0 - resolution: "fdir@npm:6.5.0" - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - checksum: bd537daa9d3cd53887eed35efa0eab2dbb1ca408790e10e024120e7a36c6e9ae2b33710cb8381e35def01bc9c1d7eaba746f886338413e68ff6ebaee07b9a6e8 +"figgy-pudding@npm:^3.5.1": + version: 3.5.2 + resolution: "figgy-pudding@npm:3.5.2" + checksum: 4090bd66193693dcda605e44d6b8715d8fb5c92a67acd57826e55cf816a342f550d57e5638f822b39366e1b2fdb244e99b3068a37213aa1d6c1bf602b8fde5ae + languageName: node + linkType: hard + +"figures@npm:^3.0.0": + version: 3.2.0 + resolution: "figures@npm:3.2.0" + dependencies: + escape-string-regexp: ^1.0.5 + checksum: 85a6ad29e9aca80b49b817e7c89ecc4716ff14e3779d9835af554db91bac41c0f289c418923519392a1e582b4d10482ad282021330cd045bb7b80c84152f2a2b languageName: node linkType: hard @@ -11487,15 +9662,15 @@ __metadata: languageName: node linkType: hard -"file-loader@npm:^6.2.0": - version: 6.2.0 - resolution: "file-loader@npm:6.2.0" +"file-loader@npm:6.1.1": + version: 6.1.1 + resolution: "file-loader@npm:6.1.1" dependencies: loader-utils: ^2.0.0 schema-utils: ^3.0.0 peerDependencies: webpack: ^4.0.0 || ^5.0.0 - checksum: faf43eecf233f4897b0150aaa874eeeac214e4f9de49738a9e0ef734a30b5260059e85b7edadf852b98e415f875bd5f12587768a93fd52aaf2e479ecf95fab20 + checksum: 6369da5af456b640599d7ede7a3a9a55e485138a7829c583313d5165d0984c3d337de3aebee32fdfa3295facb4a44b74a9c3c956b1e0e30e8c96152106ff4b23 languageName: node linkType: hard @@ -11506,57 +9681,64 @@ __metadata: languageName: node linkType: hard -"filelist@npm:^1.0.4": - version: 1.0.4 - resolution: "filelist@npm:1.0.4" - dependencies: - minimatch: ^5.0.1 - checksum: a303573b0821e17f2d5e9783688ab6fbfce5d52aaac842790ae85e704a6f5e4e3538660a63183d6453834dedf1e0f19a9dadcebfa3e926c72397694ea11f5160 +"file-uri-to-path@npm:1.0.0": + version: 1.0.0 + resolution: "file-uri-to-path@npm:1.0.0" + checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 languageName: node linkType: hard -"filesize@npm:^8.0.6": - version: 8.0.7 - resolution: "filesize@npm:8.0.7" - checksum: 8603d27c5287b984cb100733640645e078f5f5ad65c6d913173e01fb99e09b0747828498fd86647685ccecb69be31f3587b9739ab1e50732116b2374aff4cbf9 +"filesize@npm:6.1.0": + version: 6.1.0 + resolution: "filesize@npm:6.1.0" + checksum: c46d644cb562fba7b7e837d5cd339394492abaa06722018b91a97d2a63b6c753ef30653de5c03bf178c631185bf55c3561c28fa9ccc4e9755f42d853c6ed4d09 languageName: node linkType: hard -"fill-range@npm:^7.1.1": - version: 7.1.1 - resolution: "fill-range@npm:7.1.1" +"fill-range@npm:^4.0.0": + version: 4.0.0 + resolution: "fill-range@npm:4.0.0" + dependencies: + extend-shallow: ^2.0.1 + is-number: ^3.0.0 + repeat-string: ^1.6.1 + to-regex-range: ^2.1.0 + checksum: dbb5102467786ab42bc7a3ec7380ae5d6bfd1b5177b2216de89e4a541193f8ba599a6db84651bd2c58c8921db41b8cc3d699ea83b477342d3ce404020f73c298 + languageName: node + linkType: hard + +"fill-range@npm:^7.0.1": + version: 7.0.1 + resolution: "fill-range@npm:7.0.1" dependencies: to-regex-range: ^5.0.1 - checksum: b4abfbca3839a3d55e4ae5ec62e131e2e356bf4859ce8480c64c4876100f4df292a63e5bb1618e1d7460282ca2b305653064f01654474aa35c68000980f17798 + checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917 languageName: node linkType: hard -"finalhandler@npm:1.3.1": - version: 1.3.1 - resolution: "finalhandler@npm:1.3.1" +"finalhandler@npm:1.2.0": + version: 1.2.0 + resolution: "finalhandler@npm:1.2.0" dependencies: debug: 2.6.9 - encodeurl: ~2.0.0 + encodeurl: ~1.0.2 escape-html: ~1.0.3 on-finished: 2.4.1 parseurl: ~1.3.3 statuses: 2.0.1 unpipe: ~1.0.0 - checksum: a8c58cd97c9cd47679a870f6833a7b417043f5a288cd6af6d0f49b476c874a506100303a128b6d3b654c3d74fa4ff2ffed68a48a27e8630cda5c918f2977dcf4 + checksum: 92effbfd32e22a7dff2994acedbd9bcc3aa646a3e919ea6a53238090e87097f8ef07cced90aa2cc421abdf993aefbdd5b00104d55c7c5479a8d00ed105b45716 languageName: node linkType: hard -"finalhandler@npm:^2.1.0": +"find-cache-dir@npm:^2.1.0": version: 2.1.0 - resolution: "finalhandler@npm:2.1.0" + resolution: "find-cache-dir@npm:2.1.0" dependencies: - debug: ^4.4.0 - encodeurl: ^2.0.0 - escape-html: ^1.0.3 - on-finished: ^2.4.1 - parseurl: ^1.3.3 - statuses: ^2.0.1 - checksum: 27ca9cc83b1384ba37959eb95bc7e62bc0bf4d6f6af63f6d38821cf7499b113e34b23f96a2a031616817f73986f94deea67c2f558de9daf406790c181a2501df + commondir: ^1.0.1 + make-dir: ^2.0.0 + pkg-dir: ^3.0.0 + checksum: 60ad475a6da9f257df4e81900f78986ab367d4f65d33cf802c5b91e969c28a8762f098693d7a571b6e4dd4c15166c2da32ae2d18b6766a18e2071079448fdce4 languageName: node linkType: hard @@ -11578,16 +9760,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^3.0.0": - version: 3.0.0 - resolution: "find-up@npm:3.0.0" - dependencies: - locate-path: ^3.0.0 - checksum: 38eba3fe7a66e4bc7f0f5a1366dc25508b7cfc349f852640e3678d26ad9a6d7e2c43eff0a472287de4a9753ef58f066a0ea892a256fa3636ad51b3fe1e17fae9 - languageName: node - linkType: hard - -"find-up@npm:^4.0.0, find-up@npm:^4.1.0": +"find-up@npm:4.1.0, find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -11597,13 +9770,12 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^5.0.0": - version: 5.0.0 - resolution: "find-up@npm:5.0.0" +"find-up@npm:^3.0.0": + version: 3.0.0 + resolution: "find-up@npm:3.0.0" dependencies: - locate-path: ^6.0.0 - path-exists: ^4.0.0 - checksum: 07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 + locate-path: ^3.0.0 + checksum: 38eba3fe7a66e4bc7f0f5a1366dc25508b7cfc349f852640e3678d26ad9a6d7e2c43eff0a472287de4a9753ef58f066a0ea892a256fa3636ad51b3fe1e17fae9 languageName: node linkType: hard @@ -11615,24 +9787,21 @@ __metadata: "@babel/plugin-transform-object-assign": ^7.18.6 "@babel/preset-react": ^7.18.6 "@babel/preset-typescript": ^7.18.6 - "@types/jest": ^29.5.14 - "@types/multer": ^1.4.12 - "@types/node": 20.0.0 - "@typescript-eslint/eslint-plugin": 8.20.0 - "@typescript-eslint/parser": 8.20.0 - concurrently: ^9.1.0 + "@testing-library/jest-dom": ^5.16.4 + "@types/jest": ^28.1.6 + "@types/node": 18.17.1 + "@types/nodemailer": ^6.4.7 + "@types/react-query": ^1.2.9 + "@typescript-eslint/eslint-plugin": ^4.18.0 + "@typescript-eslint/parser": ^4.18.0 + concurrently: ^5.2.0 eslint: ^7.0.0 - eslint-config-prettier: ^10.0.1 - eslint-config-react-app: ^7.0.1 - eslint-plugin-cypress: 4.3.0 - eslint-plugin-prettier: ^5.2.2 - mitt: ^3.0.1 - prettier: ^3.4.2 - react-hook-form-persist: ^3.0.0 - recharts: ^2.15.3 - rimraf: ^6.0.1 + eslint-config-prettier: ^8.5.0 + eslint-plugin-prettier: ^4.2.1 + prettier: ^2.0.5 + rimraf: ^3.0.2 ts-node: ^10.9.1 - typescript: ^5.7.3 + typescript: ^4.1.5 languageName: unknown linkType: soft @@ -11648,107 +9817,122 @@ __metadata: linkType: hard "flatted@npm:^3.2.9": - version: 3.3.3 - resolution: "flatted@npm:3.3.3" - checksum: 8c96c02fbeadcf4e8ffd0fa24983241e27698b0781295622591fc13585e2f226609d95e422bcf2ef044146ffacb6b68b1f20871454eddf75ab3caa6ee5f4a1fe + version: 3.3.1 + resolution: "flatted@npm:3.3.1" + checksum: 85ae7181650bb728c221e7644cbc9f4bf28bc556f2fc89bb21266962bdf0ce1029cc7acc44bb646cd469d9baac7c317f64e841c4c4c00516afa97320cdac7f94 + languageName: node + linkType: hard + +"flatten@npm:^1.0.2": + version: 1.0.3 + resolution: "flatten@npm:1.0.3" + checksum: 5c57379816f1692aaa79fbc6390e0a0644e5e8442c5783ed57c6d315468eddbc53a659eaa03c9bb1e771b0f4a9bd8dd8a2620286bf21fd6538a7857321fdfb20 + languageName: node + linkType: hard + +"flush-write-stream@npm:^1.0.0": + version: 1.1.1 + resolution: "flush-write-stream@npm:1.1.1" + dependencies: + inherits: ^2.0.3 + readable-stream: ^2.3.6 + checksum: 42e07747f83bcd4e799da802e621d6039787749ffd41f5517f8c4f786ee967e31ba32b09f8b28a9c6f67bd4f5346772e604202df350e8d99f4141771bae31279 languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.6": - version: 1.15.11 - resolution: "follow-redirects@npm:1.15.11" +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.9, follow-redirects@npm:^1.15.6": + version: 1.15.6 + resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: debug: optional: true - checksum: 20bf55e9504f59e6cc3743ba27edb2ebf41edea1baab34799408f2c050f73f0c612728db21c691276296d2795ea8a812dc532a98e8793619fcab91abe06d017f + checksum: a62c378dfc8c00f60b9c80cab158ba54e99ba0239a5dd7c81245e5a5b39d10f0c35e249c3379eae719ff0285fff88c365dd446fab19dee771f1d76252df1bbf5 languageName: node linkType: hard -"for-each@npm:^0.3.3, for-each@npm:^0.3.5": - version: 0.3.5 - resolution: "for-each@npm:0.3.5" +"for-each@npm:^0.3.3": + version: 0.3.3 + resolution: "for-each@npm:0.3.3" dependencies: - is-callable: ^1.2.7 - checksum: 3c986d7e11f4381237cc98baa0a2f87eabe74719eee65ed7bed275163082b940ede19268c61d04c6260e0215983b12f8d885e3c8f9aa8c2113bf07c37051745c + is-callable: ^1.1.3 + checksum: 6c48ff2bc63362319c65e2edca4a8e1e3483a2fabc72fbe7feaf8c73db94fc7861bd53bc02c8a66a0c1dd709da6b04eec42e0abdd6b40ce47305ae92a25e5d28 languageName: node linkType: hard -"foreground-child@npm:^3.1.0, foreground-child@npm:^3.3.1": - version: 3.3.1 - resolution: "foreground-child@npm:3.3.1" +"for-in@npm:^1.0.2": + version: 1.0.2 + resolution: "for-in@npm:1.0.2" + checksum: 09f4ae93ce785d253ac963d94c7f3432d89398bf25ac7a24ed034ca393bf74380bdeccc40e0f2d721a895e54211b07c8fad7132e8157827f6f7f059b70b4043d + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" dependencies: - cross-spawn: ^7.0.6 + cross-spawn: ^7.0.0 signal-exit: ^4.0.1 - checksum: b2c1a6fc0bf0233d645d9fefdfa999abf37db1b33e5dab172b3cbfb0662b88bfbd2c9e7ab853533d199050ec6b65c03fcf078fc212d26e4990220e98c6930eef + checksum: 139d270bc82dc9e6f8bc045fe2aae4001dc2472157044fdfad376d0a3457f77857fa883c1c8b21b491c6caade9a926a4bed3d3d2e8d3c9202b151a4cbbd0bcd5 languageName: node linkType: hard -"fork-ts-checker-webpack-plugin@npm:^6.5.0": - version: 6.5.3 - resolution: "fork-ts-checker-webpack-plugin@npm:6.5.3" +"fork-ts-checker-webpack-plugin@npm:4.1.6": + version: 4.1.6 + resolution: "fork-ts-checker-webpack-plugin@npm:4.1.6" dependencies: - "@babel/code-frame": ^7.8.3 - "@types/json-schema": ^7.0.5 - chalk: ^4.1.0 - chokidar: ^3.4.2 - cosmiconfig: ^6.0.0 - deepmerge: ^4.2.2 - fs-extra: ^9.0.0 - glob: ^7.1.6 - memfs: ^3.1.2 + "@babel/code-frame": ^7.5.5 + chalk: ^2.4.1 + micromatch: ^3.1.10 minimatch: ^3.0.4 - schema-utils: 2.7.0 - semver: ^7.3.2 + semver: ^5.6.0 tapable: ^1.0.0 - peerDependencies: - eslint: ">= 6" - typescript: ">= 2.7" - vue-template-compiler: "*" - webpack: ">= 4" - peerDependenciesMeta: - eslint: - optional: true - vue-template-compiler: - optional: true - checksum: 9732a49bfeed8fc23e6e8a59795fa7c238edeba91040a9b520db54b4d316dda27f9f1893d360e296fd0ad8930627d364417d28a8c7007fba60cc730ebfce4956 + worker-rpc: ^0.1.0 + checksum: 4cc4fa7919dd9a0d765514d064c86e3a6f9cea8e700996b3e775cfcc0280f606a2dd16203d9b7e294b64e900795b0d80eb41fc8c192857d3350e407f14ef3eed + languageName: node + linkType: hard + +"form-data@npm:^2.5.0": + version: 2.5.1 + resolution: "form-data@npm:2.5.1" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.6 + mime-types: ^2.1.12 + checksum: 5134ada56cc246b293a1ac7678dba6830000603a3979cf83ff7b2f21f2e3725202237cfb89e32bcb38a1d35727efbd3c3a22e65b42321e8ade8eec01ce755d08 languageName: node linkType: hard "form-data@npm:^3.0.0": - version: 3.0.4 - resolution: "form-data@npm:3.0.4" + version: 3.0.1 + resolution: "form-data@npm:3.0.1" dependencies: asynckit: ^0.4.0 combined-stream: ^1.0.8 - es-set-tostringtag: ^2.1.0 - hasown: ^2.0.2 - mime-types: ^2.1.35 - checksum: 989005f575b9a14a30144df1745ef60c64cf901e648ae198bf63e5caeaf8dacf595a85dfd56f90a845eceb14fe1bea58b3845e8171337a4cf72781fa19867efc + mime-types: ^2.1.12 + checksum: b019e8d35c8afc14a2bd8a7a92fa4f525a4726b6d5a9740e8d2623c30e308fbb58dc8469f90415a856698933c8479b01646a9dff33c87cc4e76d72aedbbf860d languageName: node linkType: hard -"form-data@npm:^4.0.0, form-data@npm:^4.0.4": - version: 4.0.4 - resolution: "form-data@npm:4.0.4" +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" dependencies: asynckit: ^0.4.0 combined-stream: ^1.0.8 - es-set-tostringtag: ^2.1.0 - hasown: ^2.0.2 mime-types: ^2.1.12 - checksum: 9b7788836df9fa5a6999e0c02515b001946b2a868cfe53f026c69e2c537a2ff9fbfb8e9d2b678744628f3dc7a2d6e14e4e45dfaf68aa6239727f0bdb8ce0abf2 + checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c languageName: node linkType: hard "formidable@npm:^2.1.2": - version: 2.1.5 - resolution: "formidable@npm:2.1.5" + version: 2.1.2 + resolution: "formidable@npm:2.1.2" dependencies: - "@paralleldrive/cuid2": ^2.2.2 dezalgo: ^1.0.4 + hexoid: ^1.0.0 once: ^1.4.0 qs: ^6.11.0 - checksum: b7a38dbf3f2d32858e9199f9e1597038d22854dc7f3120e30a05097fd538c3a5ebdfcb1b14ed3d68139f592176e64a3544aa14b5be624e26fe5b383a5c096a74 + checksum: 81c8e5d89f5eb873e992893468f0de22c01678ca3d315db62be0560f9de1c77d4faefc9b1f4575098eb2263b3c81ba1024833a9fc3206297ddbac88a4f69b7a8 languageName: node linkType: hard @@ -11759,10 +9943,12 @@ __metadata: languageName: node linkType: hard -"fraction.js@npm:^4.3.7": - version: 4.3.7 - resolution: "fraction.js@npm:4.3.7" - checksum: e1553ae3f08e3ba0e8c06e43a3ab20b319966dfb7ddb96fd9b5d0ee11a66571af7f993229c88ebbb0d4a816eb813a24ed48207b140d442a8f76f33763b8d1f3f +"fragment-cache@npm:^0.2.1": + version: 0.2.1 + resolution: "fragment-cache@npm:0.2.1" + dependencies: + map-cache: ^0.2.2 + checksum: 1cbbd0b0116b67d5790175de0038a11df23c1cd2e8dcdbade58ebba5594c2d641dade6b4f126d82a7b4a6ffc2ea12e3d387dbb64ea2ae97cf02847d436f60fdc languageName: node linkType: hard @@ -11773,10 +9959,13 @@ __metadata: languageName: node linkType: hard -"fresh@npm:^2.0.0": - version: 2.0.0 - resolution: "fresh@npm:2.0.0" - checksum: 38b9828352c6271e2a0dd8bdd985d0100dbbc4eb8b6a03286071dd6f7d96cfaacd06d7735701ad9a95870eb3f4555e67c08db1dcfe24c2e7bb87383c72fae1d2 +"from2@npm:^2.1.0": + version: 2.3.0 + resolution: "from2@npm:2.3.0" + dependencies: + inherits: ^2.0.1 + readable-stream: ^2.0.0 + checksum: 6080eba0793dce32f475141fb3d54cc15f84ee52e420ee22ac3ab0ad639dc95a1875bc6eb9c0e1140e94972a36a89dc5542491b85f1ab8df0c126241e0f1a61b languageName: node linkType: hard @@ -11786,88 +9975,80 @@ __metadata: dependencies: "@emotion/react": ^11.10.4 "@emotion/styled": ^11.10.4 - "@hello-pangea/dnd": ^17.0.0 - "@hookform/resolvers": ^3.10.0 - "@mui/icons-material": ^6.4.0 - "@mui/lab": 6.0.0-beta.10 - "@mui/material": ^6.4.0 - "@mui/system": ^6.4.0 + "@hookform/resolvers": ^2.9.7 + "@mui/icons-material": ^5.10.3 + "@mui/material": ^5.10.3 + "@mui/system": ^5.10.16 "@mui/x-data-grid": ^5.16.0 - "@mui/x-date-pickers": ^7.24.0 - "@react-oauth/google": ^0.12.1 - "@testing-library/dom": ^10.4.0 - "@testing-library/jest-dom": ^6.6.3 - "@testing-library/react": ^16.2.0 + "@mui/x-date-pickers": ^6.19.4 + "@testing-library/dom": ^8.19.0 + "@testing-library/jest-dom": ^5.11.9 + "@testing-library/react": ^11.2.5 "@testing-library/react-hooks": ^8.0.1 - "@testing-library/user-event": ^14.6.0 + "@testing-library/user-event": ^12.6.3 "@types/file-saver": ^2.0.5 - "@types/node": 20.0.0 - "@types/react": ^19.0.7 - "@types/react-dom": ^19.0.3 + "@types/node": 18.17.1 + "@types/react": ^18.2.15 + "@types/react-dom": ^18.2.7 "@types/react-helmet": ^6.1.6 "@types/react-query": ^1.2.9 "@types/react-router-dom": ^5.1.7 - "@types/uuid": ^10.0.0 "@vitejs/plugin-react": ^4.0.0 - axios: ^1.7.9 - bootstrap: ^5.3.0 - chart.js: 4.4.6 - chartjs-plugin-datalabels: ^2.2.0 + axios: ^0.27.2 + bootstrap: ^4.6.0 classnames: ^2.3.1 - customize-cra: ^1.0.0 - date-fns: ^4.1.0 + customize-cra: ^0.9.1 dayjs: ^1.11.10 file-saver: ^2.0.5 - google-auth-library: ^9.15.0 + google-auth-library: ^8.1.1 jest-fail-on-console: ^3.0.2 - msw: ^2.7.0 + msw: ^0.44.2 pdf-lib: ^1.17.1 - react: 19.0.0 - react-archer: ^4.4.0 - react-chartjs-2: 5.2.0 - react-dom: 19.0.0 - react-draggable: ^4.4.6 - react-google-charts: ^5.2.1 + react: ^18.2.0 + react-dom: ^18.2.0 + react-google-charts: ^4.0.0 + react-google-login: ^5.2.2 react-helmet: ^6.1.0 react-hook-form: ^7.34.0 - react-hook-form-persist: ^3.0.0 - react-markdown: ^9.0.3 - react-pdf: ^9.2.1 + react-markdown: ^6.0.0 react-query: 3.17.0 react-router-dom: ^5.2.0 - react-scripts: ^5.0.1 + react-scripts: ^4.0.1 react-use-measure: ^2.1.1 sass: ^1.54.0 shared: 1.0.0 - typed-scss-modules: ^8.1.1 - typescript: 5.7.3 - uuid: ^11.1.0 - vite: 6.0.7 - vitest: ^2.1.8 - web-vitals: ^4.2.4 - yup: ^1.6.1 + typed-scss-modules: ^6.5.0 + typescript: ^4.1.5 + vite: ^4.4.5 + vitest: ^0.32.1 + web-vitals: ^0.2.4 + yup: ^0.32.11 languageName: unknown linkType: soft -"fs-constants@npm:^1.0.0": - version: 1.0.0 - resolution: "fs-constants@npm:1.0.0" - checksum: 18f5b718371816155849475ac36c7d0b24d39a11d91348cfcb308b4494824413e03572c403c86d3a260e049465518c4f0d5bd00f0371cdfcad6d4f30a85b350d +"fs-extra@npm:^7.0.0": + version: 7.0.1 + resolution: "fs-extra@npm:7.0.1" + dependencies: + graceful-fs: ^4.1.2 + jsonfile: ^4.0.0 + universalify: ^0.1.0 + checksum: 141b9dccb23b66a66cefdd81f4cda959ff89282b1d721b98cea19ba08db3dcbe6f862f28841f3cf24bb299e0b7e6c42303908f65093cb7e201708e86ea5a8dcf languageName: node linkType: hard -"fs-extra@npm:^10.0.0": - version: 10.1.0 - resolution: "fs-extra@npm:10.1.0" +"fs-extra@npm:^8.1.0": + version: 8.1.0 + resolution: "fs-extra@npm:8.1.0" dependencies: graceful-fs: ^4.2.0 - jsonfile: ^6.0.1 - universalify: ^2.0.0 - checksum: dc94ab37096f813cc3ca12f0f1b5ad6744dfed9ed21e953d72530d103cea193c2f81584a39e9dee1bea36de5ee66805678c0dddc048e8af1427ac19c00fffc50 + jsonfile: ^4.0.0 + universalify: ^0.1.0 + checksum: bf44f0e6cea59d5ce071bba4c43ca76d216f89e402dc6285c128abc0902e9b8525135aa808adad72c9d5d218e9f4bcc63962815529ff2f684ad532172a284880 languageName: node linkType: hard -"fs-extra@npm:^9.0.0, fs-extra@npm:^9.0.1": +"fs-extra@npm:^9.0.1": version: 9.1.0 resolution: "fs-extra@npm:9.1.0" dependencies: @@ -11879,6 +10060,15 @@ __metadata: languageName: node linkType: hard +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: ^3.0.0 + checksum: 1b8d128dae2ac6cc94230cc5ead341ba3e0efaef82dab46a33d171c044caaa6ca001364178d42069b2809c35a1c3c35079a32107c770e9ffab3901b59af8c8b1 + languageName: node + linkType: hard + "fs-minipass@npm:^3.0.0": version: 3.0.3 resolution: "fs-minipass@npm:3.0.3" @@ -11888,10 +10078,15 @@ __metadata: languageName: node linkType: hard -"fs-monkey@npm:^1.0.4": - version: 1.1.0 - resolution: "fs-monkey@npm:1.1.0" - checksum: ebb6305a37ca4731ffe9aceae21be40992fe5384f7a25819a1d64d17c649e7eeac3fc9ad6269cad6fffc409df0f4583253c93a930549fd82d5f8aed46beb5b9b +"fs-write-stream-atomic@npm:^1.0.8": + version: 1.0.10 + resolution: "fs-write-stream-atomic@npm:1.0.10" + dependencies: + graceful-fs: ^4.1.2 + iferr: ^0.1.5 + imurmurhash: ^0.1.4 + readable-stream: 1 || 2 + checksum: 43c2d6817b72127793abc811ebf87a135b03ac7cbe41cdea9eeacf59b23e6e29b595739b083e9461303d525687499a1aaefcec3e5ff9bc82b170edd3dc467ccc languageName: node linkType: hard @@ -11902,7 +10097,18 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:2.3.3, fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": +"fsevents@npm:^1.2.7": + version: 1.2.13 + resolution: "fsevents@npm:1.2.13" + dependencies: + bindings: ^1.5.0 + nan: ^2.12.1 + checksum: ae855aa737aaa2f9167e9f70417cf6e45a5cd11918e1fee9923709a0149be52416d765433b4aeff56c789b1152e718cd1b13ddec6043b78cdda68260d86383c1 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@npm:^2.1.2, fsevents@npm:^2.1.3, fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -11912,7 +10118,17 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@2.3.3#~builtin, fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin, fsevents@patch:fsevents@~2.3.3#~builtin": +"fsevents@patch:fsevents@^1.2.7#~builtin": + version: 1.2.13 + resolution: "fsevents@patch:fsevents@npm%3A1.2.13#~builtin::version=1.2.13&hash=18f3a7" + dependencies: + bindings: ^1.5.0 + nan: ^2.12.1 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@^2.1.2#~builtin, fsevents@patch:fsevents@^2.1.3#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=18f3a7" dependencies: @@ -11928,17 +10144,15 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8": - version: 1.1.8 - resolution: "function.prototype.name@npm:1.1.8" +"function.prototype.name@npm:^1.1.5, function.prototype.name@npm:^1.1.6": + version: 1.1.6 + resolution: "function.prototype.name@npm:1.1.6" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.3 - define-properties: ^1.2.1 + call-bind: ^1.0.2 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 functions-have-names: ^1.2.3 - hasown: ^2.0.2 - is-callable: ^1.2.7 - checksum: 3a366535dc08b25f40a322efefa83b2da3cd0f6da41db7775f2339679120ef63b6c7e967266182609e655b8f0a8f65596ed21c7fd72ad8bd5621c2340edd4010 + checksum: 7a3f9bd98adab09a07f6e1f03da03d3f7c26abbdeaeee15223f6c04a9fb5674792bdf5e689dac19b97ac71de6aad2027ba3048a9b883aa1b3173eed6ab07f479 languageName: node linkType: hard @@ -11968,19 +10182,6 @@ __metadata: languageName: node linkType: hard -"gaxios@npm:^6.0.0, gaxios@npm:^6.1.1": - version: 6.7.1 - resolution: "gaxios@npm:6.7.1" - dependencies: - extend: ^3.0.2 - https-proxy-agent: ^7.0.1 - is-stream: ^2.0.0 - node-fetch: ^2.6.9 - uuid: ^9.0.1 - checksum: ed5952655339918e0868c6f4e079d6e9e55b20a242ddb1be25076cdfb0dd1ca5a2cb233da7352baa972c19f898a78fa6ba67e7d848717c9ca9877c269b5b02f7 - languageName: node - linkType: hard - "gcp-metadata@npm:^5.3.0": version: 5.3.0 resolution: "gcp-metadata@npm:5.3.0" @@ -11991,27 +10192,7 @@ __metadata: languageName: node linkType: hard -"gcp-metadata@npm:^6.1.0": - version: 6.1.1 - resolution: "gcp-metadata@npm:6.1.1" - dependencies: - gaxios: ^6.1.1 - google-logging-utils: ^0.0.2 - json-bigint: ^1.0.0 - checksum: 7dffe884fd718482b559a841da469dc30e766a4b86c71cda96bed42579763d58f28328238b2eb424c29ba10ef45d4bb8a6586441921734f01012b55bbea79711 - languageName: node - linkType: hard - -"generic-names@npm:^4.0.0": - version: 4.0.0 - resolution: "generic-names@npm:4.0.0" - dependencies: - loader-utils: ^3.2.0 - checksum: 8dabd2505164191501b75f2861b5e1194458a344ae2a7c9776bdd72d1f50b248dff737bcdf118fff677275edb3632f2d10662e6ac122dd7b245c5baa8d303270 - languageName: node - linkType: hard - -"gensync@npm:^1.0.0-beta.2": +"gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" checksum: a7437e58c6be12aa6c90f7730eac7fa9833dc78872b4ad2963d2031b00a3367a93f98aec75f9aaac7220848e4026d67a8655e870b24f20a543d103c0d65952ec @@ -12025,21 +10206,23 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0": - version: 1.3.0 - resolution: "get-intrinsic@npm:1.3.0" +"get-func-name@npm:^2.0.1, get-func-name@npm:^2.0.2": + version: 2.0.2 + resolution: "get-func-name@npm:2.0.2" + checksum: 3f62f4c23647de9d46e6f76d2b3eafe58933a9b3830c60669e4180d6c601ce1b4aa310ba8366143f55e52b139f992087a9f0647274e8745621fa2af7e0acf13b + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" dependencies: - call-bind-apply-helpers: ^1.0.2 - es-define-property: ^1.0.1 es-errors: ^1.3.0 - es-object-atoms: ^1.1.1 function-bind: ^1.1.2 - get-proto: ^1.0.1 - gopd: ^1.2.0 - has-symbols: ^1.1.0 - hasown: ^2.0.2 - math-intrinsics: ^1.1.0 - checksum: 301008e4482bb9a9cb49e132b88fee093bff373b4e6def8ba219b1e96b60158a6084f273ef5cafe832e42cd93462f4accb46a618d35fe59a2b507f2388c5b79d + has-proto: ^1.0.1 + has-symbols: ^1.0.3 + hasown: ^2.0.0 + checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951 languageName: node linkType: hard @@ -12057,38 +10240,49 @@ __metadata: languageName: node linkType: hard -"get-proto@npm:^1.0.0, get-proto@npm:^1.0.1": - version: 1.0.1 - resolution: "get-proto@npm:1.0.1" +"get-stream@npm:^4.0.0": + version: 4.1.0 + resolution: "get-stream@npm:4.1.0" dependencies: - dunder-proto: ^1.0.1 - es-object-atoms: ^1.0.0 - checksum: 4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b + pump: ^3.0.0 + checksum: 443e1914170c15bd52ff8ea6eff6dfc6d712b031303e36302d2778e3de2506af9ee964d6124010f7818736dcfde05c04ba7ca6cc26883106e084357a17ae7d73 languageName: node linkType: hard -"get-stream@npm:^6.0.0": - version: 6.0.1 - resolution: "get-stream@npm:6.0.1" - checksum: e04ecece32c92eebf5b8c940f51468cd53554dcbb0ea725b2748be583c9523d00128137966afce410b9b051eb2ef16d657cd2b120ca8edafcf5a65e81af63cad +"get-stream@npm:^5.0.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: ^3.0.0 + checksum: 8bc1a23174a06b2b4ce600df38d6c98d2ef6d84e020c1ddad632ad75bac4e092eeb40e4c09e0761c35fc2dbc5e7fff5dab5e763a383582c4a167dd69a905bd12 languageName: node linkType: hard -"get-symbol-description@npm:^1.1.0": - version: 1.1.0 - resolution: "get-symbol-description@npm:1.1.0" +"get-symbol-description@npm:^1.0.2": + version: 1.0.2 + resolution: "get-symbol-description@npm:1.0.2" dependencies: - call-bound: ^1.0.3 + call-bind: ^1.0.5 es-errors: ^1.3.0 - get-intrinsic: ^1.2.6 - checksum: 655ed04db48ee65ef2ddbe096540d4405e79ba0a7f54225775fef43a7e2afcb93a77d141c5f05fdef0afce2eb93bcbfb3597142189d562ac167ff183582683cd + get-intrinsic: ^1.2.4 + checksum: e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973 languageName: node linkType: hard -"github-from-package@npm:0.0.0": - version: 0.0.0 - resolution: "github-from-package@npm:0.0.0" - checksum: 14e448192a35c1e42efee94c9d01a10f42fe790375891a24b25261246ce9336ab9df5d274585aedd4568f7922246c2a78b8a8cd2571bfe99c693a9718e7dd0e3 +"get-value@npm:^2.0.3, get-value@npm:^2.0.6": + version: 2.0.6 + resolution: "get-value@npm:2.0.6" + checksum: 5c3b99cb5398ea8016bf46ff17afc5d1d286874d2ad38ca5edb6e87d75c0965b0094cb9a9dddef2c59c23d250702323539a7fbdd870620db38c7e7d7ec87c1eb + languageName: node + linkType: hard + +"glob-parent@npm:^3.1.0": + version: 3.1.0 + resolution: "glob-parent@npm:3.1.0" + dependencies: + is-glob: ^3.1.0 + path-dirname: ^1.0.0 + checksum: 653d559237e89a11b9934bef3f392ec42335602034c928590544d383ff5ef449f7b12f3cfa539708e74bc0a6c28ab1fe51d663cc07463cdf899ba92afd85a855 languageName: node linkType: hard @@ -12101,55 +10295,22 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^6.0.2": - version: 6.0.2 - resolution: "glob-parent@npm:6.0.2" - dependencies: - is-glob: ^4.0.3 - checksum: c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8 - languageName: node - linkType: hard - -"glob-to-regexp@npm:^0.4.1": - version: 0.4.1 - resolution: "glob-to-regexp@npm:0.4.1" - checksum: e795f4e8f06d2a15e86f76e4d92751cf8bbfcf0157cea5c2f0f35678a8195a750b34096b1256e436f0cebc1883b5ff0888c47348443e69546a5a87f9e1eb1167 - languageName: node - linkType: hard - "glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.4.5 - resolution: "glob@npm:10.4.5" + version: 10.3.12 + resolution: "glob@npm:10.3.12" 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 - checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a - languageName: node - linkType: hard - -"glob@npm:^11.0.0": - version: 11.0.3 - resolution: "glob@npm:11.0.3" - dependencies: - foreground-child: ^3.3.1 - jackspeak: ^4.1.1 - minimatch: ^10.0.3 - minipass: ^7.1.2 - package-json-from-dist: ^1.0.0 - path-scurry: ^2.0.0 + jackspeak: ^2.3.6 + minimatch: ^9.0.1 + minipass: ^7.0.4 + path-scurry: ^1.10.2 bin: glob: dist/esm/bin.mjs - checksum: 65ddc1e3c969e87999880580048763cc8b5bdd375930dd43b8100a5ba481d2e2563e4553de42875790800c602522a98aa8d3ed1c5bd4d27621609e6471eb371d + checksum: 2b0949d6363021aaa561b108ac317bf5a97271b8a5d7a5fac1a176e40e8068ecdcccc992f8a7e958593d501103ac06d673de92adc1efcbdab45edefe35f8d7c6 languageName: node linkType: hard -"glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0": +"glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -12163,7 +10324,7 @@ __metadata: languageName: node linkType: hard -"global-modules@npm:^2.0.0": +"global-modules@npm:2.0.0": version: 2.0.0 resolution: "global-modules@npm:2.0.0" dependencies: @@ -12183,7 +10344,14 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0, globals@npm:^13.6.0, globals@npm:^13.9.0": +"globals@npm:^11.1.0": + version: 11.12.0 + resolution: "globals@npm:11.12.0" + checksum: 67051a45eca3db904aee189dfc7cd53c20c7d881679c93f6146ddd4c9f4ab2268e68a919df740d39c71f4445d2b38ee360fc234428baea1dbdfe68bbcb46979e + languageName: node + linkType: hard + +"globals@npm:^13.6.0, globals@npm:^13.9.0": version: 13.24.0 resolution: "globals@npm:13.24.0" dependencies: @@ -12192,24 +10360,30 @@ __metadata: languageName: node linkType: hard -"globals@npm:^15.15.0": - version: 15.15.0 - resolution: "globals@npm:15.15.0" - checksum: a2a92199a112db00562a2f85eeef2a7e3943e171f7f7d9b17dfa9231e35fd612588f3c199d1509ab1757273467e413b08c80424cf6e399e96acdaf93deb3ee88 +"globalthis@npm:^1.0.3": + version: 1.0.3 + resolution: "globalthis@npm:1.0.3" + dependencies: + define-properties: ^1.1.3 + checksum: fbd7d760dc464c886d0196166d92e5ffb4c84d0730846d6621a39fbbc068aeeb9c8d1421ad330e94b7bca4bb4ea092f5f21f3d36077812af5d098b4dc006c998 languageName: node linkType: hard -"globalthis@npm:^1.0.4": - version: 1.0.4 - resolution: "globalthis@npm:1.0.4" +"globby@npm:11.0.1": + version: 11.0.1 + resolution: "globby@npm:11.0.1" dependencies: - define-properties: ^1.2.1 - gopd: ^1.0.1 - checksum: 39ad667ad9f01476474633a1834a70842041f70a55571e8dcef5fb957980a92da5022db5430fca8aecc5d47704ae30618c0bc877a579c70710c904e9ef06108a + array-union: ^2.1.0 + dir-glob: ^3.0.1 + fast-glob: ^3.1.1 + ignore: ^5.1.4 + merge2: ^1.3.0 + slash: ^3.0.0 + checksum: b0b26e580666ef8caf0b0facd585c1da46eb971207ee9f8c7b690c1372d77602dd072f047f26c3ae1c293807fdf8fb6890d9291d37bc6d2602b1f07386f983e5 languageName: node linkType: hard -"globby@npm:^11.0.4, globby@npm:^11.1.0": +"globby@npm:^11.0.3": version: 11.1.0 resolution: "globby@npm:11.1.0" dependencies: @@ -12223,6 +10397,19 @@ __metadata: languageName: node linkType: hard +"globby@npm:^6.1.0": + version: 6.1.0 + resolution: "globby@npm:6.1.0" + dependencies: + array-union: ^1.0.1 + glob: ^7.0.3 + object-assign: ^4.0.1 + pify: ^2.0.0 + pinkie-promise: ^2.0.0 + checksum: 18109d6b9d55643d2b98b59c3cfae7073ccfe39829632f353d516cc124d836c2ddebe48a23f04af63d66a621b6d86dd4cbd7e6af906f2458a7fe510ffc4bd424 + languageName: node + linkType: hard + "google-auth-library@npm:^8.0.2, google-auth-library@npm:^8.1.1": version: 8.9.0 resolution: "google-auth-library@npm:8.9.0" @@ -12240,27 +10427,6 @@ __metadata: languageName: node linkType: hard -"google-auth-library@npm:^9.15.0": - version: 9.15.1 - resolution: "google-auth-library@npm:9.15.1" - dependencies: - base64-js: ^1.3.0 - ecdsa-sig-formatter: ^1.0.11 - gaxios: ^6.1.1 - gcp-metadata: ^6.1.0 - gtoken: ^7.0.0 - jws: ^4.0.0 - checksum: 1c7660b7d21504a58b6b7780b0ca56f07a4d2b68d2ca14e5c4beaedd45cc4898baa8df1cfaf4dac15413a8db3cecc00e84662d8a327f9b9488ff2df7d8d23c84 - languageName: node - linkType: hard - -"google-logging-utils@npm:^0.0.2": - version: 0.0.2 - resolution: "google-logging-utils@npm:0.0.2" - checksum: 270de74cde8abe0a6639b4bebbb6db2c7d8a495cf14b23779450d3d010e759f3ffcb7eb200b1bcb05da1897fa63f3e336df2274f02fc69d3bb388019fa2b3134 - languageName: node - linkType: hard - "google-p12-pem@npm:^4.0.0": version: 4.0.1 resolution: "google-p12-pem@npm:4.0.1" @@ -12296,31 +10462,33 @@ __metadata: languageName: node linkType: hard -"gopd@npm:^1.0.1, gopd@npm:^1.2.0": - version: 1.2.0 - resolution: "gopd@npm:1.2.0" - checksum: cc6d8e655e360955bdccaca51a12a474268f95bb793fc3e1f2bdadb075f28bfd1fd988dab872daf77a61d78cbaf13744bc8727a17cfb1d150d76047d805375f3 +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: ^1.1.3 + checksum: a5ccfb8806e0917a94e0b3de2af2ea4979c1da920bc381667c260e00e7cafdbe844e2cb9c5bcfef4e5412e8bf73bab837285bc35c7ba73aaaf0134d4583393a6 languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": +"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 languageName: node linkType: hard -"graphemer@npm:^1.4.0": - version: 1.4.0 - resolution: "graphemer@npm:1.4.0" - checksum: bab8f0be9b568857c7bec9fda95a89f87b783546d02951c40c33f84d05bb7da3fd10f863a9beb901463669b6583173a8c8cc6d6b306ea2b9b9d5d3d943c3a673 +"graphql@npm:^16.3.0": + version: 16.8.1 + resolution: "graphql@npm:16.8.1" + checksum: 8d304b7b6f708c8c5cc164b06e92467dfe36aff6d4f2cf31dd19c4c2905a0e7b89edac4b7e225871131fd24e21460836b369de0c06532644d15b461d55b1ccc0 languageName: node linkType: hard -"graphql@npm:^16.8.1": - version: 16.11.0 - resolution: "graphql@npm:16.11.0" - checksum: 65bc206edbe980f2759a8e4cf324873f75a66ab48263961472716e50127ae446739be20f926bb7f036a8d199bd4de072f684fd147c285bd6ba965d98cebb6200 +"growly@npm:^1.3.0": + version: 1.3.0 + resolution: "growly@npm:1.3.0" + checksum: 53cdecd4c16d7d9154a9061a9ccb87d602e957502ca69b529d7d1b2436c2c0b700ec544fc6b3e4cd115d59b81e62e44ce86bd0521403b579d3a2a97d7ce72a44 languageName: node linkType: hard @@ -12335,22 +10503,13 @@ __metadata: languageName: node linkType: hard -"gtoken@npm:^7.0.0": - version: 7.1.0 - resolution: "gtoken@npm:7.1.0" - dependencies: - gaxios: ^6.0.0 - jws: ^4.0.0 - checksum: 1f338dced78f9d895ea03cd507454eb5a7b77e841ecd1d45e44483b08c1e64d16a9b0342358d37586d87462ffc2d5f5bff5dfe77ed8d4f0aafc3b5b0347d5d16 - languageName: node - linkType: hard - -"gzip-size@npm:^6.0.0": - version: 6.0.0 - resolution: "gzip-size@npm:6.0.0" +"gzip-size@npm:5.1.1": + version: 5.1.1 + resolution: "gzip-size@npm:5.1.1" dependencies: - duplexer: ^0.1.2 - checksum: 2df97f359696ad154fc171dcb55bc883fe6e833bca7a65e457b9358f3cb6312405ed70a8da24a77c1baac0639906cd52358dc0ce2ec1a937eaa631b934c94194 + duplexer: ^0.1.1 + pify: ^4.0.1 + checksum: 6451ba2210877368f6d9ee9b4dc0d14501671472801323bf81fbd38bdeb8525f40a78be45a59d0182895d51e6b60c6314b7d02bd6ed40e7225a01e8d038aac1b languageName: node linkType: hard @@ -12368,10 +10527,26 @@ __metadata: languageName: node linkType: hard -"has-bigints@npm:^1.0.2": - version: 1.1.0 - resolution: "has-bigints@npm:1.1.0" - checksum: 79730518ae02c77e4af6a1d1a0b6a2c3e1509785532771f9baf0241e83e36329542c3d7a0e723df8cbc85f74eff4f177828a2265a01ba576adbdc2d40d86538b +"has-ansi@npm:^2.0.0": + version: 2.0.0 + resolution: "has-ansi@npm:2.0.0" + dependencies: + ansi-regex: ^2.0.0 + checksum: 1b51daa0214440db171ff359d0a2d17bc20061164c57e76234f614c91dbd2a79ddd68dfc8ee73629366f7be45a6df5f2ea9de83f52e1ca24433f2cc78c35d8ec + languageName: node + linkType: hard + +"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": + version: 1.0.2 + resolution: "has-bigints@npm:1.0.2" + checksum: 390e31e7be7e5c6fe68b81babb73dfc35d413604d7ee5f56da101417027a4b4ce6a27e46eff97ad040c835b5d228676eae99a9b5c3bc0e23c8e81a49241ff45b + languageName: node + linkType: hard + +"has-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "has-flag@npm:1.0.0" + checksum: ce3f8ae978e70f16e4bbe17d3f0f6d6c0a3dd3b62a23f97c91d0fda9ed8e305e13baf95cc5bee4463b9f25ac9f5255de113165c5fb285e01b8065b2ac079b301 languageName: node linkType: hard @@ -12398,23 +10573,21 @@ __metadata: languageName: node linkType: hard -"has-proto@npm:^1.2.0": - version: 1.2.0 - resolution: "has-proto@npm:1.2.0" - dependencies: - dunder-proto: ^1.0.0 - checksum: f55010cb94caa56308041d77967c72a02ffd71386b23f9afa8447e58bc92d49d15c19bf75173713468e92fe3fb1680b03b115da39c21c32c74886d1d50d3e7ff +"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: fe7c3d50b33f50f3933a04413ed1f69441d21d2d2944f81036276d30635cad9279f6b43bc8f32036c31ebdfcf6e731150f46c1907ad90c669ffe9b066c3ba5c4 languageName: node linkType: hard -"has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": - version: 1.1.0 - resolution: "has-symbols@npm:1.1.0" - checksum: b2316c7302a0e8ba3aaba215f834e96c22c86f192e7310bdf689dd0e6999510c89b00fbc5742571507cebf25764d68c988b3a0da217369a73596191ac0ce694b +"has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 languageName: node linkType: hard -"has-tostringtag@npm:^1.0.2": +"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": version: 1.0.2 resolution: "has-tostringtag@npm:1.0.2" dependencies: @@ -12423,44 +10596,89 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.2": - version: 2.0.2 - resolution: "hasown@npm:2.0.2" +"has-value@npm:^0.3.1": + version: 0.3.1 + resolution: "has-value@npm:0.3.1" dependencies: - function-bind: ^1.1.2 - checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db + get-value: ^2.0.3 + has-values: ^0.1.4 + isobject: ^2.0.0 + checksum: 29e2a1e6571dad83451b769c7ce032fce6009f65bccace07c2962d3ad4d5530b6743d8f3229e4ecf3ea8e905d23a752c5f7089100c1f3162039fa6dc3976558f languageName: node linkType: hard -"hast-util-to-jsx-runtime@npm:^2.0.0": - version: 2.3.6 - resolution: "hast-util-to-jsx-runtime@npm:2.3.6" - dependencies: - "@types/estree": ^1.0.0 - "@types/hast": ^3.0.0 - "@types/unist": ^3.0.0 - comma-separated-tokens: ^2.0.0 - devlop: ^1.0.0 - estree-util-is-identifier-name: ^3.0.0 - hast-util-whitespace: ^3.0.0 - mdast-util-mdx-expression: ^2.0.0 - mdast-util-mdx-jsx: ^3.0.0 - mdast-util-mdxjs-esm: ^2.0.0 - property-information: ^7.0.0 - space-separated-tokens: ^2.0.0 - style-to-js: ^1.0.0 - unist-util-position: ^5.0.0 - vfile-message: ^4.0.0 - checksum: 78c25465cf010f1004b22f0bbb3bd47793f458ead3561c779ea2b9204ceb1adc9c048592b0a15025df0c683a12ebe16a8bef008c06d9c0369f51116f64b35a2d - languageName: node - linkType: hard - -"hast-util-whitespace@npm:^3.0.0": - version: 3.0.0 - resolution: "hast-util-whitespace@npm:3.0.0" +"has-value@npm:^1.0.0": + version: 1.0.0 + resolution: "has-value@npm:1.0.0" + dependencies: + get-value: ^2.0.6 + has-values: ^1.0.0 + isobject: ^3.0.0 + checksum: b9421d354e44f03d3272ac39fd49f804f19bc1e4fa3ceef7745df43d6b402053f828445c03226b21d7d934a21ac9cf4bc569396dc312f496ddff873197bbd847 + languageName: node + linkType: hard + +"has-values@npm:^0.1.4": + version: 0.1.4 + resolution: "has-values@npm:0.1.4" + checksum: ab1c4bcaf811ccd1856c11cfe90e62fca9e2b026ebe474233a3d282d8d67e3b59ed85b622c7673bac3db198cb98bd1da2b39300a2f98e453729b115350af49bc + languageName: node + linkType: hard + +"has-values@npm:^1.0.0": + version: 1.0.0 + resolution: "has-values@npm:1.0.0" + dependencies: + is-number: ^3.0.0 + kind-of: ^4.0.0 + checksum: 77e6693f732b5e4cf6c38dfe85fdcefad0fab011af74995c3e83863fabf5e3a836f406d83565816baa0bc0a523c9410db8b990fe977074d61aeb6d8f4fcffa11 + languageName: node + linkType: hard + +"has@npm:^1.0.0": + version: 1.0.4 + resolution: "has@npm:1.0.4" + checksum: 8a11ba062e0627c9578a1d08285401e39f1d071a9692ddf793199070edb5648b21c774dd733e2a181edd635bf6862731885f476f4ccf67c998d7a5ff7cef2550 + languageName: node + linkType: hard + +"hash-base@npm:^3.0.0": + version: 3.1.0 + resolution: "hash-base@npm:3.1.0" + dependencies: + inherits: ^2.0.4 + readable-stream: ^3.6.0 + safe-buffer: ^5.2.0 + checksum: 26b7e97ac3de13cb23fc3145e7e3450b0530274a9562144fc2bf5c1e2983afd0e09ed7cc3b20974ba66039fad316db463da80eb452e7373e780cbee9a0d2f2dc + languageName: node + linkType: hard + +"hash-base@npm:~3.0": + version: 3.0.4 + resolution: "hash-base@npm:3.0.4" + dependencies: + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: 878465a0dfcc33cce195c2804135352c590d6d10980adc91a9005fd377e77f2011256c2b7cfce472e3f2e92d561d1bf3228d2da06348a9017ce9a258b3b49764 + languageName: node + linkType: hard + +"hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": + version: 1.1.7 + resolution: "hash.js@npm:1.1.7" + dependencies: + inherits: ^2.0.3 + minimalistic-assert: ^1.0.1 + checksum: e350096e659c62422b85fa508e4b3669017311aa4c49b74f19f8e1bc7f3a54a584fdfd45326d4964d6011f2b2d882e38bea775a96046f2a61b7779a979629d8f + languageName: node + linkType: hard + +"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" dependencies: - "@types/hast": ^3.0.0 - checksum: 41d93ccce218ba935dc3c12acdf586193c35069489c8c8f50c2aa824c00dec94a3c78b03d1db40fa75381942a189161922e4b7bca700b3a2cc779634c351a1e4 + function-bind: ^1.1.2 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db languageName: node linkType: hard @@ -12483,10 +10701,31 @@ __metadata: languageName: node linkType: hard -"headers-polyfill@npm:^4.0.2": - version: 4.0.3 - resolution: "headers-polyfill@npm:4.0.3" - checksum: 382efe88575362f9f343f813a9df5131cec23129121111c55fb1151fb6dc87d963a820412fc95ff9cbc3016149de0714211dfa5d5914020ed92a69f014f66600 +"headers-polyfill@npm:3.2.5": + version: 3.2.5 + resolution: "headers-polyfill@npm:3.2.5" + checksum: a3c4bdd661584fd39e40c0f91412abc514616edfbd20d29a75567e591f90ef5c445c8e209b7f3c2b2375d27e95e4690f33417368a168d4832484a93861ab6a3c + languageName: node + linkType: hard + +"headers-polyfill@npm:^3.0.4": + version: 3.3.0 + resolution: "headers-polyfill@npm:3.3.0" + checksum: 6dd010544b7c1a878aa612b49d9e27d273aa9e8a462e1ae05ca212fafa68e6b7cbdec4765f4e443b2fe70d2818f5d9814eab53fa2ba793bf1e5a6b6eff760474 + languageName: node + linkType: hard + +"hex-color-regex@npm:^1.1.0": + version: 1.1.0 + resolution: "hex-color-regex@npm:1.1.0" + checksum: 44fa1b7a26d745012f3bfeeab8015f60514f72d2fcf10dce33068352456b8d71a2e6bc5a17f933ab470da2c5ab1e3e04b05caf3fefe3c1cabd7e02e516fc8784 + languageName: node + linkType: hard + +"hexoid@npm:^1.0.0": + version: 1.0.0 + resolution: "hexoid@npm:1.0.0" + checksum: 27a148ca76a2358287f40445870116baaff4a0ed0acc99900bf167f0f708ffd82e044ff55e9949c71963852b580fc024146d3ac6d5d76b508b78d927fa48ae2d languageName: node linkType: hard @@ -12504,6 +10743,17 @@ __metadata: languageName: node linkType: hard +"hmac-drbg@npm:^1.0.1": + version: 1.0.1 + resolution: "hmac-drbg@npm:1.0.1" + dependencies: + hash.js: ^1.0.3 + minimalistic-assert: ^1.0.0 + minimalistic-crypto-utils: ^1.0.1 + checksum: bd30b6a68d7f22d63f10e1888aee497d7c2c5c0bb469e66bbdac99f143904d1dfe95f8131f95b3e86c86dd239963c9d972fcbe147e7cffa00e55d18585c43fe0 + languageName: node + linkType: hard + "hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.1": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" @@ -12520,6 +10770,13 @@ __metadata: languageName: node linkType: hard +"hosted-git-info@npm:^2.1.4": + version: 2.8.9 + resolution: "hosted-git-info@npm:2.8.9" + checksum: c955394bdab888a1e9bb10eb33029e0f7ce5a2ac7b3f158099dc8c486c99e73809dca609f5694b223920ca2174db33d32b12f9a2a47141dc59607c29da5a62dd + languageName: node + linkType: hard + "hpack.js@npm:^2.1.6": version: 2.1.6 resolution: "hpack.js@npm:2.1.6" @@ -12532,6 +10789,20 @@ __metadata: languageName: node linkType: hard +"hsl-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "hsl-regex@npm:1.0.0" + checksum: de9ee1bf39de1b83cc3fa0fa1cc337f29f14911e79411d66347365c54fab6b109eea2dd741eaa02486e24de31627ad7bf4453f22224fb55a2fe2b58166fa63b8 + languageName: node + linkType: hard + +"hsla-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "hsla-regex@npm:1.0.0" + checksum: 9aa6eb9ff6c102d2395435aa5d1d91eae20043c4b1497c543d8db501c05f3edacd9a07fb34a987059d7902dba415af4cb4e610f751859ae8e7525df4ffcd085f + languageName: node + linkType: hard + "html-encoding-sniffer@npm:^2.0.1": version: 2.0.1 resolution: "html-encoding-sniffer@npm:2.0.1" @@ -12541,10 +10812,10 @@ __metadata: languageName: node linkType: hard -"html-entities@npm:^2.1.0, html-entities@npm:^2.3.2": - version: 2.6.0 - resolution: "html-entities@npm:2.6.0" - checksum: 720643f7954019c80911430a7df2728524c07080edfe812610bfc5d8191cd772b470bee0ee151bf7426679314ae53cf28a1c845d702123714e625a8565b26567 +"html-entities@npm:^1.2.1, html-entities@npm:^1.3.1": + version: 1.4.0 + resolution: "html-entities@npm:1.4.0" + checksum: 4b73ffb9eead200f99146e4fbe70acb0af2fea136901a131fc3a782e9ef876a7cbb07dec303ca1f8804232b812249dbf3643a270c9c524852065d9224a8dcdd0 languageName: node linkType: hard @@ -12555,48 +10826,39 @@ __metadata: languageName: node linkType: hard -"html-minifier-terser@npm:^6.0.2": - version: 6.1.0 - resolution: "html-minifier-terser@npm:6.1.0" +"html-minifier-terser@npm:^5.0.1": + version: 5.1.1 + resolution: "html-minifier-terser@npm:5.1.1" dependencies: - camel-case: ^4.1.2 - clean-css: ^5.2.2 - commander: ^8.3.0 + camel-case: ^4.1.1 + clean-css: ^4.2.3 + commander: ^4.1.1 he: ^1.2.0 - param-case: ^3.0.4 + param-case: ^3.0.3 relateurl: ^0.2.7 - terser: ^5.10.0 + terser: ^4.6.3 bin: html-minifier-terser: cli.js - checksum: ac52c14006476f773204c198b64838477859dc2879490040efab8979c0207424da55d59df7348153f412efa45a0840a1ca3c757bf14767d23a15e3e389d37a93 - languageName: node - linkType: hard - -"html-url-attributes@npm:^3.0.0": - version: 3.0.1 - resolution: "html-url-attributes@npm:3.0.1" - checksum: 1ecbf9cae0c438d2802386710177b7bbf7e30cc61327e9f125eb32fca7302cd1e3ab45c441859cb1e7646109be322fc1163592ad4dfde9b14d09416d101a6573 + checksum: 75ff3ff886631b9ecb3035acb8e7dd98c599bb4d4618ad6f7e487ee9752987dddcf6848dc3c1ab1d7fc1ad4484337c2ce39c19eac17b0342b4b15e4294c8a904 languageName: node linkType: hard -"html-webpack-plugin@npm:^5.5.0": - version: 5.6.4 - resolution: "html-webpack-plugin@npm:5.6.4" - dependencies: - "@types/html-minifier-terser": ^6.0.0 - html-minifier-terser: ^6.0.2 - lodash: ^4.17.21 - pretty-error: ^4.0.0 - tapable: ^2.0.0 +"html-webpack-plugin@npm:4.5.0": + version: 4.5.0 + resolution: "html-webpack-plugin@npm:4.5.0" + dependencies: + "@types/html-minifier-terser": ^5.0.0 + "@types/tapable": ^1.0.5 + "@types/webpack": ^4.41.8 + html-minifier-terser: ^5.0.1 + loader-utils: ^1.2.3 + lodash: ^4.17.15 + pretty-error: ^2.1.1 + tapable: ^1.1.3 + util.promisify: 1.0.0 peerDependencies: - "@rspack/core": 0.x || 1.x - webpack: ^5.20.0 - peerDependenciesMeta: - "@rspack/core": - optional: true - webpack: - optional: true - checksum: b486d99ce820d563dda215f8b6bbeb78127a738b88b419c95d577165e10dd29125e151010b5745ce933e8055f2445c2f9ad1c93024ad3b752db9ac613e84cfac + webpack: ^4.0.0 || ^5.0.0 + checksum: d197db16a160ab9136a544e297c3c75d34b769d3cee12a82b9e7af7ee38ff07f4a27f2235581a9624f03996cd24997613df807341799140b4427c12bc4f496f9 languageName: node linkType: hard @@ -12613,9 +10875,9 @@ __metadata: linkType: hard "http-cache-semantics@npm:^4.1.1": - version: 4.2.0 - resolution: "http-cache-semantics@npm:4.2.0" - checksum: 7a7246ddfce629f96832791176fd643589d954e6f3b49548dadb4290451961237fab8fcea41cd2008fe819d95b41c1e8b97f47d088afc0a1c81705287b4ddbcc + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 83ac0bc60b17a3a36f9953e7be55e5c8f41acc61b22583060e8dedc9dd5e3607c823a88d0926f9150e571f90946835c7fe150732801010845c72cd8bbff1a236 languageName: node linkType: hard @@ -12626,7 +10888,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:2.0.0, http-errors@npm:^2.0.0": +"http-errors@npm:2.0.0": version: 2.0.0 resolution: "http-errors@npm:2.0.0" dependencies: @@ -12652,9 +10914,9 @@ __metadata: linkType: hard "http-parser-js@npm:>=0.5.1": - version: 0.5.10 - resolution: "http-parser-js@npm:0.5.10" - checksum: 1038177c5f114860345ce7c19223d2cdd9a103265bd897bab13343c9eff4deef60f7956a674485f1234ffc9b19fb4b97f0c20a5848cfc9ccbf5d3c438d89ae89 + version: 0.5.8 + resolution: "http-parser-js@npm:0.5.8" + checksum: 6bbdf2429858e8cf13c62375b0bfb6dc3955ca0f32e58237488bc86cd2378f31d31785fd3ac4ce93f1c74e0189cf8823c91f5cb061696214fd368d2452dc871d languageName: node linkType: hard @@ -12679,25 +10941,19 @@ __metadata: languageName: node linkType: hard -"http-proxy-middleware@npm:^2.0.3": - version: 2.0.9 - resolution: "http-proxy-middleware@npm:2.0.9" +"http-proxy-middleware@npm:0.19.1": + version: 0.19.1 + resolution: "http-proxy-middleware@npm:0.19.1" 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 - peerDependencies: - "@types/express": ^4.17.13 - peerDependenciesMeta: - "@types/express": - optional: true - checksum: 0ea88609b9c13fa03b89f8e6b85bd5c537027ec6990005dd81a7fbb3e73fcf8d6a6e3db2b57b1c6cddbcda80965704584dc6291d0e721b2700198c4e59ee0d0b + http-proxy: ^1.17.0 + is-glob: ^4.0.0 + lodash: ^4.17.11 + micromatch: ^3.1.10 + checksum: 64df0438417a613bb22b3689d9652a1b7a56f10b145a463f95f4e8a9b9a351f2c63bc5fd3a9cd710baec224897733b6f299cb7f974ea82769b2a4f1e074764ac languageName: node linkType: hard -"http-proxy@npm:^1.18.1": +"http-proxy@npm:^1.17.0": version: 1.18.1 resolution: "http-proxy@npm:1.18.1" dependencies: @@ -12708,6 +10964,13 @@ __metadata: languageName: node linkType: hard +"https-browserify@npm:^1.0.0": + version: 1.0.0 + resolution: "https-browserify@npm:1.0.0" + checksum: 09b35353e42069fde2435760d13f8a3fb7dd9105e358270e2e225b8a94f811b461edd17cb57594e5f36ec1218f121c160ddceeec6e8be2d55e01dcbbbed8cbae + languageName: node + linkType: hard + "https-proxy-agent@npm:^5.0.0": version: 5.0.1 resolution: "https-proxy-agent@npm:5.0.1" @@ -12719,23 +10982,23 @@ __metadata: linkType: hard "https-proxy-agent@npm:^7.0.1": - version: 7.0.6 - resolution: "https-proxy-agent@npm:7.0.6" + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" dependencies: - agent-base: ^7.1.2 + agent-base: ^7.0.2 debug: 4 - checksum: b882377a120aa0544846172e5db021fa8afbf83fea2a897d397bd2ddd8095ab268c24bc462f40a15f2a8c600bf4aa05ce52927f70038d4014e68aefecfa94e8d + checksum: daaab857a967a2519ddc724f91edbbd388d766ff141b9025b629f92b9408fc83cee8a27e11a907aede392938e9c398e240d643e178408a59e4073539cde8cfe9 languageName: node linkType: hard -"human-signals@npm:^2.1.0": - version: 2.1.0 - resolution: "human-signals@npm:2.1.0" - checksum: b87fd89fce72391625271454e70f67fe405277415b48bcc0117ca73d31fa23a4241787afdc8d67f5a116cf37258c052f59ea82daffa72364d61351423848e3b8 +"human-signals@npm:^1.1.1": + version: 1.1.1 + resolution: "human-signals@npm:1.1.1" + checksum: d587647c9e8ec24e02821b6be7de5a0fc37f591f6c4e319b3054b43fd4c35a70a94c46fc74d8c1a43c47fde157d23acd7421f375e1c1365b09a16835b8300205 languageName: node linkType: hard -"iconv-lite@npm:0.4.24": +"iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" dependencies: @@ -12744,16 +11007,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.7.0": - version: 0.7.0 - resolution: "iconv-lite@npm:0.7.0" - dependencies: - safer-buffer: ">= 2.1.2 < 3.0.0" - checksum: f362a8befb95e37f29be1d1290c17e0c9d0d4ad4fa62fcfd813cc9c937ab89401abed9a011f83e10651a267abb2aa231ec7da91d843570bec873bd98489b5bf8 - languageName: node - linkType: hard - -"iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": +"iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -12762,23 +11016,23 @@ __metadata: languageName: node linkType: hard -"icss-utils@npm:^5.0.0, icss-utils@npm:^5.1.0": - version: 5.1.0 - resolution: "icss-utils@npm:5.1.0" - peerDependencies: - postcss: ^8.1.0 - checksum: 5c324d283552b1269cfc13a503aaaa172a280f914e5b81544f3803bc6f06a3b585fb79f66f7c771a2c052db7982c18bf92d001e3b47282e3abbbb4c4cc488d68 +"icss-replace-symbols@npm:1.1.0, icss-replace-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "icss-replace-symbols@npm:1.1.0" + checksum: 24575b2c2f7e762bfc6f4beee31be9ba98a01cad521b5aa9954090a5de2b5e1bf67814c17e22f9e51b7d798238db8215a173d6c2b4726ce634ce06b68ece8045 languageName: node linkType: hard -"idb@npm:^7.0.1": - version: 7.1.1 - resolution: "idb@npm:7.1.1" - checksum: 1973c28d53c784b177bdef9f527ec89ec239ec7cf5fcbd987dae75a16c03f5b7dfcc8c6d3285716fd0309dd57739805390bd9f98ce23b1b7d8849a3b52de8d56 +"icss-utils@npm:^4.0.0, icss-utils@npm:^4.1.1": + version: 4.1.1 + resolution: "icss-utils@npm:4.1.1" + dependencies: + postcss: ^7.0.14 + checksum: a4ca2c6b82cb3eb879d635bd4028d74bca174edc49ee48ef5f01988489747d340a389d5a0ac6f6887a5c24ab8fc4386c781daab32a7ade5344a2edff66207635 languageName: node linkType: hard -"identity-obj-proxy@npm:^3.0.0": +"identity-obj-proxy@npm:3.0.0": version: 3.0.0 resolution: "identity-obj-proxy@npm:3.0.0" dependencies: @@ -12787,13 +11041,20 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.1.13": +"ieee754@npm:^1.1.13, ieee754@npm:^1.1.4": version: 1.2.1 resolution: "ieee754@npm:1.2.1" checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e languageName: node linkType: hard +"iferr@npm:^0.1.5": + version: 0.1.5 + resolution: "iferr@npm:0.1.5" + checksum: a18d19b6ad06a2d5412c0d37f6364869393ef6d1688d59d00082c1f35c92399094c031798340612458cd832f4f2e8b13bc9615934a7d8b0c53061307a3816aa1 + languageName: node + linkType: hard + "ignore-by-default@npm:^1.0.1": version: 1.0.1 resolution: "ignore-by-default@npm:1.0.1" @@ -12808,46 +11069,86 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.2.0, ignore@npm:^5.3.1": - version: 5.3.2 - resolution: "ignore@npm:5.3.2" - checksum: 2acfd32a573260ea522ea0bfeff880af426d68f6831f973129e2ba7363f422923cf53aab62f8369cbf4667c7b25b6f8a3761b34ecdb284ea18e87a5262a865be +"ignore@npm:^5.1.4, ignore@npm:^5.1.8, ignore@npm:^5.2.0": + version: 5.3.1 + resolution: "ignore@npm:5.3.1" + checksum: 71d7bb4c1dbe020f915fd881108cbe85a0db3d636a0ea3ba911393c53946711d13a9b1143c7e70db06d571a5822c0a324a6bcde5c9904e7ca5047f01f1bf8cd3 languageName: node linkType: hard -"immer@npm:^9.0.7": - version: 9.0.21 - resolution: "immer@npm:9.0.21" - checksum: 70e3c274165995352f6936695f0ef4723c52c92c92dd0e9afdfe008175af39fa28e76aafb3a2ca9d57d1fb8f796efc4dd1e1cc36f18d33fa5b74f3dfb0375432 +"immer@npm:8.0.1": + version: 8.0.1 + resolution: "immer@npm:8.0.1" + checksum: 63d875c04882b862481a0a692816e5982975a47a57619698bc1bb52963ad3b624911991708b2b81a7af6fdac15083d408e43932d83a6a61216e5a4503efd4095 languageName: node linkType: hard -"immutable@npm:^5.0.2": - version: 5.1.3 - resolution: "immutable@npm:5.1.3" - checksum: 63a1df5f68bbcaa7b1cb17aeaa8bc327734ad7b6936afe33b157fbdb480542c95fbab2de800b4969b5d45d51f2974aa916c78fa5c0d3a48810604268e72824cc +"immutable@npm:^4.0.0": + version: 4.3.5 + resolution: "immutable@npm:4.3.5" + checksum: 0e25dd5c314421faede9e1122ab26cdb638cc3edc8678c4a75dee104279b12621a30c80a480fae7f68bc7e81672f1e672e454dc0fdc7e6cf0af10809348387b8 languageName: node linkType: hard -"import-fresh@npm:^3.0.0, import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1": - version: 3.3.1 - resolution: "import-fresh@npm:3.3.1" +"import-cwd@npm:^2.0.0": + version: 2.1.0 + resolution: "import-cwd@npm:2.1.0" + dependencies: + import-from: ^2.1.0 + checksum: b8786fa3578f3df55370352bf61f99c2d8e6ee9b5741a07503d5a73d99281d141330a8faf87078e67527be4558f758356791ee5efb4b0112ac5eaed0f07de544 + languageName: node + linkType: hard + +"import-fresh@npm:^2.0.0": + version: 2.0.0 + resolution: "import-fresh@npm:2.0.0" + dependencies: + caller-path: ^2.0.0 + resolve-from: ^3.0.0 + checksum: 610255f9753cc6775df00be08e9f43691aa39f7703e3636c45afe22346b8b545e600ccfe100c554607546fc8e861fa149a0d1da078c8adedeea30fff326eef79 + languageName: node + linkType: hard + +"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": + version: 3.3.0 + resolution: "import-fresh@npm:3.3.0" dependencies: parent-module: ^1.0.0 resolve-from: ^4.0.0 - checksum: a06b19461b4879cc654d46f8a6244eb55eb053437afd4cbb6613cad6be203811849ed3e4ea038783092879487299fda24af932b86bdfff67c9055ba3612b8c87 + checksum: 2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa + languageName: node + linkType: hard + +"import-from@npm:^2.1.0": + version: 2.1.0 + resolution: "import-from@npm:2.1.0" + dependencies: + resolve-from: ^3.0.0 + checksum: 91f6f89f46a07227920ef819181bb52eb93023ccc0bdf00224fdfb326f8f753e279ad06819f39a02bb88c9d3a4606adc85b0cc995285e5d65feeb59f1421a1d4 + languageName: node + linkType: hard + +"import-local@npm:^2.0.0": + version: 2.0.0 + resolution: "import-local@npm:2.0.0" + dependencies: + pkg-dir: ^3.0.0 + resolve-cwd: ^2.0.0 + bin: + import-local-fixture: fixtures/cli.js + checksum: b8469252483624379fd65d53c82f3658b32a1136f7168bfeea961a4ea7ca10a45786ea2b02e0006408f9cd22d2f33305a6f17a64e4d5a03274a50942c5e7c949 languageName: node linkType: hard "import-local@npm:^3.0.2": - version: 3.2.0 - resolution: "import-local@npm:3.2.0" + version: 3.1.0 + resolution: "import-local@npm:3.1.0" dependencies: pkg-dir: ^4.2.0 resolve-cwd: ^3.0.0 bin: import-local-fixture: fixtures/cli.js - checksum: 0b0b0b412b2521739fbb85eeed834a3c34de9bc67e670b3d0b86248fc460d990a7b116ad056c084b87a693ef73d1f17268d6a5be626bb43c998a8b1c8a230004 + checksum: bfcdb63b5e3c0e245e347f3107564035b128a414c4da1172a20dc67db2504e05ede4ac2eee1252359f78b0bfd7b19ef180aec427c2fce6493ae782d73a04cddd languageName: node linkType: hard @@ -12865,6 +11166,20 @@ __metadata: languageName: node linkType: hard +"indexes-of@npm:^1.0.1": + version: 1.0.1 + resolution: "indexes-of@npm:1.0.1" + checksum: 4f9799b1739a62f3e02d09f6f4162cf9673025282af7fa36e790146e7f4e216dad3e776a25b08536c093209c9fcb5ea7bd04b082d42686a45f58ff401d6da32e + languageName: node + linkType: hard + +"infer-owner@npm:^1.0.3, infer-owner@npm:^1.0.4": + version: 1.0.4 + resolution: "infer-owner@npm:1.0.4" + checksum: 181e732764e4a0611576466b4b87dac338972b839920b2a8cde43642e4ed6bd54dc1fb0b40874728f2a2df9a1b097b8ff83b56d5f8f8e3927f837fdcb47d8a89 + languageName: node + linkType: hard + "inflight@npm:^1.0.4": version: 1.0.6 resolution: "inflight@npm:1.0.6" @@ -12875,7 +11190,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -12889,84 +11204,152 @@ __metadata: languageName: node linkType: hard -"ini@npm:^1.3.5, ini@npm:~1.3.0": +"ini@npm:^1.3.5": version: 1.3.8 resolution: "ini@npm:1.3.8" checksum: dfd98b0ca3a4fc1e323e38a6c8eb8936e31a97a918d3b377649ea15bdb15d481207a0dda1021efbd86b464cae29a0d33c1d7dcaf6c5672bee17fa849bc50a1b3 languageName: node linkType: hard -"inline-style-parser@npm:0.2.4": - version: 0.2.4 - resolution: "inline-style-parser@npm:0.2.4" - checksum: 5df20a21dd8d67104faaae29774bb50dc9690c75bc5c45dac107559670a5530104ead72c4cf54f390026e617e7014c65b3d68fb0bb573a37c4d1f94e9c36e1ca +"inline-style-parser@npm:0.1.1": + version: 0.1.1 + resolution: "inline-style-parser@npm:0.1.1" + checksum: 5d545056a3e1f2bf864c928a886a0e1656a3517127d36917b973de581bd54adc91b4bf1febcb0da054f204b4934763f1a4e09308b4d55002327cf1d48ac5d966 languageName: node linkType: hard -"internal-slot@npm:^1.1.0": - version: 1.1.0 - resolution: "internal-slot@npm:1.1.0" +"inquirer@npm:^8.2.0": + version: 8.2.6 + resolution: "inquirer@npm:8.2.6" + dependencies: + ansi-escapes: ^4.2.1 + chalk: ^4.1.1 + cli-cursor: ^3.1.0 + cli-width: ^3.0.0 + external-editor: ^3.0.3 + figures: ^3.0.0 + lodash: ^4.17.21 + mute-stream: 0.0.8 + ora: ^5.4.1 + run-async: ^2.4.0 + rxjs: ^7.5.5 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + through: ^2.3.6 + wrap-ansi: ^6.0.1 + checksum: 387ffb0a513559cc7414eb42c57556a60e302f820d6960e89d376d092e257a919961cd485a1b4de693dbb5c0de8bc58320bfd6247dfd827a873aa82a4215a240 + languageName: node + linkType: hard + +"internal-ip@npm:^4.3.0": + version: 4.3.0 + resolution: "internal-ip@npm:4.3.0" + dependencies: + default-gateway: ^4.2.0 + ipaddr.js: ^1.9.0 + checksum: c970433c84d9a6b46e2c9f5ab7785d3105b856d0a566891bf919241b5a884c5c1c9bf8e915aebb822a86c14b1b6867e58c1eaf5cd49eb023368083069d1a4a9a + languageName: node + linkType: hard + +"internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.7": + version: 1.0.7 + resolution: "internal-slot@npm:1.0.7" dependencies: es-errors: ^1.3.0 - hasown: ^2.0.2 - side-channel: ^1.1.0 - checksum: 8e0991c2d048cc08dab0a91f573c99f6a4215075887517ea4fa32203ce8aea60fa03f95b177977fa27eb502e5168366d0f3e02c762b799691411d49900611861 + hasown: ^2.0.0 + side-channel: ^1.0.4 + checksum: cadc5eea5d7d9bc2342e93aae9f31f04c196afebb11bde97448327049f492cd7081e18623ae71388aac9cd237b692ca3a105be9c68ac39c1dec679d7409e33eb languageName: node linkType: hard -"internmap@npm:1 - 2": - version: 2.0.3 - resolution: "internmap@npm:2.0.3" - checksum: 7ca41ec6aba8f0072fc32fa8a023450a9f44503e2d8e403583c55714b25efd6390c38a87161ec456bf42d7bc83aab62eb28f5aef34876b1ac4e60693d5e1d241 +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: 1.1.0 + sprintf-js: ^1.1.3 + checksum: aa15f12cfd0ef5e38349744e3654bae649a34c3b10c77a674a167e99925d1549486c5b14730eebce9fea26f6db9d5e42097b00aa4f9f612e68c79121c71652dc languageName: node linkType: hard -"ip-address@npm:^10.0.1": - version: 10.0.1 - resolution: "ip-address@npm:10.0.1" - checksum: 525d5391cfd31a91f80f5857e98487aeaa8474e860a6725a0b6461ac8e436c7f8c869774dece391c8f8e7486306a34a4d1c094778c4c583a3f1f2cd905e5ed50 +"ip-regex@npm:^2.1.0": + version: 2.1.0 + resolution: "ip-regex@npm:2.1.0" + checksum: 331d95052aa53ce245745ea0fc3a6a1e2e3c8d6da65fa8ea52bf73768c1b22a9ac50629d1d2b08c04e7b3ac4c21b536693c149ce2c2615ee4796030e5b3e3cba + languageName: node + linkType: hard + +"ip@npm:^1.1.0, ip@npm:^1.1.5": + version: 1.1.9 + resolution: "ip@npm:1.1.9" + checksum: b6d91fd45a856e3bd6d4f601ea0619d90f3517638f6918ebd079f959a8a6308568d8db5ef4fdf037e0d9cfdcf264f46833dfeea81ca31309cf0a7eb4b1307b84 languageName: node linkType: hard -"ipaddr.js@npm:1.9.1": +"ipaddr.js@npm:1.9.1, ipaddr.js@npm:^1.9.0": version: 1.9.1 resolution: "ipaddr.js@npm:1.9.1" checksum: f88d3825981486f5a1942414c8d77dd6674dd71c065adcfa46f578d677edcb99fda25af42675cb59db492fdf427b34a5abfcde3982da11a8fd83a500b41cfe77 languageName: node linkType: hard -"ipaddr.js@npm:^2.0.1": - version: 2.2.0 - resolution: "ipaddr.js@npm:2.2.0" - checksum: 770ba8451fd9bf78015e8edac0d5abd7a708cbf75f9429ca9147a9d2f3a2d60767cd5de2aab2b1e13ca6e4445bdeff42bf12ef6f151c07a5c6cf8a44328e2859 +"is-absolute-url@npm:^2.0.0": + version: 2.1.0 + resolution: "is-absolute-url@npm:2.1.0" + checksum: 781e8cf8a2af54b1b7a92f269244d96c66224030d91120e734ebeebbce044c167767e1389789d8aaf82f9e429cb20ae93d6d0acfe6c4b53d2bd6ebb47a236d76 languageName: node linkType: hard -"is-alphabetical@npm:^2.0.0": - version: 2.0.1 - resolution: "is-alphabetical@npm:2.0.1" - checksum: 56207db8d9de0850f0cd30f4966bf731eb82cedfe496cbc2e97e7c3bacaf66fc54a972d2d08c0d93bb679cb84976a05d24c5ad63de56fabbfc60aadae312edaa +"is-absolute-url@npm:^3.0.3": + version: 3.0.3 + resolution: "is-absolute-url@npm:3.0.3" + checksum: 5159b51d065d9ad29e16a2f78d6c0e41c43227caf90a45e659c54ea6fd50ef0595b1871ce392e84b1df7cfdcad9a8e66eec0813a029112188435abf115accb16 languageName: node linkType: hard -"is-alphanumerical@npm:^2.0.0": - version: 2.0.1 - resolution: "is-alphanumerical@npm:2.0.1" +"is-accessor-descriptor@npm:^1.0.1": + version: 1.0.1 + resolution: "is-accessor-descriptor@npm:1.0.1" + dependencies: + hasown: ^2.0.0 + checksum: 8db44c02230a5e9b9dec390a343178791f073d5d5556a400527d2fd67a72d93b226abab2bd4123305c268f5dc22831bfdbd38430441fda82ea9e0b95ddc6b267 + languageName: node + linkType: hard + +"is-alphabetical@npm:^1.0.0": + version: 1.0.4 + resolution: "is-alphabetical@npm:1.0.4" + checksum: 6508cce44fd348f06705d377b260974f4ce68c74000e7da4045f0d919e568226dc3ce9685c5a2af272195384df6930f748ce9213fc9f399b5d31b362c66312cb + languageName: node + linkType: hard + +"is-alphanumerical@npm:^1.0.0": + version: 1.0.4 + resolution: "is-alphanumerical@npm:1.0.4" + dependencies: + is-alphabetical: ^1.0.0 + is-decimal: ^1.0.0 + checksum: e2e491acc16fcf5b363f7c726f666a9538dba0a043665740feb45bba1652457a73441e7c5179c6768a638ed396db3437e9905f403644ec7c468fb41f4813d03f + languageName: node + linkType: hard + +"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1": + version: 1.1.1 + resolution: "is-arguments@npm:1.1.1" dependencies: - is-alphabetical: ^2.0.0 - is-decimal: ^2.0.0 - checksum: 87acc068008d4c9c4e9f5bd5e251041d42e7a50995c77b1499cf6ed248f971aadeddb11f239cabf09f7975ee58cac7a48ffc170b7890076d8d227b24a68663c9 + call-bind: ^1.0.2 + has-tostringtag: ^1.0.0 + checksum: 7f02700ec2171b691ef3e4d0e3e6c0ba408e8434368504bb593d0d7c891c0dbfda6d19d30808b904a6cb1929bca648c061ba438c39f296c2a8ca083229c49f27 languageName: node linkType: hard -"is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5": - version: 3.0.5 - resolution: "is-array-buffer@npm:3.0.5" +"is-array-buffer@npm:^3.0.2, is-array-buffer@npm:^3.0.4": + version: 3.0.4 + resolution: "is-array-buffer@npm:3.0.4" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.3 - get-intrinsic: ^1.2.6 - checksum: f137a2a6e77af682cdbffef1e633c140cf596f72321baf8bba0f4ef22685eb4339dde23dfe9e9ca430b5f961dee4d46577dcf12b792b68518c8449b134fb9156 + call-bind: ^1.0.2 + get-intrinsic: ^1.2.1 + checksum: e4e3e6ef0ff2239e75371d221f74bc3c26a03564a22efb39f6bb02609b598917ddeecef4e8c877df2a25888f247a98198959842a5e73236bc7f22cabdf6351a7 languageName: node linkType: hard @@ -12977,25 +11360,37 @@ __metadata: languageName: node linkType: hard +"is-arrayish@npm:^0.3.1": + version: 0.3.2 + resolution: "is-arrayish@npm:0.3.2" + checksum: 977e64f54d91c8f169b59afcd80ff19227e9f5c791fa28fa2e5bce355cbaf6c2c356711b734656e80c9dd4a854dd7efcf7894402f1031dfc5de5d620775b4d5f + languageName: node + linkType: hard + "is-async-function@npm:^2.0.0": - version: 2.1.1 - resolution: "is-async-function@npm:2.1.1" + version: 2.0.0 + resolution: "is-async-function@npm:2.0.0" dependencies: - async-function: ^1.0.0 - call-bound: ^1.0.3 - get-proto: ^1.0.1 - has-tostringtag: ^1.0.2 - safe-regex-test: ^1.1.0 - checksum: 9bece45133da26636488ca127d7686b85ad3ca18927e2850cff1937a650059e90be1c71a48623f8791646bb7a241b0cabf602a0b9252dcfa5ab273f2399000e6 + has-tostringtag: ^1.0.0 + checksum: e3471d95e6c014bf37cad8a93f2f4b6aac962178e0a5041e8903147166964fdc1c5c1d2ef87e86d77322c370ca18f2ea004fa7420581fa747bcaf7c223069dbd languageName: node linkType: hard -"is-bigint@npm:^1.1.0": - version: 1.1.0 - resolution: "is-bigint@npm:1.1.0" +"is-bigint@npm:^1.0.1": + version: 1.0.4 + resolution: "is-bigint@npm:1.0.4" dependencies: - has-bigints: ^1.0.2 - checksum: ee1544f0e664f253306786ed1dce494b8cf242ef415d6375d8545b4d8816b0f054bd9f948a8988ae2c6325d1c28260dd02978236b2f7b8fb70dfc4838a6c9fa7 + has-bigints: ^1.0.1 + checksum: c56edfe09b1154f8668e53ebe8252b6f185ee852a50f9b41e8d921cb2bed425652049fbe438723f6cb48a63ca1aa051e948e7e401e093477c99c84eba244f666 + languageName: node + linkType: hard + +"is-binary-path@npm:^1.0.0": + version: 1.0.1 + resolution: "is-binary-path@npm:1.0.1" + dependencies: + binary-extensions: ^1.0.0 + checksum: a803c99e9d898170c3b44a86fbdc0736d3d7fcbe737345433fb78e810b9fe30c982657782ad0e676644ba4693ddf05601a7423b5611423218663d6b533341ac9 languageName: node linkType: hard @@ -13008,61 +11403,133 @@ __metadata: languageName: node linkType: hard -"is-boolean-object@npm:^1.2.1": - version: 1.2.2 - resolution: "is-boolean-object@npm:1.2.2" +"is-boolean-object@npm:^1.1.0": + version: 1.1.2 + resolution: "is-boolean-object@npm:1.1.2" dependencies: - call-bound: ^1.0.3 - has-tostringtag: ^1.0.2 - checksum: 0415b181e8f1bfd5d3f8a20f8108e64d372a72131674eea9c2923f39d065b6ad08d654765553bdbffbd92c3746f1007986c34087db1bd89a31f71be8359ccdaa + call-bind: ^1.0.2 + has-tostringtag: ^1.0.0 + checksum: c03b23dbaacadc18940defb12c1c0e3aaece7553ef58b162a0f6bba0c2a7e1551b59f365b91e00d2dbac0522392d576ef322628cb1d036a0fe51eb466db67222 + languageName: node + linkType: hard + +"is-buffer@npm:^1.1.5": + version: 1.1.6 + resolution: "is-buffer@npm:1.1.6" + checksum: 4a186d995d8bbf9153b4bd9ff9fd04ae75068fe695d29025d25e592d9488911eeece84eefbd8fa41b8ddcc0711058a71d4c466dcf6f1f6e1d83830052d8ca707 languageName: node linkType: hard -"is-callable@npm:^1.2.7": +"is-buffer@npm:^2.0.0": + version: 2.0.5 + resolution: "is-buffer@npm:2.0.5" + checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42 + languageName: node + linkType: hard + +"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" checksum: 61fd57d03b0d984e2ed3720fb1c7a897827ea174bd44402878e059542ea8c4aeedee0ea0985998aa5cc2736b2fa6e271c08587addb5b3959ac52cf665173d1ac languageName: node linkType: hard -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1": - version: 2.16.1 - resolution: "is-core-module@npm:2.16.1" +"is-ci@npm:^2.0.0": + version: 2.0.0 + resolution: "is-ci@npm:2.0.0" dependencies: - hasown: ^2.0.2 - checksum: 6ec5b3c42d9cbf1ac23f164b16b8a140c3cec338bf8f884c076ca89950c7cc04c33e78f02b8cae7ff4751f3247e3174b2330f1fe4de194c7210deb8b1ea316a7 + ci-info: ^2.0.0 + bin: + is-ci: bin.js + checksum: 77b869057510f3efa439bbb36e9be429d53b3f51abd4776eeea79ab3b221337fe1753d1e50058a9e2c650d38246108beffb15ccfd443929d77748d8c0cc90144 languageName: node linkType: hard -"is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2": - version: 1.0.2 - resolution: "is-data-view@npm:1.0.2" +"is-color-stop@npm:^1.0.0": + version: 1.1.0 + resolution: "is-color-stop@npm:1.1.0" + dependencies: + css-color-names: ^0.0.4 + hex-color-regex: ^1.1.0 + hsl-regex: ^1.0.0 + hsla-regex: ^1.0.0 + rgb-regex: ^1.0.1 + rgba-regex: ^1.0.0 + checksum: 778dd52a603ab8da827925aa4200fe6733b667b216495a04110f038b925dc5ef58babe759b94ffc4e44fcf439328695770873937f59d6045f676322b97f3f92d + languageName: node + linkType: hard + +"is-core-module@npm:^2.0.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1": + version: 2.13.1 + resolution: "is-core-module@npm:2.13.1" + dependencies: + hasown: ^2.0.0 + checksum: 256559ee8a9488af90e4bad16f5583c6d59e92f0742e9e8bb4331e758521ee86b810b93bae44f390766ffbc518a0488b18d9dab7da9a5ff997d499efc9403f7c + languageName: node + linkType: hard + +"is-data-descriptor@npm:^1.0.1": + version: 1.0.1 + resolution: "is-data-descriptor@npm:1.0.1" + dependencies: + hasown: ^2.0.0 + checksum: fc6da5be5177149d554c5612cc382e9549418ed72f2d3ed5a3e6511b03dd119ae1b2258320ca94931df50b7e9ee012894eccd4ca45bbcadf0d5b27da6faeb15a + languageName: node + linkType: hard + +"is-data-view@npm:^1.0.1": + version: 1.0.1 + resolution: "is-data-view@npm:1.0.1" dependencies: - call-bound: ^1.0.2 - get-intrinsic: ^1.2.6 is-typed-array: ^1.1.13 - checksum: 31600dd19932eae7fd304567e465709ffbfa17fa236427c9c864148e1b54eb2146357fcf3aed9b686dee13c217e1bb5a649cb3b9c479e1004c0648e9febde1b2 + checksum: 4ba4562ac2b2ec005fefe48269d6bd0152785458cd253c746154ffb8a8ab506a29d0cfb3b74af87513843776a88e4981ae25c89457bf640a33748eab1a7216b5 languageName: node linkType: hard -"is-date-object@npm:^1.0.5, is-date-object@npm:^1.1.0": - version: 1.1.0 - resolution: "is-date-object@npm:1.1.0" +"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": + version: 1.0.5 + resolution: "is-date-object@npm:1.0.5" dependencies: - call-bound: ^1.0.2 - has-tostringtag: ^1.0.2 - checksum: d6c36ab9d20971d65f3fc64cef940d57a4900a2ac85fb488a46d164c2072a33da1cb51eefcc039e3e5c208acbce343d3480b84ab5ff0983f617512da2742562a + has-tostringtag: ^1.0.0 + checksum: baa9077cdf15eb7b58c79398604ca57379b2fc4cf9aa7a9b9e295278648f628c9b201400c01c5e0f7afae56507d741185730307cbe7cad3b9f90a77e5ee342fc languageName: node linkType: hard -"is-decimal@npm:^2.0.0": - version: 2.0.1 - resolution: "is-decimal@npm:2.0.1" - checksum: 97132de7acdce77caa7b797632970a2ecd649a88e715db0e4dbc00ab0708b5e7574ba5903962c860cd4894a14fd12b100c0c4ac8aed445cf6f55c6cf747a4158 +"is-decimal@npm:^1.0.0": + version: 1.0.4 + resolution: "is-decimal@npm:1.0.4" + checksum: ed483a387517856dc395c68403a10201fddcc1b63dc56513fbe2fe86ab38766120090ecdbfed89223d84ca8b1cd28b0641b93cb6597b6e8f4c097a7c24e3fb96 + languageName: node + linkType: hard + +"is-descriptor@npm:^0.1.0": + version: 0.1.7 + resolution: "is-descriptor@npm:0.1.7" + dependencies: + is-accessor-descriptor: ^1.0.1 + is-data-descriptor: ^1.0.1 + checksum: 45743109f0bb03f9fa989c34d31ece87cc15792649f147b896a7c4db2906a02fca685867619f4d312e024d7bbd53b945a47c6830d01f5e73efcc6388ac211963 languageName: node linkType: hard -"is-docker@npm:^2.0.0, is-docker@npm:^2.1.1": +"is-descriptor@npm:^1.0.0, is-descriptor@npm:^1.0.2": + version: 1.0.3 + resolution: "is-descriptor@npm:1.0.3" + dependencies: + is-accessor-descriptor: ^1.0.1 + is-data-descriptor: ^1.0.1 + checksum: 316153b2fd86ac23b0a2f28b77744ae0a4e3c7a54fe52fa70b125d0971eb0a3bcfb562fa8e74537af0dad5bc405cc606726eb501fc748a241c10910deea89cfb + languageName: node + linkType: hard + +"is-directory@npm:^0.3.1": + version: 0.3.1 + resolution: "is-directory@npm:0.3.1" + checksum: dce9a9d3981e38f2ded2a80848734824c50ee8680cd09aa477bef617949715cfc987197a2ca0176c58a9fb192a1a0d69b535c397140d241996a609d5906ae524 + languageName: node + linkType: hard + +"is-docker@npm:^2.0.0": version: 2.2.1 resolution: "is-docker@npm:2.2.1" bin: @@ -13078,19 +11545,42 @@ __metadata: languageName: node linkType: hard -"is-extglob@npm:^2.1.1": +"is-extendable@npm:^0.1.0, is-extendable@npm:^0.1.1": + version: 0.1.1 + resolution: "is-extendable@npm:0.1.1" + checksum: 3875571d20a7563772ecc7a5f36cb03167e9be31ad259041b4a8f73f33f885441f778cee1f1fe0085eb4bc71679b9d8c923690003a36a6a5fdf8023e6e3f0672 + languageName: node + linkType: hard + +"is-extendable@npm:^1.0.1": + version: 1.0.1 + resolution: "is-extendable@npm:1.0.1" + dependencies: + is-plain-object: ^2.0.4 + checksum: db07bc1e9de6170de70eff7001943691f05b9d1547730b11be01c0ebfe67362912ba743cf4be6fd20a5e03b4180c685dad80b7c509fe717037e3eee30ad8e84f + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.0, is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 languageName: node linkType: hard -"is-finalizationregistry@npm:^1.1.0": - version: 1.1.1 - resolution: "is-finalizationregistry@npm:1.1.1" +"is-finalizationregistry@npm:^1.0.2": + version: 1.0.2 + resolution: "is-finalizationregistry@npm:1.0.2" dependencies: - call-bound: ^1.0.3 - checksum: 38c646c506e64ead41a36c182d91639833311970b6b6c6268634f109eef0a1a9d2f1f2e499ef4cb43c744a13443c4cdd2f0812d5afdcee5e9b65b72b28c48557 + call-bind: ^1.0.2 + checksum: 4f243a8e06228cd45bdab8608d2cb7abfc20f6f0189c8ac21ea8d603f1f196eabd531ce0bb8e08cbab047e9845ef2c191a3761c9a17ad5cabf8b35499c4ad35d + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^2.0.0": + version: 2.0.0 + resolution: "is-fullwidth-code-point@npm:2.0.0" + checksum: eef9c6e15f68085fec19ff6a978a6f1b8f48018fd1265035552078ee945573594933b09bbd6f562553e2a241561439f1ef5339276eba68d272001343084cfab8 languageName: node linkType: hard @@ -13108,15 +11598,21 @@ __metadata: languageName: node linkType: hard -"is-generator-function@npm:^1.0.10": - version: 1.1.0 - resolution: "is-generator-function@npm:1.1.0" +"is-generator-function@npm:^1.0.10, is-generator-function@npm:^1.0.7": + version: 1.0.10 + resolution: "is-generator-function@npm:1.0.10" dependencies: - call-bound: ^1.0.3 - get-proto: ^1.0.0 - has-tostringtag: ^1.0.2 - safe-regex-test: ^1.1.0 - checksum: f7f7276131bdf7e28169b86ac55a5b080012a597f9d85a0cbef6fe202a7133fa450a3b453e394870e3cb3685c5a764c64a9f12f614684b46969b1e6f297bed6b + has-tostringtag: ^1.0.0 + checksum: d54644e7dbaccef15ceb1e5d91d680eb5068c9ee9f9eb0a9e04173eb5542c9b51b5ab52c5537f5703e48d5fddfd376817c1ca07a84a407b7115b769d4bdde72b + languageName: node + linkType: hard + +"is-glob@npm:^3.1.0": + version: 3.1.0 + resolution: "is-glob@npm:3.1.0" + dependencies: + is-extglob: ^2.1.0 + checksum: 9d483bca84f16f01230f7c7c8c63735248fe1064346f292e0f6f8c76475fd20c6f50fc19941af5bec35f85d6bf26f4b7768f39a48a5f5fdc72b408dc74e07afc languageName: node linkType: hard @@ -13129,14 +11625,28 @@ __metadata: languageName: node linkType: hard -"is-hexadecimal@npm:^2.0.0": - version: 2.0.1 - resolution: "is-hexadecimal@npm:2.0.1" - checksum: 66a2ea85994c622858f063f23eda506db29d92b52580709eb6f4c19550552d4dcf3fb81952e52f7cf972097237959e00adc7bb8c9400cd12886e15bf06145321 +"is-hexadecimal@npm:^1.0.0": + version: 1.0.4 + resolution: "is-hexadecimal@npm:1.0.4" + checksum: a452e047587b6069332d83130f54d30da4faf2f2ebaa2ce6d073c27b5703d030d58ed9e0b729c8e4e5b52c6f1dab26781bb77b7bc6c7805f14f320e328ff8cd5 + languageName: node + linkType: hard + +"is-interactive@npm:^1.0.0": + version: 1.0.0 + resolution: "is-interactive@npm:1.0.0" + checksum: 824808776e2d468b2916cdd6c16acacebce060d844c35ca6d82267da692e92c3a16fdba624c50b54a63f38bdc4016055b6f443ce57d7147240de4f8cdabaf6f9 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 languageName: node linkType: hard -"is-map@npm:^2.0.3": +"is-map@npm:^2.0.2, is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" checksum: e6ce5f6380f32b141b3153e6ba9074892bbbbd655e92e7ba5ff195239777e767a976dcd4e22f864accaf30e53ebf961ab1995424aef91af68788f0591b7396cc @@ -13157,20 +11667,28 @@ __metadata: languageName: node linkType: hard -"is-node-process@npm:^1.2.0": +"is-node-process@npm:^1.0.1": version: 1.2.0 resolution: "is-node-process@npm:1.2.0" checksum: 930765cdc6d81ab8f1bbecbea4a8d35c7c6d88a3ff61f3630e0fc7f22d624d7661c1df05c58547d0eb6a639dfa9304682c8e342c4113a6ed51472b704cee2928 languageName: node linkType: hard -"is-number-object@npm:^1.1.1": - version: 1.1.1 - resolution: "is-number-object@npm:1.1.1" +"is-number-object@npm:^1.0.4": + version: 1.0.7 + resolution: "is-number-object@npm:1.0.7" dependencies: - call-bound: ^1.0.3 - has-tostringtag: ^1.0.2 - checksum: 6517f0a0e8c4b197a21afb45cd3053dc711e79d45d8878aa3565de38d0102b130ca8732485122c7b336e98c27dacd5236854e3e6526e0eb30cae64956535662f + has-tostringtag: ^1.0.0 + checksum: d1e8d01bb0a7134c74649c4e62da0c6118a0bfc6771ea3c560914d52a627873e6920dd0fd0ebc0e12ad2ff4687eac4c308f7e80320b973b2c8a2c8f97a7524f7 + languageName: node + linkType: hard + +"is-number@npm:^3.0.0": + version: 3.0.0 + resolution: "is-number@npm:3.0.0" + dependencies: + kind-of: ^3.0.2 + checksum: 0c62bf8e9d72c4dd203a74d8cfc751c746e75513380fef420cda8237e619a988ee43e678ddb23c87ac24d91ac0fe9f22e4ffb1301a50310c697e9d73ca3994e9 languageName: node linkType: hard @@ -13188,24 +11706,58 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.3": - version: 3.0.3 - resolution: "is-path-inside@npm:3.0.3" - checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 +"is-obj@npm:^2.0.0": + version: 2.0.0 + resolution: "is-obj@npm:2.0.0" + checksum: c9916ac8f4621962a42f5e80e7ffdb1d79a3fab7456ceaeea394cd9e0858d04f985a9ace45be44433bf605673c8be8810540fe4cc7f4266fc7526ced95af5a08 languageName: node linkType: hard -"is-plain-obj@npm:^3.0.0": - version: 3.0.0 - resolution: "is-plain-obj@npm:3.0.0" - checksum: a6ebdf8e12ab73f33530641972a72a4b8aed6df04f762070d823808303e4f76d87d5ea5bd76f96a7bbe83d93f04ac7764429c29413bd9049853a69cb630fb21c +"is-path-cwd@npm:^2.0.0": + version: 2.2.0 + resolution: "is-path-cwd@npm:2.2.0" + checksum: 46a840921bb8cc0dc7b5b423a14220e7db338072a4495743a8230533ce78812dc152548c86f4b828411fe98c5451959f07cf841c6a19f611e46600bd699e8048 languageName: node linkType: hard -"is-plain-obj@npm:^4.0.0": - version: 4.1.0 - resolution: "is-plain-obj@npm:4.1.0" - checksum: 6dc45da70d04a81f35c9310971e78a6a3c7a63547ef782e3a07ee3674695081b6ca4e977fbb8efc48dae3375e0b34558d2bcd722aec9bddfa2d7db5b041be8ce +"is-path-in-cwd@npm:^2.0.0": + version: 2.1.0 + resolution: "is-path-in-cwd@npm:2.1.0" + dependencies: + is-path-inside: ^2.1.0 + checksum: 6b01b3f8c9172e9682ea878d001836a0cc5a78cbe6236024365d478c2c9e384da2417e5f21f2ad2da2761d0465309fc5baf6e71187d2a23f0058da69790f7f48 + languageName: node + linkType: hard + +"is-path-inside@npm:^2.1.0": + version: 2.1.0 + resolution: "is-path-inside@npm:2.1.0" + dependencies: + path-is-inside: ^1.0.2 + checksum: 6ca34dbd84d5c50a3ee1547afb6ada9b06d556a4ff42da9b303797e4acc3ac086516a4833030aa570f397f8c58dacabd57ee8e6c2ce8b2396a986ad2af10fcaf + languageName: node + linkType: hard + +"is-plain-obj@npm:^1.0.0": + version: 1.1.0 + resolution: "is-plain-obj@npm:1.1.0" + checksum: 0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 + languageName: node + linkType: hard + +"is-plain-obj@npm:^2.0.0": + version: 2.1.0 + resolution: "is-plain-obj@npm:2.1.0" + checksum: cec9100678b0a9fe0248a81743041ed990c2d4c99f893d935545cfbc42876cbe86d207f3b895700c690ad2fa520e568c44afc1605044b535a7820c1d40e38daa + languageName: node + linkType: hard + +"is-plain-object@npm:^2.0.3, is-plain-object@npm:^2.0.4": + version: 2.0.4 + resolution: "is-plain-object@npm:2.0.4" + dependencies: + isobject: ^3.0.1 + checksum: 2a401140cfd86cabe25214956ae2cfee6fbd8186809555cd0e84574f88de7b17abacb2e477a6a658fa54c6083ecbda1e6ae404c7720244cd198903848fca70ca languageName: node linkType: hard @@ -13216,22 +11768,13 @@ __metadata: languageName: node linkType: hard -"is-promise@npm:^4.0.0": - version: 4.0.0 - resolution: "is-promise@npm:4.0.0" - checksum: 0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a - languageName: node - linkType: hard - -"is-regex@npm:^1.2.1": - version: 1.2.1 - resolution: "is-regex@npm:1.2.1" +"is-regex@npm:^1.1.4": + version: 1.1.4 + resolution: "is-regex@npm:1.1.4" dependencies: - call-bound: ^1.0.2 - gopd: ^1.2.0 - has-tostringtag: ^1.0.2 - hasown: ^2.0.2 - checksum: 99ee0b6d30ef1bb61fa4b22fae7056c6c9b3c693803c0c284ff7a8570f83075a7d38cda53b06b7996d441215c27895ea5d1af62124562e13d91b3dbec41a5e13 + call-bind: ^1.0.2 + has-tostringtag: ^1.0.0 + checksum: 362399b33535bc8f386d96c45c9feb04cf7f8b41c182f54174c1a45c9abbbe5e31290bbad09a458583ff6bf3b2048672cdb1881b13289569a7c548370856a652 languageName: node linkType: hard @@ -13242,63 +11785,74 @@ __metadata: languageName: node linkType: hard -"is-root@npm:^2.1.0": +"is-resolvable@npm:^1.0.0": + version: 1.1.0 + resolution: "is-resolvable@npm:1.1.0" + checksum: 2ddff983be0cabc2c8d60246365755f8fb322f5fb9db834740d3e694c635c1b74c1bd674cf221e072fc4bd911ef3f08f2247d390e476f7e80af9092443193c68 + languageName: node + linkType: hard + +"is-root@npm:2.1.0": version: 2.1.0 resolution: "is-root@npm:2.1.0" checksum: 37eea0822a2a9123feb58a9d101558ba276771a6d830f87005683349a9acff15958a9ca590a44e778c6b335660b83e85c744789080d734f6081a935a4880aee2 languageName: node linkType: hard -"is-set@npm:^2.0.3": +"is-set@npm:^2.0.2, is-set@npm:^2.0.3": version: 2.0.3 resolution: "is-set@npm:2.0.3" checksum: 36e3f8c44bdbe9496c9689762cc4110f6a6a12b767c5d74c0398176aa2678d4467e3bf07595556f2dba897751bde1422480212b97d973c7b08a343100b0c0dfe languageName: node linkType: hard -"is-shared-array-buffer@npm:^1.0.4": - version: 1.0.4 - resolution: "is-shared-array-buffer@npm:1.0.4" +"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "is-shared-array-buffer@npm:1.0.3" dependencies: - call-bound: ^1.0.3 - checksum: 1611fedc175796eebb88f4dfc393dd969a4a8e6c69cadaff424ee9d4464f9f026399a5f84a90f7c62d6d7ee04e3626a912149726de102b0bd6c1ee6a9868fa5a + call-bind: ^1.0.7 + checksum: a4fff602c309e64ccaa83b859255a43bb011145a42d3f56f67d9268b55bc7e6d98a5981a1d834186ad3105d6739d21547083fe7259c76c0468483fc538e716d8 + languageName: node + linkType: hard + +"is-stream@npm:^1.1.0": + version: 1.1.0 + resolution: "is-stream@npm:1.1.0" + checksum: 063c6bec9d5647aa6d42108d4c59723d2bd4ae42135a2d4db6eadbd49b7ea05b750fd69d279e5c7c45cf9da753ad2c00d8978be354d65aa9f6bb434969c6a2ae languageName: node linkType: hard -"is-stream@npm:^2, is-stream@npm:^2.0.0": +"is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 languageName: node linkType: hard -"is-string@npm:^1.1.1": - version: 1.1.1 - resolution: "is-string@npm:1.1.1" +"is-string@npm:^1.0.5, is-string@npm:^1.0.7": + version: 1.0.7 + resolution: "is-string@npm:1.0.7" dependencies: - call-bound: ^1.0.3 - has-tostringtag: ^1.0.2 - checksum: 2eeaaff605250f5e836ea3500d33d1a5d3aa98d008641d9d42fb941e929ffd25972326c2ef912987e54c95b6f10416281aaf1b35cdf81992cfb7524c5de8e193 + has-tostringtag: ^1.0.0 + checksum: 323b3d04622f78d45077cf89aab783b2f49d24dc641aa89b5ad1a72114cfeff2585efc8c12ef42466dff32bde93d839ad321b26884cf75e5a7892a938b089989 languageName: node linkType: hard -"is-symbol@npm:^1.0.4, is-symbol@npm:^1.1.1": - version: 1.1.1 - resolution: "is-symbol@npm:1.1.1" +"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": + version: 1.0.4 + resolution: "is-symbol@npm:1.0.4" dependencies: - call-bound: ^1.0.2 - has-symbols: ^1.1.0 - safe-regex-test: ^1.1.0 - checksum: bfafacf037af6f3c9d68820b74be4ae8a736a658a3344072df9642a090016e281797ba8edbeb1c83425879aae55d1cb1f30b38bf132d703692b2570367358032 + has-symbols: ^1.0.2 + checksum: 92805812ef590738d9de49d677cd17dfd486794773fb6fa0032d16452af46e9b91bb43ffe82c983570f015b37136f4b53b28b8523bfb10b0ece7a66c31a54510 languageName: node linkType: hard -"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15": - version: 1.1.15 - resolution: "is-typed-array@npm:1.1.15" +"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.3": + version: 1.1.13 + resolution: "is-typed-array@npm:1.1.13" dependencies: - which-typed-array: ^1.1.16 - checksum: ea7cfc46c282f805d19a9ab2084fd4542fed99219ee9dbfbc26284728bd713a51eac66daa74eca00ae0a43b61322920ba334793607dc39907465913e921e0892 + which-typed-array: ^1.1.14 + checksum: 150f9ada183a61554c91e1c4290086d2c100b0dff45f60b028519be72a8db964da403c48760723bf5253979b8dffe7b544246e0e5351dcd05c5fdb1dcc1dc0f0 languageName: node linkType: hard @@ -13309,6 +11863,13 @@ __metadata: languageName: node linkType: hard +"is-unicode-supported@npm:^0.1.0": + version: 0.1.0 + resolution: "is-unicode-supported@npm:0.1.0" + checksum: a2aab86ee7712f5c2f999180daaba5f361bdad1efadc9610ff5b8ab5495b86e4f627839d085c6530363c6d6d4ecbde340fb8e54bdb83da4ba8e0865ed5513c52 + languageName: node + linkType: hard + "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -13316,26 +11877,40 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1": - version: 1.1.1 - resolution: "is-weakref@npm:1.1.1" +"is-weakref@npm:^1.0.2": + version: 1.0.2 + resolution: "is-weakref@npm:1.0.2" dependencies: - call-bound: ^1.0.3 - checksum: 1769b9aed5d435a3a989ffc18fc4ad1947d2acdaf530eb2bd6af844861b545047ea51102f75901f89043bed0267ed61d914ee21e6e8b9aa734ec201cdfc0726f + call-bind: ^1.0.2 + checksum: 95bd9a57cdcb58c63b1c401c60a474b0f45b94719c30f548c891860f051bc2231575c290a6b420c6bc6e7ed99459d424c652bd5bf9a1d5259505dc35b4bf83de languageName: node linkType: hard "is-weakset@npm:^2.0.3": - version: 2.0.4 - resolution: "is-weakset@npm:2.0.4" + version: 2.0.3 + resolution: "is-weakset@npm:2.0.3" dependencies: - call-bound: ^1.0.3 - get-intrinsic: ^1.2.6 - checksum: 5c6c8415a06065d78bdd5e3a771483aa1cd928df19138aa73c4c51333226f203f22117b4325df55cc8b3085a6716870a320c2d757efee92d7a7091a039082041 + call-bind: ^1.0.7 + get-intrinsic: ^1.2.4 + checksum: 8b6a20ee9f844613ff8f10962cfee49d981d584525f2357fee0a04dfbcde9fd607ed60cb6dab626dbcc470018ae6392e1ff74c0c1aced2d487271411ad9d85ae + languageName: node + linkType: hard + +"is-windows@npm:^1.0.2": + version: 1.0.2 + resolution: "is-windows@npm:1.0.2" + checksum: 438b7e52656fe3b9b293b180defb4e448088e7023a523ec21a91a80b9ff8cdb3377ddb5b6e60f7c7de4fa8b63ab56e121b6705fe081b3cf1b828b0a380009ad7 + languageName: node + linkType: hard + +"is-wsl@npm:^1.1.0": + version: 1.1.0 + resolution: "is-wsl@npm:1.1.0" + checksum: ea157d232351e68c92bd62fc541771096942fe72f69dff452dd26dcc31466258c570a3b04b8cda2e01cd2968255b02951b8670d08ea4ed76d6b1a646061ac4fe languageName: node linkType: hard -"is-wsl@npm:^2.2.0": +"is-wsl@npm:^2.1.1, is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" dependencies: @@ -13351,6 +11926,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:1.0.0, isarray@npm:^1.0.0, isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + languageName: node + linkType: hard + "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -13358,13 +11940,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab - languageName: node - linkType: hard - "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -13379,6 +11954,22 @@ __metadata: languageName: node linkType: hard +"isobject@npm:^2.0.0": + version: 2.1.0 + resolution: "isobject@npm:2.1.0" + dependencies: + isarray: 1.0.0 + checksum: 811c6f5a866877d31f0606a88af4a45f282544de886bf29f6a34c46616a1ae2ed17076cc6bf34c0128f33eecf7e1fcaa2c82cf3770560d3e26810894e96ae79f + languageName: node + linkType: hard + +"isobject@npm:^3.0.0, isobject@npm:^3.0.1": + version: 3.0.1 + resolution: "isobject@npm:3.0.1" + checksum: db85c4c970ce30693676487cca0e61da2ca34e8d4967c2e1309143ff910c207133a969f9e4ddb2dc6aba670aabce4e0e307146c310350b298e74a31f7d464703 + languageName: node + linkType: hard + "istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": version: 3.2.2 resolution: "istanbul-lib-coverage@npm:3.2.2" @@ -13386,7 +11977,19 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-instrument@npm:^5.0.4, istanbul-lib-instrument@npm:^5.1.0": +"istanbul-lib-instrument@npm:^4.0.3": + version: 4.0.3 + resolution: "istanbul-lib-instrument@npm:4.0.3" + dependencies: + "@babel/core": ^7.7.5 + "@istanbuljs/schema": ^0.1.2 + istanbul-lib-coverage: ^3.0.0 + semver: ^6.3.0 + checksum: fa1171d3022b1bb8f6a734042620ac5d9ee7dc80f3065a0bb12863e9f0494d0eefa3d86608fcc0254ab2765d29d7dad8bdc42e5f8df2f9a1fbe85ccc59d76cb9 + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^5.0.4": version: 5.2.1 resolution: "istanbul-lib-instrument@npm:5.2.1" dependencies: @@ -13421,176 +12024,157 @@ __metadata: languageName: node linkType: hard -"istanbul-reports@npm:^3.1.3": - version: 3.2.0 - resolution: "istanbul-reports@npm:3.2.0" +"istanbul-reports@npm:^3.0.2": + version: 3.1.7 + resolution: "istanbul-reports@npm:3.1.7" dependencies: html-escaper: ^2.0.0 istanbul-lib-report: ^3.0.0 - checksum: 72b4c8525276147908d28b0917bc675b1019836b638e50875521ca3b8ec63672681aa98dbab88a6f49ef798c08fe041d428abdcf84f4f3fcff5844eee54af65a + checksum: 2072db6e07bfbb4d0eb30e2700250636182398c1af811aea5032acb219d2080f7586923c09fa194029efd6b92361afb3dcbe1ebcc3ee6651d13340f7c6c4ed95 languageName: node linkType: hard -"iterator.prototype@npm:^1.1.4": - version: 1.1.5 - resolution: "iterator.prototype@npm:1.1.5" +"iterator.prototype@npm:^1.1.2": + version: 1.1.2 + resolution: "iterator.prototype@npm:1.1.2" dependencies: - define-data-property: ^1.1.4 - es-object-atoms: ^1.0.0 - get-intrinsic: ^1.2.6 - get-proto: ^1.0.0 - has-symbols: ^1.1.0 - set-function-name: ^2.0.2 - checksum: 7db23c42629ba4790e6e15f78b555f41dbd08818c85af306988364bd19d86716a1187cb333444f3a0036bfc078a0e9cb7ec67fef3a61662736d16410d7f77869 + define-properties: ^1.2.1 + get-intrinsic: ^1.2.1 + has-symbols: ^1.0.3 + reflect.getprototypeof: ^1.0.4 + set-function-name: ^2.0.1 + checksum: d8a507e2ccdc2ce762e8a1d3f4438c5669160ac72b88b648e59a688eec6bc4e64b22338e74000518418d9e693faf2a092d2af21b9ec7dbf7763b037a54701168 languageName: node linkType: hard -"jackspeak@npm:^3.1.2": - version: 3.4.3 - resolution: "jackspeak@npm:3.4.3" +"jackspeak@npm:^2.3.6": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" dependencies: "@isaacs/cliui": ^8.0.2 "@pkgjs/parseargs": ^0.11.0 dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: be31027fc72e7cc726206b9f560395604b82e0fddb46c4cbf9f97d049bcef607491a5afc0699612eaa4213ca5be8fd3e1e7cd187b3040988b65c9489838a7c00 - languageName: node - linkType: hard - -"jackspeak@npm:^4.1.1": - version: 4.1.1 - resolution: "jackspeak@npm:4.1.1" - dependencies: - "@isaacs/cliui": ^8.0.2 - checksum: daca714c5adebfb80932c0b0334025307b68602765098d73d52ec546bc4defdb083292893384261c052742255d0a77d8fcf96f4c669bcb4a99b498b94a74955e - languageName: node - linkType: hard - -"jake@npm:^10.8.5": - version: 10.9.4 - resolution: "jake@npm:10.9.4" - dependencies: - async: ^3.2.6 - filelist: ^1.0.4 - picocolors: ^1.1.1 - bin: - jake: bin/cli.js - checksum: 1ca6f6a6fe1f2385ed32df82fcb71f9c7378f7fb591ed0b183e9d79a1801221cfe96f3dd9174db2d1a9705a13ae659f2af7004ad23645c910121fc7086a137ef + checksum: 57d43ad11eadc98cdfe7496612f6bbb5255ea69fe51ea431162db302c2a11011642f50cfad57288bd0aea78384a0612b16e131944ad8ecd09d619041c8531b54 languageName: node linkType: hard -"jest-changed-files@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-changed-files@npm:27.5.1" +"jest-changed-files@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-changed-files@npm:26.6.2" dependencies: - "@jest/types": ^27.5.1 - execa: ^5.0.0 - throat: ^6.0.1 - checksum: 95e9dc74c3ca688ef85cfeab270f43f8902721a6c8ade6ac2459459a77890c85977f537d6fb809056deaa6d9c3f075fa7d2699ff5f3bf7d3fda17c3760b79b15 + "@jest/types": ^26.6.2 + execa: ^4.0.0 + throat: ^5.0.0 + checksum: 8c405f5ff905ee69ace9fd39355233206e3e233badf6a3f3b27e45bbf0a46d86943430be2e080d25b1e085f4231b9b3b27c94317aa04116efb40b592184066f4 languageName: node linkType: hard -"jest-circus@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-circus@npm:27.5.1" +"jest-circus@npm:26.6.0": + version: 26.6.0 + resolution: "jest-circus@npm:26.6.0" dependencies: - "@jest/environment": ^27.5.1 - "@jest/test-result": ^27.5.1 - "@jest/types": ^27.5.1 + "@babel/traverse": ^7.1.0 + "@jest/environment": ^26.6.0 + "@jest/test-result": ^26.6.0 + "@jest/types": ^26.6.0 + "@types/babel__traverse": ^7.0.4 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 dedent: ^0.7.0 - expect: ^27.5.1 + expect: ^26.6.0 is-generator-fn: ^2.0.0 - jest-each: ^27.5.1 - jest-matcher-utils: ^27.5.1 - jest-message-util: ^27.5.1 - jest-runtime: ^27.5.1 - jest-snapshot: ^27.5.1 - jest-util: ^27.5.1 - pretty-format: ^27.5.1 - slash: ^3.0.0 - stack-utils: ^2.0.3 - throat: ^6.0.1 - checksum: 6192dccbccb3a6acfa361cbb97bdbabe94864ccf3d885932cfd41f19534329d40698078cf9be1489415e8234255d6ea9f9aff5396b79ad842a6fca6e6fc08fd0 - languageName: node - linkType: hard - -"jest-cli@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-cli@npm:27.5.1" - dependencies: - "@jest/core": ^27.5.1 - "@jest/test-result": ^27.5.1 - "@jest/types": ^27.5.1 + jest-each: ^26.6.0 + jest-matcher-utils: ^26.6.0 + jest-message-util: ^26.6.0 + jest-runner: ^26.6.0 + jest-runtime: ^26.6.0 + jest-snapshot: ^26.6.0 + jest-util: ^26.6.0 + pretty-format: ^26.6.0 + stack-utils: ^2.0.2 + throat: ^5.0.0 + checksum: acc354223964bafd40fd1caae4099b58ccb1551bc93a394398b441274c225552f1941ce9903d126fb0adc3952a108e2994270c6a50a3e7e5af931b65b8c170f0 + languageName: node + linkType: hard + +"jest-cli@npm:^26.6.0": + version: 26.6.3 + resolution: "jest-cli@npm:26.6.3" + dependencies: + "@jest/core": ^26.6.3 + "@jest/test-result": ^26.6.2 + "@jest/types": ^26.6.2 chalk: ^4.0.0 exit: ^0.1.2 - graceful-fs: ^4.2.9 + graceful-fs: ^4.2.4 import-local: ^3.0.2 - jest-config: ^27.5.1 - jest-util: ^27.5.1 - jest-validate: ^27.5.1 + is-ci: ^2.0.0 + jest-config: ^26.6.3 + jest-util: ^26.6.2 + jest-validate: ^26.6.2 prompts: ^2.0.1 - yargs: ^16.2.0 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + yargs: ^15.4.1 bin: jest: bin/jest.js - checksum: 6c0a69fb48e500241409e09ff743ed72bc6578d7769e2c994724e7ef1e5587f6c1f85dc429e93b98ae38a365222993ee70f0acc2199358992120900984f349e5 + checksum: c8554147be756f09f5566974f0026485f78742e8642d2723f8fbee5746f50f44fb72b17aad181226655a8446d3ecc8ad8ed0a11a8a55686fa2b9c10d85700121 languageName: node linkType: hard -"jest-config@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-config@npm:27.5.1" +"jest-config@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-config@npm:26.6.3" dependencies: - "@babel/core": ^7.8.0 - "@jest/test-sequencer": ^27.5.1 - "@jest/types": ^27.5.1 - babel-jest: ^27.5.1 + "@babel/core": ^7.1.0 + "@jest/test-sequencer": ^26.6.3 + "@jest/types": ^26.6.2 + babel-jest: ^26.6.3 chalk: ^4.0.0 - ci-info: ^3.2.0 deepmerge: ^4.2.2 glob: ^7.1.1 - graceful-fs: ^4.2.9 - jest-circus: ^27.5.1 - jest-environment-jsdom: ^27.5.1 - jest-environment-node: ^27.5.1 - jest-get-type: ^27.5.1 - jest-jasmine2: ^27.5.1 - jest-regex-util: ^27.5.1 - jest-resolve: ^27.5.1 - jest-runner: ^27.5.1 - jest-util: ^27.5.1 - jest-validate: ^27.5.1 - micromatch: ^4.0.4 - parse-json: ^5.2.0 - pretty-format: ^27.5.1 - slash: ^3.0.0 - strip-json-comments: ^3.1.1 + graceful-fs: ^4.2.4 + jest-environment-jsdom: ^26.6.2 + jest-environment-node: ^26.6.2 + jest-get-type: ^26.3.0 + jest-jasmine2: ^26.6.3 + jest-regex-util: ^26.0.0 + jest-resolve: ^26.6.2 + jest-util: ^26.6.2 + jest-validate: ^26.6.2 + micromatch: ^4.0.2 + pretty-format: ^26.6.2 peerDependencies: ts-node: ">=9.0.0" peerDependenciesMeta: ts-node: optional: true - checksum: 1188fd46c0ed78cbe3175eb9ad6712ccf74a74be33d9f0d748e147c107f0889f8b701fbff1567f31836ae18597dacdc43d6a8fc30dd34ade6c9229cc6c7cb82d + checksum: 303c798582d3c5d4b4e6ab8a4d91a83ded28e4ebbc0bcfc1ad271f9864437ef5409b7c7773010143811bc8176b0695c096717b91419c6484b56dcc032560a74b languageName: node linkType: hard -"jest-diff@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-diff@npm:27.5.1" +"jest-diff@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-diff@npm:26.6.2" + dependencies: + chalk: ^4.0.0 + diff-sequences: ^26.6.2 + jest-get-type: ^26.3.0 + pretty-format: ^26.6.2 + checksum: d00d297f31e1ac0252127089892432caa7a11c69bde29cf3bb6c7a839c8afdb95cf1fd401f9df16a4422745da2e6a5d94b428b30666a2540c38e1c5699915c2d + languageName: node + linkType: hard + +"jest-diff@npm:^28.1.3": + version: 28.1.3 + resolution: "jest-diff@npm:28.1.3" dependencies: chalk: ^4.0.0 - diff-sequences: ^27.5.1 - jest-get-type: ^27.5.1 - pretty-format: ^27.5.1 - checksum: 8be27c1e1ee57b2bb2bef9c0b233c19621b4c43d53a3c26e2c00a4e805eb4ea11fe1694a06a9fb0e80ffdcfdc0d2b1cb0b85920b3f5c892327ecd1e7bd96b865 + diff-sequences: ^28.1.1 + jest-get-type: ^28.0.2 + pretty-format: ^28.1.3 + checksum: fa8583e0ccbe775714ce850b009be1b0f6b17a4b6759f33ff47adef27942ebc610dbbcc8a5f7cfb7f12b3b3b05afc9fb41d5f766674616025032ff1e4f9866e0 languageName: node linkType: hard @@ -13606,68 +12190,75 @@ __metadata: languageName: node linkType: hard -"jest-docblock@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-docblock@npm:27.5.1" +"jest-docblock@npm:^26.0.0": + version: 26.0.0 + resolution: "jest-docblock@npm:26.0.0" dependencies: detect-newline: ^3.0.0 - checksum: c0fed6d55b229d8bffdd8d03f121dd1a3be77c88f50552d374f9e1ea3bde57bf6bea017a0add04628d98abcb1bfb48b456438eeca8a74ef0053f4dae3b95d29c + checksum: e03ef104ee8c571335e6fa394b8fc8d2bd87eec9fe8b3d7d9aac056ada7de288f37ee8ac4922bb3a4222ac304db975d8832d5abc85486092866c534a16847cd5 languageName: node linkType: hard -"jest-each@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-each@npm:27.5.1" +"jest-each@npm:^26.6.0, jest-each@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-each@npm:26.6.2" dependencies: - "@jest/types": ^27.5.1 + "@jest/types": ^26.6.2 chalk: ^4.0.0 - jest-get-type: ^27.5.1 - jest-util: ^27.5.1 - pretty-format: ^27.5.1 - checksum: b5a6d8730fd938982569c9e0b42bdf3c242f97b957ed8155a6473b5f7b540970f8685524e7f53963dc1805319f4b6602abfc56605590ca19d55bd7a87e467e63 + jest-get-type: ^26.3.0 + jest-util: ^26.6.2 + pretty-format: ^26.6.2 + checksum: 4e00ea4667e4fe015b894dc698cce0ae695cf458e021e5da62d4a5b052cd2c0a878da93f8c97cbdde60bcecf70982e8d3a7a5d63e1588f59531cc797a18c39ef languageName: node linkType: hard -"jest-environment-jsdom@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-environment-jsdom@npm:27.5.1" +"jest-environment-jsdom@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-environment-jsdom@npm:26.6.2" dependencies: - "@jest/environment": ^27.5.1 - "@jest/fake-timers": ^27.5.1 - "@jest/types": ^27.5.1 + "@jest/environment": ^26.6.2 + "@jest/fake-timers": ^26.6.2 + "@jest/types": ^26.6.2 "@types/node": "*" - jest-mock: ^27.5.1 - jest-util: ^27.5.1 - jsdom: ^16.6.0 - checksum: bc104aef7d7530d0740402aa84ac812138b6d1e51fe58adecce679f82b99340ddab73e5ec68fa079f33f50c9ddec9728fc9f0ddcca2ad6f0b351eed2762cc555 + jest-mock: ^26.6.2 + jest-util: ^26.6.2 + jsdom: ^16.4.0 + checksum: 8af9ffdf1b147362a19032bfe9ed51b709d43c74dc4b1c45e56d721808bf6cabdca8c226855b55a985ea196ce51cdb171bfe420ceec3daa2d13818d5c1915890 languageName: node linkType: hard -"jest-environment-node@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-environment-node@npm:27.5.1" +"jest-environment-node@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-environment-node@npm:26.6.2" dependencies: - "@jest/environment": ^27.5.1 - "@jest/fake-timers": ^27.5.1 - "@jest/types": ^27.5.1 + "@jest/environment": ^26.6.2 + "@jest/fake-timers": ^26.6.2 + "@jest/types": ^26.6.2 "@types/node": "*" - jest-mock: ^27.5.1 - jest-util: ^27.5.1 - checksum: 0f988330c4f3eec092e3fb37ea753b0c6f702e83cd8f4d770af9c2bf964a70bc45fbd34ec6fdb6d71ce98a778d9f54afd673e63f222e4667fff289e8069dba39 + jest-mock: ^26.6.2 + jest-util: ^26.6.2 + checksum: 0b69b481e6d6f2350ed241c2dabc70b0b1f3a00f9a410b7dad97c8ab38e88026acf7445ca663eb314f46ff50acee0133100b1006bf4ebda5298ffb02763a6861 languageName: node linkType: hard "jest-fail-on-console@npm:^3.0.2": - version: 3.3.1 - resolution: "jest-fail-on-console@npm:3.3.1" - checksum: ca83aaf623e3772ec612e639fefca54472d38a7f4ea8119de8f12dcdb5e425e9f09d803ffd3b7db7b78fdc4edcffea3340f1ea7d160007da32f03d6ec569686b + version: 3.2.0 + resolution: "jest-fail-on-console@npm:3.2.0" + checksum: 389aa581484825a285fc27f959369a674d4a81ede7474218a27d3596cfc8ed6ea13a0f99053e5d08d7fa43b68246ab8ff51592a70fdb9b4e2b355ca9a165221a languageName: node linkType: hard -"jest-get-type@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-get-type@npm:27.5.1" - checksum: 63064ab70195c21007d897c1157bf88ff94a790824a10f8c890392e7d17eda9c3900513cb291ca1c8d5722cad79169764e9a1279f7c8a9c4cd6e9109ff04bbc0 +"jest-get-type@npm:^26.3.0": + version: 26.3.0 + resolution: "jest-get-type@npm:26.3.0" + checksum: 1cc6465ae4f5e880be22ba52fd270fa64c21994915f81b41f8f7553a7957dd8e077cc8d03035de9412e2d739f8bad6a032ebb5dab5805692a5fb9e20dd4ea666 + languageName: node + linkType: hard + +"jest-get-type@npm:^28.0.2": + version: 28.0.2 + resolution: "jest-get-type@npm:28.0.2" + checksum: 5281d7c89bc8156605f6d15784f45074f4548501195c26e9b188742768f72d40948252d13230ea905b5349038865a1a8eeff0e614cc530ff289dfc41fe843abd languageName: node linkType: hard @@ -13678,74 +12269,88 @@ __metadata: languageName: node linkType: hard -"jest-haste-map@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-haste-map@npm:27.5.1" +"jest-haste-map@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-haste-map@npm:26.6.2" dependencies: - "@jest/types": ^27.5.1 + "@jest/types": ^26.6.2 "@types/graceful-fs": ^4.1.2 "@types/node": "*" anymatch: ^3.0.3 fb-watchman: ^2.0.0 - fsevents: ^2.3.2 - graceful-fs: ^4.2.9 - jest-regex-util: ^27.5.1 - jest-serializer: ^27.5.1 - jest-util: ^27.5.1 - jest-worker: ^27.5.1 - micromatch: ^4.0.4 + fsevents: ^2.1.2 + graceful-fs: ^4.2.4 + jest-regex-util: ^26.0.0 + jest-serializer: ^26.6.2 + jest-util: ^26.6.2 + jest-worker: ^26.6.2 + micromatch: ^4.0.2 + sane: ^4.0.3 walker: ^1.0.7 dependenciesMeta: fsevents: optional: true - checksum: e092a1412829a9254b4725531ee72926de530f77fda7b0d9ea18008fb7623c16f72e772d8e93be71cac9e591b2c6843a669610887dd2c89bd9eb528856e3ab47 + checksum: 8ad5236d5646d2388d2bd58a57ea53698923434f43d59ea9ebdc58bce4d0b8544c8de2f7acaa9a6d73171f04460388b2b6d7d6b6c256aea4ebb8780140781596 languageName: node linkType: hard -"jest-jasmine2@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-jasmine2@npm:27.5.1" +"jest-jasmine2@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-jasmine2@npm:26.6.3" dependencies: - "@jest/environment": ^27.5.1 - "@jest/source-map": ^27.5.1 - "@jest/test-result": ^27.5.1 - "@jest/types": ^27.5.1 + "@babel/traverse": ^7.1.0 + "@jest/environment": ^26.6.2 + "@jest/source-map": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/types": ^26.6.2 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 - expect: ^27.5.1 + expect: ^26.6.2 is-generator-fn: ^2.0.0 - jest-each: ^27.5.1 - jest-matcher-utils: ^27.5.1 - jest-message-util: ^27.5.1 - jest-runtime: ^27.5.1 - jest-snapshot: ^27.5.1 - jest-util: ^27.5.1 - pretty-format: ^27.5.1 - throat: ^6.0.1 - checksum: b716adf253ceb73db661936153394ab90d7f3a8ba56d6189b7cd4df8e4e2a4153b4e63ebb5d36e29ceb0f4c211d5a6f36ab7048c6abbd881c8646567e2ab8e6d + jest-each: ^26.6.2 + jest-matcher-utils: ^26.6.2 + jest-message-util: ^26.6.2 + jest-runtime: ^26.6.3 + jest-snapshot: ^26.6.2 + jest-util: ^26.6.2 + pretty-format: ^26.6.2 + throat: ^5.0.0 + checksum: 41df0b993ae0cdeb2660fb3d8e88e2dcc83aec6b5c27d85eb233c2d507b546f8dce45fc54898ffbefa48ccc4633f225d0e023fd0979b8f7f2f1626074a69a9a3 languageName: node linkType: hard -"jest-leak-detector@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-leak-detector@npm:27.5.1" +"jest-leak-detector@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-leak-detector@npm:26.6.2" dependencies: - jest-get-type: ^27.5.1 - pretty-format: ^27.5.1 - checksum: 5c9689060960567ddaf16c570d87afa760a461885765d2c71ef4f4857bbc3af1482c34e3cce88e50beefde1bf35e33530b020480752057a7e3dbb1ca0bae359f + jest-get-type: ^26.3.0 + pretty-format: ^26.6.2 + checksum: 364dd4d021347e26c66ba9c09da8a30477f14a3a8a208d2d7d64e4c396db81b85d8cb6b6834bcfc47a61b5938e274553957d11a7de2255f058c9d55d7f8fdfe7 languageName: node linkType: hard -"jest-matcher-utils@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-matcher-utils@npm:27.5.1" +"jest-matcher-utils@npm:^26.6.0, jest-matcher-utils@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-matcher-utils@npm:26.6.2" + dependencies: + chalk: ^4.0.0 + jest-diff: ^26.6.2 + jest-get-type: ^26.3.0 + pretty-format: ^26.6.2 + checksum: 74d2165c1ac7fe98fe27cd2b5407499478e6b2fe99dd54e26d8ee5c9f5f913bdd7bdc07c7221b9b04df0c15e9be0e866ff3455b03e38cc66c480d9996d6d5405 + languageName: node + linkType: hard + +"jest-matcher-utils@npm:^28.1.3": + version: 28.1.3 + resolution: "jest-matcher-utils@npm:28.1.3" dependencies: chalk: ^4.0.0 - jest-diff: ^27.5.1 - jest-get-type: ^27.5.1 - pretty-format: ^27.5.1 - checksum: bb2135fc48889ff3fe73888f6cc7168ddab9de28b51b3148f820c89fdfd2effdcad005f18be67d0b9be80eda208ad47290f62f03d0a33f848db2dd0273c8217a + jest-diff: ^28.1.3 + jest-get-type: ^28.0.2 + pretty-format: ^28.1.3 + checksum: 6b34f0cf66f6781e92e3bec97bf27796bd2ba31121e5c5997218d9adba6deea38a30df5203937d6785b68023ed95cbad73663cc9aad6fb0cb59aeb5813a58daf languageName: node linkType: hard @@ -13761,20 +12366,20 @@ __metadata: languageName: node linkType: hard -"jest-message-util@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-message-util@npm:27.5.1" +"jest-message-util@npm:^26.6.0, jest-message-util@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-message-util@npm:26.6.2" dependencies: - "@babel/code-frame": ^7.12.13 - "@jest/types": ^27.5.1 + "@babel/code-frame": ^7.0.0 + "@jest/types": ^26.6.2 "@types/stack-utils": ^2.0.0 chalk: ^4.0.0 - graceful-fs: ^4.2.9 - micromatch: ^4.0.4 - pretty-format: ^27.5.1 + graceful-fs: ^4.2.4 + micromatch: ^4.0.2 + pretty-format: ^26.6.2 slash: ^3.0.0 - stack-utils: ^2.0.3 - checksum: eb6d637d1411c71646de578c49826b6da8e33dd293e501967011de9d1916d53d845afbfb52a5b661ff1c495be7c13f751c48c7f30781fd94fbd64842e8195796 + stack-utils: ^2.0.2 + checksum: ffe5a715591c41240b9ed4092faf10f3eaf9ddfdf25d257a0c9f903aaa8d9eed5baa7e38016d2ec4f610fd29225e0f5231a91153e087a043e62824972c83d015 languageName: node linkType: hard @@ -13812,13 +12417,13 @@ __metadata: languageName: node linkType: hard -"jest-mock@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-mock@npm:27.5.1" +"jest-mock@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-mock@npm:26.6.2" dependencies: - "@jest/types": ^27.5.1 + "@jest/types": ^26.6.2 "@types/node": "*" - checksum: f5b5904bb1741b4a1687a5f492535b7b1758dc26534c72a5423305f8711292e96a601dec966df81bb313269fb52d47227e29f9c2e08324d79529172f67311be0 + checksum: 6c0fe028ff0cdc87b5d63b9ca749af04cae6c5577aaab234f602e546cae3f4b932adac9d77e6de2abb24955ee00978e1e5d5a861725654e2f9a42317d91fbc1f languageName: node linkType: hard @@ -13834,159 +12439,166 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-regex-util@npm:27.5.1" - checksum: d45ca7a9543616a34f7f3079337439cf07566e677a096472baa2810e274b9808b76767c97b0a4029b8a5b82b9d256dee28ef9ad4138b2b9e5933f6fac106c418 +"jest-regex-util@npm:^26.0.0": + version: 26.0.0 + resolution: "jest-regex-util@npm:26.0.0" + checksum: 930a00665e8dfbedc29140678b4a54f021b41b895cf35050f76f557c1da3ac48ff42dd7b18ba2ccba6f4e518c6445d6753730d03ec7049901b93992db1ef0483 languageName: node linkType: hard -"jest-regex-util@npm:^28.0.0": - version: 28.0.2 - resolution: "jest-regex-util@npm:28.0.2" - checksum: 0ea8c5c82ec88bc85e273c0ec82e0c0f35f7a1e2d055070e50f0cc2a2177f848eec55f73e37ae0d045c3db5014c42b2f90ac62c1ab3fdb354d2abd66a9e08add +"jest-resolve-dependencies@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-resolve-dependencies@npm:26.6.3" + dependencies: + "@jest/types": ^26.6.2 + jest-regex-util: ^26.0.0 + jest-snapshot: ^26.6.2 + checksum: 533ea1e271426006ff02c03c9802b108fcd68f2144615b6110ae59f3a0a2cc4a7abb3f44c3c65299c76b3a725d5d8220aaed9c58b79c8c8c508c18699a96e3f7 languageName: node linkType: hard -"jest-resolve-dependencies@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-resolve-dependencies@npm:27.5.1" +"jest-resolve@npm:26.6.0": + version: 26.6.0 + resolution: "jest-resolve@npm:26.6.0" dependencies: - "@jest/types": ^27.5.1 - jest-regex-util: ^27.5.1 - jest-snapshot: ^27.5.1 - checksum: c67af97afad1da88f5530317c732bbd1262d1225f6cd7f4e4740a5db48f90ab0bd8564738ac70d1a43934894f9aef62205c1b8f8ee89e5c7a737e6a121ee4c25 + "@jest/types": ^26.6.0 + chalk: ^4.0.0 + graceful-fs: ^4.2.4 + jest-pnp-resolver: ^1.2.2 + jest-util: ^26.6.0 + read-pkg-up: ^7.0.1 + resolve: ^1.17.0 + slash: ^3.0.0 + checksum: c5d0277d4aa22f9f38693ba3e5d6176edf2e367af2f0c38e16c88e9b80b2292ee4d9df9b3675607f5d0c0b2652b4e3f69d8155f9fedd83ddd0ef937cfb6230c0 languageName: node linkType: hard -"jest-resolve@npm:^27.4.2, jest-resolve@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-resolve@npm:27.5.1" +"jest-resolve@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-resolve@npm:26.6.2" dependencies: - "@jest/types": ^27.5.1 + "@jest/types": ^26.6.2 chalk: ^4.0.0 - graceful-fs: ^4.2.9 - jest-haste-map: ^27.5.1 + graceful-fs: ^4.2.4 jest-pnp-resolver: ^1.2.2 - jest-util: ^27.5.1 - jest-validate: ^27.5.1 - resolve: ^1.20.0 - resolve.exports: ^1.1.0 + jest-util: ^26.6.2 + read-pkg-up: ^7.0.1 + resolve: ^1.18.1 slash: ^3.0.0 - checksum: 735830e7265b20a348029738680bb2f6e37f80ecea86cda869a4c318ba3a45d39c7a3a873a22f7f746d86258c50ead6e7f501de043e201c095d7ba628a1c440f + checksum: d6264d3f39b098753802a237c8c54f3109f5f3b3b7fa6f8d7aec7dca01b357ddf518ce1c33a68454357c15f48fb3c6026a92b9c4f5d72f07e24e80f04bcc8d58 languageName: node linkType: hard -"jest-runner@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-runner@npm:27.5.1" +"jest-runner@npm:^26.6.0, jest-runner@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-runner@npm:26.6.3" dependencies: - "@jest/console": ^27.5.1 - "@jest/environment": ^27.5.1 - "@jest/test-result": ^27.5.1 - "@jest/transform": ^27.5.1 - "@jest/types": ^27.5.1 + "@jest/console": ^26.6.2 + "@jest/environment": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/types": ^26.6.2 "@types/node": "*" chalk: ^4.0.0 - emittery: ^0.8.1 - graceful-fs: ^4.2.9 - jest-docblock: ^27.5.1 - jest-environment-jsdom: ^27.5.1 - jest-environment-node: ^27.5.1 - jest-haste-map: ^27.5.1 - jest-leak-detector: ^27.5.1 - jest-message-util: ^27.5.1 - jest-resolve: ^27.5.1 - jest-runtime: ^27.5.1 - jest-util: ^27.5.1 - jest-worker: ^27.5.1 + emittery: ^0.7.1 + exit: ^0.1.2 + graceful-fs: ^4.2.4 + jest-config: ^26.6.3 + jest-docblock: ^26.0.0 + jest-haste-map: ^26.6.2 + jest-leak-detector: ^26.6.2 + jest-message-util: ^26.6.2 + jest-resolve: ^26.6.2 + jest-runtime: ^26.6.3 + jest-util: ^26.6.2 + jest-worker: ^26.6.2 source-map-support: ^0.5.6 - throat: ^6.0.1 - checksum: 5bbe6cf847dd322b3332ec9d6977b54f91bd5f72ff620bc1a0192f0f129deda8aa7ca74c98922187a7aa87d8e0ce4f6c50e99a7ccb2a310bf4d94be2e0c3ce8e + throat: ^5.0.0 + checksum: ccd69918baa49a5efa45985cf60cfa1fbb1686b32d7a86296b7b55f89684e36d1f08e62598c4b7be7e81f2cf2e245d1a65146ea7bdcaedfa6ed176d3e645d7e2 languageName: node linkType: hard -"jest-runtime@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-runtime@npm:27.5.1" - dependencies: - "@jest/environment": ^27.5.1 - "@jest/fake-timers": ^27.5.1 - "@jest/globals": ^27.5.1 - "@jest/source-map": ^27.5.1 - "@jest/test-result": ^27.5.1 - "@jest/transform": ^27.5.1 - "@jest/types": ^27.5.1 +"jest-runtime@npm:^26.6.0, jest-runtime@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-runtime@npm:26.6.3" + dependencies: + "@jest/console": ^26.6.2 + "@jest/environment": ^26.6.2 + "@jest/fake-timers": ^26.6.2 + "@jest/globals": ^26.6.2 + "@jest/source-map": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/transform": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/yargs": ^15.0.0 chalk: ^4.0.0 - cjs-module-lexer: ^1.0.0 + cjs-module-lexer: ^0.6.0 collect-v8-coverage: ^1.0.0 - execa: ^5.0.0 + exit: ^0.1.2 glob: ^7.1.3 - graceful-fs: ^4.2.9 - jest-haste-map: ^27.5.1 - jest-message-util: ^27.5.1 - jest-mock: ^27.5.1 - jest-regex-util: ^27.5.1 - jest-resolve: ^27.5.1 - jest-snapshot: ^27.5.1 - jest-util: ^27.5.1 + graceful-fs: ^4.2.4 + jest-config: ^26.6.3 + jest-haste-map: ^26.6.2 + jest-message-util: ^26.6.2 + jest-mock: ^26.6.2 + jest-regex-util: ^26.0.0 + jest-resolve: ^26.6.2 + jest-snapshot: ^26.6.2 + jest-util: ^26.6.2 + jest-validate: ^26.6.2 slash: ^3.0.0 strip-bom: ^4.0.0 - checksum: 929e3df0c53dab43f831f2af4e2996b22aa8cb2d6d483919d6b0426cbc100098fd5b777b998c6568b77f8c4d860b2e83127514292ff61416064f5ef926492386 + yargs: ^15.4.1 + bin: + jest-runtime: bin/jest-runtime.js + checksum: 867922b49f9ab4cf2f5f1356ac3d9962c4477c7a2ff696cc841ea4c600ea389e7d6dfcbf945fec6849e606f81980addf31e4f34d63eaa3d3415f4901de2f605a languageName: node linkType: hard -"jest-serializer@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-serializer@npm:27.5.1" +"jest-serializer@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-serializer@npm:26.6.2" dependencies: "@types/node": "*" - graceful-fs: ^4.2.9 - checksum: 803e03a552278610edc6753c0dd9fa5bb5cd3ca47414a7b2918106efb62b79fd5e9ae785d0a21f12a299fa599fea8acc1fa6dd41283328cee43962cf7df9bb44 + graceful-fs: ^4.2.4 + checksum: dbecfb0d01462fe486a0932cf1680cf6abb204c059db2a8f72c6c2a7c9842a82f6d256874112774cea700764ed8f38fc9e3db982456c138d87353e3390e746fe languageName: node linkType: hard -"jest-snapshot@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-snapshot@npm:27.5.1" +"jest-snapshot@npm:^26.6.0, jest-snapshot@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-snapshot@npm:26.6.2" dependencies: - "@babel/core": ^7.7.2 - "@babel/generator": ^7.7.2 - "@babel/plugin-syntax-typescript": ^7.7.2 - "@babel/traverse": ^7.7.2 "@babel/types": ^7.0.0 - "@jest/transform": ^27.5.1 - "@jest/types": ^27.5.1 + "@jest/types": ^26.6.2 "@types/babel__traverse": ^7.0.4 - "@types/prettier": ^2.1.5 - babel-preset-current-node-syntax: ^1.0.0 + "@types/prettier": ^2.0.0 chalk: ^4.0.0 - expect: ^27.5.1 - graceful-fs: ^4.2.9 - jest-diff: ^27.5.1 - jest-get-type: ^27.5.1 - jest-haste-map: ^27.5.1 - jest-matcher-utils: ^27.5.1 - jest-message-util: ^27.5.1 - jest-util: ^27.5.1 + expect: ^26.6.2 + graceful-fs: ^4.2.4 + jest-diff: ^26.6.2 + jest-get-type: ^26.3.0 + jest-haste-map: ^26.6.2 + jest-matcher-utils: ^26.6.2 + jest-message-util: ^26.6.2 + jest-resolve: ^26.6.2 natural-compare: ^1.4.0 - pretty-format: ^27.5.1 + pretty-format: ^26.6.2 semver: ^7.3.2 - checksum: a5cfadf0d21cd76063925d1434bc076443ed6d87847d0e248f0b245f11db3d98ff13e45cc03b15404027dabecd712d925f47b6eae4f64986f688640a7d362514 + checksum: 53f1de055b1d3840bc6e851fd674d5991b844d4695dadbd07354c93bf191048d8767b8606999847e97c4214a485b9afb45c1d2411772befa1870414ac973b3e2 languageName: node linkType: hard -"jest-util@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-util@npm:27.5.1" +"jest-util@npm:^26.1.0, jest-util@npm:^26.6.0, jest-util@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-util@npm:26.6.2" dependencies: - "@jest/types": ^27.5.1 + "@jest/types": ^26.6.2 "@types/node": "*" chalk: ^4.0.0 - ci-info: ^3.2.0 - graceful-fs: ^4.2.9 - picomatch: ^2.2.3 - checksum: ac8d122f6daf7a035dcea156641fd3701aeba245417c40836a77e35b3341b9c02ddc5d904cfcd4ddbaa00ab854da76d3b911870cafdcdbaff90ea471de26c7d7 + graceful-fs: ^4.2.4 + is-ci: ^2.0.0 + micromatch: ^4.0.2 + checksum: 3c6a5fba05c4c6892cd3a9f66196ea8867087b77a5aa1a3f6cd349c785c3f1ca24abfd454664983aed1a165cab7846688e44fe8630652d666ba326b08625bc3d languageName: node linkType: hard @@ -14018,69 +12630,63 @@ __metadata: languageName: node linkType: hard -"jest-validate@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-validate@npm:27.5.1" +"jest-validate@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-validate@npm:26.6.2" dependencies: - "@jest/types": ^27.5.1 - camelcase: ^6.2.0 + "@jest/types": ^26.6.2 + camelcase: ^6.0.0 chalk: ^4.0.0 - jest-get-type: ^27.5.1 + jest-get-type: ^26.3.0 leven: ^3.1.0 - pretty-format: ^27.5.1 - checksum: 82e870f8ee7e4fb949652711b1567f05ae31c54be346b0899e8353e5c20fad7692b511905b37966945e90af8dc0383eb41a74f3ffefb16140ea4f9164d841412 + pretty-format: ^26.6.2 + checksum: bac11d6586d9b8885328a4a66eec45b692e45ac23034a5c09eb0ee32de324f2d3d52b073e0c34e9c222b3642b083d1152a736cf24c52109e4957537d731ca62b languageName: node linkType: hard -"jest-watch-typeahead@npm:^1.0.0": - version: 1.1.0 - resolution: "jest-watch-typeahead@npm:1.1.0" +"jest-watch-typeahead@npm:0.6.1": + version: 0.6.1 + resolution: "jest-watch-typeahead@npm:0.6.1" dependencies: ansi-escapes: ^4.3.1 chalk: ^4.0.0 - jest-regex-util: ^28.0.0 - jest-watcher: ^28.0.0 - slash: ^4.0.0 - string-length: ^5.0.1 - strip-ansi: ^7.0.1 + jest-regex-util: ^26.0.0 + jest-watcher: ^26.3.0 + slash: ^3.0.0 + string-length: ^4.0.1 + strip-ansi: ^6.0.0 peerDependencies: - jest: ^27.0.0 || ^28.0.0 - checksum: 59b0a494ac01e3801c9ec586de3209153eedb024b981e25443111c5703711d23b67ebc71b072986c1758307e0bfb5bf1c92bd323f73f58602d6f4f609dce6a0c + jest: ^26.0.0 + checksum: a65dfd080e68b79ce7c861ec07791a0768820049a1d6a471d01f3fc41ee88723db29b434e19c917421e7f34ec567bcade368f3671e234c557288e206f7fd4257 languageName: node linkType: hard -"jest-watcher@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-watcher@npm:27.5.1" +"jest-watcher@npm:^26.3.0, jest-watcher@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-watcher@npm:26.6.2" dependencies: - "@jest/test-result": ^27.5.1 - "@jest/types": ^27.5.1 + "@jest/test-result": ^26.6.2 + "@jest/types": ^26.6.2 "@types/node": "*" ansi-escapes: ^4.2.1 chalk: ^4.0.0 - jest-util: ^27.5.1 + jest-util: ^26.6.2 string-length: ^4.0.1 - checksum: 191c4e9c278c0902ade1a8a80883ac244963ba3e6e78607a3d5f729ccca9c6e71fb3b316f87883658132641c5d818aa84202585c76752e03c539e6cbecb820bd + checksum: 401137f1a73bf23cdf390019ebffb3f6f89c53ca49d48252d1dd6daf17a68787fef75cc55a623de28b63d87d0e8f13d8972d7dd06740f2f64f7b2a0409d119d2 languageName: node linkType: hard -"jest-watcher@npm:^28.0.0": - version: 28.1.3 - resolution: "jest-watcher@npm:28.1.3" +"jest-worker@npm:^24.9.0": + version: 24.9.0 + resolution: "jest-worker@npm:24.9.0" dependencies: - "@jest/test-result": ^28.1.3 - "@jest/types": ^28.1.3 - "@types/node": "*" - ansi-escapes: ^4.2.1 - chalk: ^4.0.0 - emittery: ^0.10.2 - jest-util: ^28.1.3 - string-length: ^4.0.1 - checksum: 8f6d674a4865e7df251f71544f1b51f06fd36b5a3a61f2ac81aeb81fa2a196be354fba51d0f97911c88f67cd254583b3a22ee124bf2c5b6ee2fadec27356c207 + merge-stream: ^2.0.0 + supports-color: ^6.1.0 + checksum: bd23b6c8728dcf3bad0d84543ea1bc4a95ccd3b5a40f9e2796d527ab0e87dc6afa6c30cc7b67845dce1cfe7894753812d19793de605db1976b7ac08930671bff languageName: node linkType: hard -"jest-worker@npm:^26.2.1": +"jest-worker@npm:^26.5.0, jest-worker@npm:^26.6.2": version: 26.6.2 resolution: "jest-worker@npm:26.6.2" dependencies: @@ -14091,7 +12697,7 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^27.0.2, jest-worker@npm:^27.4.5, jest-worker@npm:^27.5.1": +"jest-worker@npm:^27.5.1": version: 27.5.1 resolution: "jest-worker@npm:27.5.1" dependencies: @@ -14102,41 +12708,16 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^28.0.2": - version: 28.1.3 - resolution: "jest-worker@npm:28.1.3" - dependencies: - "@types/node": "*" - merge-stream: ^2.0.0 - supports-color: ^8.0.0 - checksum: e921c9a1b8f0909da9ea07dbf3592f95b653aef3a8bb0cbcd20fc7f9a795a1304adecac31eecb308992c167e8d7e75c522061fec38a5928ace0f9571c90169ca - languageName: node - linkType: hard - -"jest@npm:^27.4.3": - version: 27.5.1 - resolution: "jest@npm:27.5.1" +"jest@npm:26.6.0": + version: 26.6.0 + resolution: "jest@npm:26.6.0" dependencies: - "@jest/core": ^27.5.1 + "@jest/core": ^26.6.0 import-local: ^3.0.2 - jest-cli: ^27.5.1 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest-cli: ^26.6.0 bin: jest: bin/jest.js - checksum: 96f1d69042b3c6dfc695f2a4e4b0db38af6fb78582ad1a02beaa57cfcd77cbd31567d7d865c1c85709b7c3e176eefa3b2035ffecd646005f15d8ef528eccf205 - languageName: node - linkType: hard - -"jiti@npm:^1.21.6": - version: 1.21.7 - resolution: "jiti@npm:1.21.7" - bin: - jiti: bin/jiti.js - checksum: 9cd20dabf82e3a4cceecb746a69381da7acda93d34eed0cdb9c9bdff3bce07e4f2f4a016ca89924392c935297d9aedc58ff9f7d3281bc5293319ad244926e0b7 + checksum: e0d3efff0dc2a31c453a3f7d87586e5d6c0f008c9b827bb9204edde09288f922ddfb3a8917480bf68f4ac0298be28637daef98ebaaac65ea23d3cb754a6620c4 languageName: node linkType: hard @@ -14147,6 +12728,13 @@ __metadata: languageName: node linkType: hard +"js-levenshtein@npm:^1.1.6": + version: 1.1.6 + resolution: "js-levenshtein@npm:1.1.6" + checksum: 409f052a7f1141be4058d97da7860e08efd97fc588b7a4c5cfa0548bc04f6d576644dae65ab630266dff685d56fb90d494e03d4d79cb484c287746b4f1bf0694 + languageName: node + linkType: hard + "js-sha3@npm:0.8.0": version: 0.8.0 resolution: "js-sha3@npm:0.8.0" @@ -14161,13 +12749,6 @@ __metadata: languageName: node linkType: hard -"js-tokens@npm:^9.0.1": - version: 9.0.1 - resolution: "js-tokens@npm:9.0.1" - checksum: 8b604020b1a550e575404bfdde4d12c11a7991ffe0c58a2cf3515b9a512992dc7010af788f0d8b7485e403d462d9e3d3b96c4ff03201550fdbb09e17c811e054 - languageName: node - linkType: hard - "js-yaml@npm:^3.13.1": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" @@ -14180,18 +12761,14 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^4.1.0": - version: 4.1.0 - resolution: "js-yaml@npm:4.1.0" - dependencies: - argparse: ^2.0.1 - bin: - js-yaml: bin/js-yaml.js - checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 944f924f2bd67ad533b3850eee47603eed0f6ae425fd1ee8c760f477e8c34a05f144c1bd4f5a5dd1963141dc79a2c55f89ccc5ab77d039e7077f3ad196b64965 languageName: node linkType: hard -"jsdom@npm:^16.6.0": +"jsdom@npm:^16.4.0": version: 16.7.0 resolution: "jsdom@npm:16.7.0" dependencies: @@ -14231,21 +12808,21 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^3.0.2": - version: 3.1.0 - resolution: "jsesc@npm:3.1.0" +"jsesc@npm:^2.5.1": + version: 2.5.2 + resolution: "jsesc@npm:2.5.2" bin: jsesc: bin/jsesc - checksum: 19c94095ea026725540c0d29da33ab03144f6bcf2d4159e4833d534976e99e0c09c38cefa9a575279a51fc36b31166f8d6d05c9fe2645d5f15851d690b41f17f + checksum: 4dc190771129e12023f729ce20e1e0bfceac84d73a85bc3119f7f938843fe25a4aeccb54b6494dce26fcf263d815f5f31acdefac7cc9329efb8422a4f4d9fa9d languageName: node linkType: hard -"jsesc@npm:~3.0.2": - version: 3.0.2 - resolution: "jsesc@npm:3.0.2" +"jsesc@npm:~0.5.0": + version: 0.5.0 + resolution: "jsesc@npm:0.5.0" bin: jsesc: bin/jsesc - checksum: a36d3ca40574a974d9c2063bf68c2b6141c20da8f2a36bd3279fc802563f35f0527a6c828801295bdfb2803952cf2cf387786c2c90ed564f88d5782475abfe3c + checksum: b8b44cbfc92f198ad972fba706ee6a1dfa7485321ee8c0b25f5cedd538dcb20cde3197de16a7265430fce8277a12db066219369e3d51055038946039f6e20e17 languageName: node linkType: hard @@ -14265,7 +12842,14 @@ __metadata: languageName: node linkType: hard -"json-parse-even-better-errors@npm:^2.3.0, json-parse-even-better-errors@npm:^2.3.1": +"json-parse-better-errors@npm:^1.0.1, json-parse-better-errors@npm:^1.0.2": + version: 1.0.2 + resolution: "json-parse-better-errors@npm:1.0.2" + checksum: ff2b5ba2a70e88fd97a3cb28c1840144c5ce8fae9cbeeddba15afa333a5c407cf0e42300cd0a2885dbb055227fe68d405070faad941beeffbfde9cf3b2c78c5d + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^2.3.0": version: 2.3.1 resolution: "json-parse-even-better-errors@npm:2.3.1" checksum: 798ed4cf3354a2d9ccd78e86d2169515a0097a5c133337807cdf7f1fc32e1391d207ccfc276518cc1d7d8d4db93288b8a50ba4293d212ad1336e52a8ec0a941f @@ -14286,13 +12870,6 @@ __metadata: languageName: node linkType: hard -"json-schema@npm:^0.4.0": - version: 0.4.0 - resolution: "json-schema@npm:0.4.0" - checksum: 66389434c3469e698da0df2e7ac5a3281bcff75e797a5c127db7c5b56270e01ae13d9afa3c03344f76e32e81678337a8c912bdbb75101c62e487dc3778461d72 - languageName: node - linkType: hard - "json-stable-stringify-without-jsonify@npm:^1.0.1": version: 1.0.1 resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" @@ -14300,7 +12877,16 @@ __metadata: languageName: node linkType: hard -"json5@npm:^1.0.2": +"json5@npm:2.x, json5@npm:^2.1.2, json5@npm:^2.2.3": + version: 2.2.3 + resolution: "json5@npm:2.2.3" + bin: + json5: lib/cli.js + checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349 + languageName: node + linkType: hard + +"json5@npm:^1.0.1, json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" dependencies: @@ -14311,25 +12897,28 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.1.2, json5@npm:^2.2.0, json5@npm:^2.2.3": - version: 2.2.3 - resolution: "json5@npm:2.2.3" - bin: - json5: lib/cli.js - checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349 +"jsonfile@npm:^4.0.0": + version: 4.0.0 + resolution: "jsonfile@npm:4.0.0" + dependencies: + graceful-fs: ^4.1.6 + dependenciesMeta: + graceful-fs: + optional: true + checksum: 6447d6224f0d31623eef9b51185af03ac328a7553efcee30fa423d98a9e276ca08db87d71e17f2310b0263fd3ffa6c2a90a6308367f661dc21580f9469897c9e languageName: node linkType: hard "jsonfile@npm:^6.0.1": - version: 6.2.0 - resolution: "jsonfile@npm:6.2.0" + version: 6.1.0 + resolution: "jsonfile@npm:6.1.0" dependencies: graceful-fs: ^4.1.6 universalify: ^2.0.0 dependenciesMeta: graceful-fs: optional: true - checksum: c3028ec5c770bb41290c9bb9ca04bdd0a1b698ddbdf6517c9453d3f90fc9e000c9675959fb46891d317690a93c62de03ff1735d8dbe02be83e51168ce85815d3 + checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354 languageName: node linkType: hard @@ -14344,13 +12933,6 @@ __metadata: languageName: node linkType: hard -"jsonpointer@npm:^5.0.0": - version: 5.0.1 - resolution: "jsonpointer@npm:5.0.1" - checksum: 0b40f712900ad0c846681ea2db23b6684b9d5eedf55807b4708c656f5894b63507d0e28ae10aa1bddbea551241035afe62b6df0800fc94c2e2806a7f3adecd7c - languageName: node - linkType: hard - "jsonwebtoken@npm:^8.5.1": version: 8.5.1 resolution: "jsonwebtoken@npm:8.5.1" @@ -14369,24 +12951,6 @@ __metadata: languageName: node linkType: hard -"jsonwebtoken@npm:^9.0.2": - version: 9.0.2 - resolution: "jsonwebtoken@npm:9.0.2" - dependencies: - jws: ^3.2.2 - lodash.includes: ^4.3.0 - lodash.isboolean: ^3.0.3 - lodash.isinteger: ^4.0.4 - lodash.isnumber: ^3.0.3 - lodash.isplainobject: ^4.0.6 - lodash.isstring: ^4.0.1 - lodash.once: ^4.0.0 - ms: ^2.1.1 - semver: ^7.5.4 - checksum: fc739a6a8b33f1974f9772dca7f8493ca8df4cc31c5a09dcfdb7cff77447dcf22f4236fb2774ef3fe50df0abeb8e1c6f4c41eba82f500a804ab101e2fbc9d61a - languageName: node - linkType: hard - "jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" @@ -14400,24 +12964,24 @@ __metadata: linkType: hard "jwa@npm:^1.4.1": - version: 1.4.2 - resolution: "jwa@npm:1.4.2" + version: 1.4.1 + resolution: "jwa@npm:1.4.1" dependencies: - buffer-equal-constant-time: ^1.0.1 + buffer-equal-constant-time: 1.0.1 ecdsa-sig-formatter: 1.0.11 safe-buffer: ^5.0.1 - checksum: fd1a6de6c649a4b16f0775439ac9173e4bc9aa0162c7f3836699af47736ae000fafe89f232a2345170de6c14021029cb94b488f7882c6caf61e6afef5fce6494 + checksum: ff30ea7c2dcc61f3ed2098d868bf89d43701605090c5b21b5544b512843ec6fd9e028381a4dda466cbcdb885c2d1150f7c62e7168394ee07941b4098e1035e2f languageName: node linkType: hard "jwa@npm:^2.0.0": - version: 2.0.1 - resolution: "jwa@npm:2.0.1" + version: 2.0.0 + resolution: "jwa@npm:2.0.0" dependencies: - buffer-equal-constant-time: ^1.0.1 + buffer-equal-constant-time: 1.0.1 ecdsa-sig-formatter: 1.0.11 safe-buffer: ^5.0.1 - checksum: 6a9828c054c407f6718057089bd3d46dfcb1394e1553e3867abd4579dbec7728b4b0759e7253422ab7d824d95615a86427b35c43f94b83fc3a76470ca4bd2037 + checksum: 8f00b71ad5fe94cb55006d0d19202f8f56889109caada2f7eeb63ca81755769ce87f4f48101967f398462e3b8ae4faebfbd5a0269cb755dead5d63c77ba4d2f1 languageName: node linkType: hard @@ -14450,6 +13014,31 @@ __metadata: languageName: node linkType: hard +"killable@npm:^1.0.1": + version: 1.0.1 + resolution: "killable@npm:1.0.1" + checksum: 911a85c6e390c19d72c4e3149347cf44042cbd7d18c3c6c5e4f706fdde6e0ed532473392e282c7ef27f518407e6cb7d2a0e71a2ae8d8d8f8ffdb68891a29a68a + languageName: node + linkType: hard + +"kind-of@npm:^3.0.2, kind-of@npm:^3.0.3, kind-of@npm:^3.2.0": + version: 3.2.2 + resolution: "kind-of@npm:3.2.2" + dependencies: + is-buffer: ^1.1.5 + checksum: e898df8ca2f31038f27d24f0b8080da7be274f986bc6ed176f37c77c454d76627619e1681f6f9d2e8d2fd7557a18ecc419a6bb54e422abcbb8da8f1a75e4b386 + languageName: node + linkType: hard + +"kind-of@npm:^4.0.0": + version: 4.0.0 + resolution: "kind-of@npm:4.0.0" + dependencies: + is-buffer: ^1.1.5 + checksum: 1b9e7624a8771b5a2489026e820f3bbbcc67893e1345804a56b23a91e9069965854d2a223a7c6ee563c45be9d8c6ff1ef87f28ed5f0d1a8d00d9dcbb067c529f + languageName: node + linkType: hard + "kind-of@npm:^6.0.2": version: 6.0.3 resolution: "kind-of@npm:6.0.3" @@ -14464,7 +13053,7 @@ __metadata: languageName: node linkType: hard -"klona@npm:^2.0.4, klona@npm:^2.0.5": +"klona@npm:^2.0.4": version: 2.0.6 resolution: "klona@npm:2.0.6" checksum: ac9ee3732e42b96feb67faae4d27cf49494e8a3bf3fa7115ce242fe04786788e0aff4741a07a45a2462e2079aa983d73d38519c85d65b70ef11447bbc3c58ce7 @@ -14472,9 +13061,9 @@ __metadata: linkType: hard "language-subtag-registry@npm:^0.3.20": - version: 0.3.23 - resolution: "language-subtag-registry@npm:0.3.23" - checksum: 0b64c1a6c5431c8df648a6d25594ff280613c886f4a1a542d9b864e5472fb93e5c7856b9c41595c38fac31370328fc79fcc521712e89ea6d6866cbb8e0995d81 + version: 0.3.22 + resolution: "language-subtag-registry@npm:0.3.22" + checksum: 8ab70a7e0e055fe977ac16ea4c261faec7205ac43db5e806f72e5b59606939a3b972c4bd1e10e323b35d6ffa97c3e1c4c99f6553069dad2dfdd22020fa3eb56a languageName: node linkType: hard @@ -14487,13 +13076,13 @@ __metadata: languageName: node linkType: hard -"launch-editor@npm:^2.6.0": - version: 2.11.1 - resolution: "launch-editor@npm:2.11.1" +"last-call-webpack-plugin@npm:^3.0.0": + version: 3.0.0 + resolution: "last-call-webpack-plugin@npm:3.0.0" dependencies: - picocolors: ^1.1.1 - shell-quote: ^1.8.3 - checksum: 95a2e0a50ce15425a87fd035bdef2de37e13c2aee9cd62756783efb286a6e36a341cfcbaecb0d578131a5411c6a1c74c422f9c5b6cb6f4c8284d6078967e08b4 + lodash: ^4.17.5 + webpack-sources: ^1.1.0 + checksum: 23c25a2397c9f75b769b5238ab798873e857baf2363d471d186c9f05212457943f0de16181f33aeecbfd42116b72a0f343fe8910d5d8010f24956d95d536c743 languageName: node linkType: hard @@ -14524,20 +13113,6 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:^2.0.3": - version: 2.1.0 - resolution: "lilconfig@npm:2.1.0" - checksum: 8549bb352b8192375fed4a74694cd61ad293904eee33f9d4866c2192865c44c4eb35d10782966242634e0cbc1e91fe62b1247f148dc5514918e3a966da7ea117 - languageName: node - linkType: hard - -"lilconfig@npm:^3.0.0, lilconfig@npm:^3.1.3": - version: 3.1.3 - resolution: "lilconfig@npm:3.1.3" - checksum: 644eb10830350f9cdc88610f71a921f510574ed02424b57b0b3abb66ea725d7a082559552524a842f4e0272c196b88dfe1ff7d35ffcc6f45736777185cd67c9a - languageName: node - linkType: hard - "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" @@ -14545,21 +13120,43 @@ __metadata: languageName: node linkType: hard -"load-tsconfig@npm:^0.2.3": +"load-tsconfig@npm:^0.2.0": version: 0.2.5 resolution: "load-tsconfig@npm:0.2.5" checksum: 631740833c4a7157bb7b6eeae6e1afb6a6fac7416b7ba91bd0944d5c5198270af2d68bf8347af3cc2ba821adc4d83ef98f66278bd263bc284c863a09ec441503 languageName: node linkType: hard -"loader-runner@npm:^4.2.0": - version: 4.3.0 - resolution: "loader-runner@npm:4.3.0" - checksum: a90e00dee9a16be118ea43fec3192d0b491fe03a32ed48a4132eb61d498f5536a03a1315531c19d284392a8726a4ecad71d82044c28d7f22ef62e029bf761569 +"loader-runner@npm:^2.4.0": + version: 2.4.0 + resolution: "loader-runner@npm:2.4.0" + checksum: e27eebbca5347a03f6b1d1bce5b2736a4984fb742f872c0a4d68e62de10f7637613e79a464d3bcd77c246d9c70fcac112bb4a3123010eb527e8b203a614647db + languageName: node + linkType: hard + +"loader-utils@npm:2.0.0": + version: 2.0.0 + resolution: "loader-utils@npm:2.0.0" + dependencies: + big.js: ^5.2.2 + emojis-list: ^3.0.0 + json5: ^2.1.2 + checksum: 6856423131b50b6f5f259da36f498cfd7fc3c3f8bb17777cf87fdd9159e797d4ba4288d9a96415fd8da62c2906960e88f74711dee72d03a9003bddcd0d364a51 + languageName: node + linkType: hard + +"loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3, loader-utils@npm:^1.4.0": + version: 1.4.2 + resolution: "loader-utils@npm:1.4.2" + dependencies: + big.js: ^5.2.2 + emojis-list: ^3.0.0 + json5: ^1.0.1 + checksum: eb6fb622efc0ffd1abdf68a2022f9eac62bef8ec599cf8adb75e94d1d338381780be6278534170e99edc03380a6d29bc7eb1563c89ce17c5fed3a0b17f1ad804 languageName: node linkType: hard -"loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.4": +"loader-utils@npm:^2.0.0": version: 2.0.4 resolution: "loader-utils@npm:2.0.4" dependencies: @@ -14570,10 +13167,10 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^3.2.0": - version: 3.3.1 - resolution: "loader-utils@npm:3.3.1" - checksum: d35808e081635e5bc50228a52ed79f83e2c82bd8f7578818c12b1b4cf0b7f409d72d9b93a683ec36b9eaa93346693d3f3c8380183ba2ff81599b0829d685de39 +"local-pkg@npm:^0.4.3": + version: 0.4.3 + resolution: "local-pkg@npm:0.4.3" + checksum: 7825aca531dd6afa3a3712a0208697aa4a5cd009065f32e3fb732aafcc42ed11f277b5ac67229222e96f4def55197171cdf3d5522d0381b489d2e5547b407d55 languageName: node linkType: hard @@ -14596,19 +13193,17 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^6.0.0": - version: 6.0.0 - resolution: "locate-path@npm:6.0.0" - dependencies: - p-locate: ^5.0.0 - checksum: 72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a +"lodash-es@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash-es@npm:4.17.21" + checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2 languageName: node linkType: hard -"lodash.camelcase@npm:^4.3.0": - version: 4.3.0 - resolution: "lodash.camelcase@npm:4.3.0" - checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1 +"lodash._reinterpolate@npm:^3.0.0": + version: 3.0.0 + resolution: "lodash._reinterpolate@npm:3.0.0" + checksum: 06d2d5f33169604fa5e9f27b6067ed9fb85d51a84202a656901e5ffb63b426781a601508466f039c720af111b0c685d12f1a5c14ff8df5d5f27e491e562784b2 languageName: node linkType: hard @@ -14689,10 +13284,22 @@ __metadata: languageName: node linkType: hard -"lodash.sortby@npm:^4.7.0": - version: 4.7.0 - resolution: "lodash.sortby@npm:4.7.0" - checksum: db170c9396d29d11fe9a9f25668c4993e0c1331bcb941ddbd48fb76f492e732add7f2a47cfdf8e9d740fa59ac41bbfaf931d268bc72aab3ab49e9f89354d718c +"lodash.template@npm:^4.5.0": + version: 4.5.0 + resolution: "lodash.template@npm:4.5.0" + dependencies: + lodash._reinterpolate: ^3.0.0 + lodash.templatesettings: ^4.0.0 + checksum: ca64e5f07b6646c9d3dbc0fe3aaa995cb227c4918abd1cef7a9024cd9c924f2fa389a0ec4296aa6634667e029bc81d4bbdb8efbfde11df76d66085e6c529b450 + languageName: node + linkType: hard + +"lodash.templatesettings@npm:^4.0.0": + version: 4.2.0 + resolution: "lodash.templatesettings@npm:4.2.0" + dependencies: + lodash._reinterpolate: ^3.0.0 + checksum: 863e025478b092997e11a04e9d9e735875eeff1ffcd6c61742aa8272e3c2cddc89ce795eb9726c4e74cef5991f722897ff37df7738a125895f23fc7d12a7bb59 languageName: node linkType: hard @@ -14710,21 +13317,31 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.7.0": +"lodash@npm:4.x, lodash@npm:>=3.5 <5, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.5, lodash@npm:^4.7.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 languageName: node linkType: hard -"longest-streak@npm:^3.0.0": - version: 3.1.0 - resolution: "longest-streak@npm:3.1.0" - checksum: d7f952ed004cbdb5c8bcfc4f7f5c3d65449e6c5a9e9be4505a656e3df5a57ee125f284286b4bf8ecea0c21a7b3bf2b8f9001ad506c319b9815ad6a63a47d0fd0 +"log-symbols@npm:^4.1.0": + version: 4.1.0 + resolution: "log-symbols@npm:4.1.0" + dependencies: + chalk: ^4.1.0 + is-unicode-supported: ^0.1.0 + checksum: fce1497b3135a0198803f9f07464165e9eb83ed02ceb2273930a6f8a508951178d8cf4f0378e9d28300a2ed2bc49050995d2bd5f53ab716bb15ac84d58c6ef74 + languageName: node + linkType: hard + +"loglevel@npm:^1.6.8": + version: 1.9.1 + resolution: "loglevel@npm:1.9.1" + checksum: e1c8586108c4d566122e91f8a79c8df728920e3a714875affa5120566761a24077ec8ec9e5fc388b022e39fc411ec6e090cde1b5775871241b045139771eeb06 languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -14735,10 +13352,12 @@ __metadata: languageName: node linkType: hard -"loupe@npm:^3.1.0, loupe@npm:^3.1.2, loupe@npm:^3.1.4": - version: 3.2.1 - resolution: "loupe@npm:3.2.1" - checksum: 3ce9ecc5b2c56ffc073bf065ad3a4644cccce3eac81e61a8732e9c8ebfe05513ed478592d25f9dba24cfe82766913be045ab384c04711c7c6447deaf800ad94c +"loupe@npm:^2.3.6": + version: 2.3.7 + resolution: "loupe@npm:2.3.7" + dependencies: + get-func-name: ^2.0.1 + checksum: 96c058ec7167598e238bb7fb9def2f9339215e97d6685d9c1e3e4bdb33d14600e11fe7a812cf0c003dfb73ca2df374f146280b2287cae9e8d989e9d7a69a203b languageName: node linkType: hard @@ -14752,16 +13371,9 @@ __metadata: linkType: hard "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": - version: 10.4.3 - resolution: "lru-cache@npm:10.4.3" - checksum: 6476138d2125387a6d20f100608c2583d415a4f64a0fecf30c9e2dda976614f09cad4baa0842447bd37dd459a7bd27f57d9d8f8ce558805abd487c583f3d774a - languageName: node - linkType: hard - -"lru-cache@npm:^11.0.0": - version: 11.2.1 - resolution: "lru-cache@npm:11.2.1" - checksum: d54584b6f03e6de64c9e9f01e48abce5a9bc04318874d5204cee9e4275719544624d51eea6a167672576794af8bba3a7cfc23455d28b270a278cc387d1965131 + version: 10.2.0 + resolution: "lru-cache@npm:10.2.0" + checksum: eee7ddda4a7475deac51ac81d7dd78709095c6fa46e8350dc2d22462559a1faa3b81ed931d5464b13d48cbd7e08b46100b6f768c76833912bc444b99c37e25db languageName: node linkType: hard @@ -14783,7 +13395,7 @@ __metadata: languageName: node linkType: hard -"lz-string@npm:^1.5.0": +"lz-string@npm:^1.4.4, lz-string@npm:^1.5.0": version: 1.5.0 resolution: "lz-string@npm:1.5.0" bin: @@ -14801,23 +13413,26 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.12, magic-string@npm:^0.30.17": - version: 0.30.19 - resolution: "magic-string@npm:0.30.19" +"magic-string@npm:^0.30.0": + version: 0.30.10 + resolution: "magic-string@npm:0.30.10" dependencies: - "@jridgewell/sourcemap-codec": ^1.5.5 - checksum: f360b87febeceddb35238e55963b70ef68381688c1aada6d842833a7be440a08cb0a8776e23b5e4e34785edc6b42b92dc08c829f43ecdb58547122f3fd79fdc7 + "@jridgewell/sourcemap-codec": ^1.4.15 + checksum: 456fd47c39b296c47dff967e1965121ace35417eab7f45a99e681e725b8661b48e1573c366ee67a27715025b3740773c46b088f115421c7365ea4ea6fa10d399 languageName: node linkType: hard -"make-cancellable-promise@npm:^1.3.1": - version: 1.3.2 - resolution: "make-cancellable-promise@npm:1.3.2" - checksum: d4dcad8211272a4d6ef979747a3d7085cdefb92cf50e096ab6a3ea8295e7578b82edaac261c7c4e3d656eadfac285f05b98856b3cf1fd14390ec2708328a9b35 +"make-dir@npm:^2.0.0": + version: 2.1.0 + resolution: "make-dir@npm:2.1.0" + dependencies: + pify: ^4.0.1 + semver: ^5.6.0 + checksum: 043548886bfaf1820323c6a2997e6d2fa51ccc2586ac14e6f14634f7458b4db2daf15f8c310e2a0abd3e0cddc64df1890d8fc7263033602c47bb12cbfcf86aab languageName: node linkType: hard -"make-dir@npm:^3.0.2, make-dir@npm:^3.1.0": +"make-dir@npm:^3.0.2": version: 3.1.0 resolution: "make-dir@npm:3.1.0" dependencies: @@ -14835,520 +13450,244 @@ __metadata: languageName: node linkType: hard -"make-error@npm:^1.1.1": +"make-error@npm:1.x, make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" checksum: b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 languageName: node linkType: hard -"make-event-props@npm:^1.6.0": - version: 1.6.2 - resolution: "make-event-props@npm:1.6.2" - checksum: ded823d8b73926d94513416c75585be2cea9d9408b085eed31c20a1005147661a50852f869e1779990ddd04c8e07e1f24c766453cc9b4870bcef8d79c533a5fc - languageName: node - linkType: hard - -"make-fetch-happen@npm:^14.0.3": - version: 14.0.3 - resolution: "make-fetch-happen@npm:14.0.3" +"make-fetch-happen@npm:^13.0.0": + version: 13.0.0 + resolution: "make-fetch-happen@npm:13.0.0" dependencies: - "@npmcli/agent": ^3.0.0 - cacache: ^19.0.1 + "@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: ^4.0.0 + minipass-fetch: ^3.0.0 minipass-flush: ^1.0.5 minipass-pipeline: ^1.2.4 - negotiator: ^1.0.0 - proc-log: ^5.0.0 + negotiator: ^0.6.3 promise-retry: ^2.0.1 - ssri: ^12.0.0 - checksum: 6fb2fee6da3d98f1953b03d315826b5c5a4ea1f908481afc113782d8027e19f080c85ae998454de4e5f27a681d3ec58d57278f0868d4e0b736f51d396b661691 - languageName: node - linkType: hard - -"makeerror@npm:1.0.12": - version: 1.0.12 - resolution: "makeerror@npm:1.0.12" - dependencies: - tmpl: 1.0.5 - checksum: b38a025a12c8146d6eeea5a7f2bf27d51d8ad6064da8ca9405fcf7bf9b54acd43e3b30ddd7abb9b1bfa4ddb266019133313482570ddb207de568f71ecfcf6060 - languageName: node - linkType: hard - -"match-sorter@npm:^6.0.2": - version: 6.3.4 - resolution: "match-sorter@npm:6.3.4" - dependencies: - "@babel/runtime": ^7.23.8 - remove-accents: 0.5.0 - checksum: 950c1600173a639e216947559a389b64258d52f33aea3a6ddb97500589888b83c976a028f731f40bc08d9d8af20de7916992fabb403f38330183a1df44c7634b - languageName: node - linkType: hard - -"math-intrinsics@npm:^1.1.0": - version: 1.1.0 - resolution: "math-intrinsics@npm:1.1.0" - checksum: 0e513b29d120f478c85a70f49da0b8b19bc638975eca466f2eeae0071f3ad00454c621bf66e16dd435896c208e719fc91ad79bbfba4e400fe0b372e7c1c9c9a2 - languageName: node - linkType: hard - -"mdast-util-from-markdown@npm:^2.0.0": - version: 2.0.2 - resolution: "mdast-util-from-markdown@npm:2.0.2" - dependencies: - "@types/mdast": ^4.0.0 - "@types/unist": ^3.0.0 - decode-named-character-reference: ^1.0.0 - devlop: ^1.0.0 - mdast-util-to-string: ^4.0.0 - micromark: ^4.0.0 - micromark-util-decode-numeric-character-reference: ^2.0.0 - micromark-util-decode-string: ^2.0.0 - micromark-util-normalize-identifier: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - unist-util-stringify-position: ^4.0.0 - checksum: 1ad19f48b30ac6e0cb756070c210c78ad93c26876edfb3f75127783bc6df8b9402016d8f3e9964f3d1d5430503138ec65c145e869438727e1aa7f3cebf228fba - languageName: node - linkType: hard - -"mdast-util-mdx-expression@npm:^2.0.0": - version: 2.0.1 - resolution: "mdast-util-mdx-expression@npm:2.0.1" - dependencies: - "@types/estree-jsx": ^1.0.0 - "@types/hast": ^3.0.0 - "@types/mdast": ^4.0.0 - devlop: ^1.0.0 - mdast-util-from-markdown: ^2.0.0 - mdast-util-to-markdown: ^2.0.0 - checksum: 6af56b06bde3ab971129db9855dcf0d31806c70b3b052d7a90a5499a366b57ffd0c2efca67d281c448c557298ba7e3e61bd07133733b735440840dd339b28e19 - languageName: node - linkType: hard - -"mdast-util-mdx-jsx@npm:^3.0.0": - version: 3.2.0 - resolution: "mdast-util-mdx-jsx@npm:3.2.0" - dependencies: - "@types/estree-jsx": ^1.0.0 - "@types/hast": ^3.0.0 - "@types/mdast": ^4.0.0 - "@types/unist": ^3.0.0 - ccount: ^2.0.0 - devlop: ^1.1.0 - mdast-util-from-markdown: ^2.0.0 - mdast-util-to-markdown: ^2.0.0 - parse-entities: ^4.0.0 - stringify-entities: ^4.0.0 - unist-util-stringify-position: ^4.0.0 - vfile-message: ^4.0.0 - checksum: 224f5f6ad247f0f2622ee36c82ac7a4c6a60c31850de4056bf95f531bd2f7ec8943ef34dfe8a8375851f65c07e4913c4f33045d703df4ff4d11b2de5a088f7f9 - languageName: node - linkType: hard - -"mdast-util-mdxjs-esm@npm:^2.0.0": - version: 2.0.1 - resolution: "mdast-util-mdxjs-esm@npm:2.0.1" - dependencies: - "@types/estree-jsx": ^1.0.0 - "@types/hast": ^3.0.0 - "@types/mdast": ^4.0.0 - devlop: ^1.0.0 - mdast-util-from-markdown: ^2.0.0 - mdast-util-to-markdown: ^2.0.0 - checksum: 1f9dad04d31d59005332e9157ea9510dc1d03092aadbc607a10475c7eec1c158b475aa0601a3a4f74e13097ca735deb8c2d9d37928ddef25d3029fd7c9e14dc3 - languageName: node - linkType: hard - -"mdast-util-phrasing@npm:^4.0.0": - version: 4.1.0 - resolution: "mdast-util-phrasing@npm:4.1.0" - dependencies: - "@types/mdast": ^4.0.0 - unist-util-is: ^6.0.0 - checksum: 3a97533e8ad104a422f8bebb34b3dde4f17167b8ed3a721cf9263c7416bd3447d2364e6d012a594aada40cac9e949db28a060bb71a982231693609034ed5324e - languageName: node - linkType: hard - -"mdast-util-to-hast@npm:^13.0.0": - version: 13.2.0 - resolution: "mdast-util-to-hast@npm:13.2.0" - dependencies: - "@types/hast": ^3.0.0 - "@types/mdast": ^4.0.0 - "@ungap/structured-clone": ^1.0.0 - devlop: ^1.0.0 - micromark-util-sanitize-uri: ^2.0.0 - trim-lines: ^3.0.0 - unist-util-position: ^5.0.0 - unist-util-visit: ^5.0.0 - vfile: ^6.0.0 - checksum: 7e5231ff3d4e35e1421908437577fd5098141f64918ff5cc8a0f7a8a76c5407f7a3ee88d75f7a1f7afb763989c9f357475fa0ba8296c00aaff1e940098fe86a6 - languageName: node - linkType: hard - -"mdast-util-to-markdown@npm:^2.0.0": - version: 2.1.2 - resolution: "mdast-util-to-markdown@npm:2.1.2" - dependencies: - "@types/mdast": ^4.0.0 - "@types/unist": ^3.0.0 - longest-streak: ^3.0.0 - mdast-util-phrasing: ^4.0.0 - mdast-util-to-string: ^4.0.0 - micromark-util-classify-character: ^2.0.0 - micromark-util-decode-string: ^2.0.0 - unist-util-visit: ^5.0.0 - zwitch: ^2.0.0 - checksum: 288d152bd50c00632e6e01c610bb904a220d1e226c8086c40627877959746f83ab0b872f4150cb7d910198953b1bf756e384ac3fee3e7b0ddb4517f9084c5803 - languageName: node - linkType: hard - -"mdast-util-to-string@npm:^4.0.0": - version: 4.0.0 - resolution: "mdast-util-to-string@npm:4.0.0" - dependencies: - "@types/mdast": ^4.0.0 - checksum: 35489fb5710d58cbc2d6c8b6547df161a3f81e0f28f320dfb3548a9393555daf07c310c0c497708e67ed4dfea4a06e5655799e7d631ca91420c288b4525d6c29 - languageName: node - linkType: hard - -"mdn-data@npm:2.0.14": - version: 2.0.14 - resolution: "mdn-data@npm:2.0.14" - checksum: 9d0128ed425a89f4cba8f787dca27ad9408b5cb1b220af2d938e2a0629d17d879a34d2cb19318bdb26c3f14c77dd5dfbae67211f5caaf07b61b1f2c5c8c7dc16 - languageName: node - linkType: hard - -"mdn-data@npm:2.0.4": - version: 2.0.4 - resolution: "mdn-data@npm:2.0.4" - checksum: add3c95e6d03d301b8a8bcfee3de33f4d07e4c5eee5b79f18d6d737de717e22472deadf67c1a8563983c0b603e10d7df40aa8e5fddf18884dfe118ccec7ae329 - languageName: node - linkType: hard - -"media-typer@npm:0.3.0": - version: 0.3.0 - resolution: "media-typer@npm:0.3.0" - checksum: af1b38516c28ec95d6b0826f6c8f276c58aec391f76be42aa07646b4e39d317723e869700933ca6995b056db4b09a78c92d5440dc23657e6764be5d28874bba1 - languageName: node - linkType: hard - -"media-typer@npm:^1.1.0": - version: 1.1.0 - resolution: "media-typer@npm:1.1.0" - checksum: a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd - languageName: node - linkType: hard - -"memfs@npm:^3.1.2, memfs@npm:^3.4.3": - version: 3.5.3 - resolution: "memfs@npm:3.5.3" - dependencies: - fs-monkey: ^1.0.4 - checksum: 18dfdeacad7c8047b976a6ccd58bc98ba76e122ad3ca0e50a21837fe2075fc0d9aafc58ab9cf2576c2b6889da1dd2503083f2364191b695273f40969db2ecc44 - languageName: node - linkType: hard - -"memoize-one@npm:^6.0.0": - version: 6.0.0 - resolution: "memoize-one@npm:6.0.0" - checksum: f185ea69f7cceae5d1cb596266dcffccf545e8e7b4106ec6aa93b71ab9d16460dd118ac8b12982c55f6d6322fcc1485de139df07eacffaae94888b9b3ad7675f - languageName: node - linkType: hard - -"merge-descriptors@npm:1.0.3": - version: 1.0.3 - resolution: "merge-descriptors@npm:1.0.3" - checksum: 52117adbe0313d5defa771c9993fe081e2d2df9b840597e966aadafde04ae8d0e3da46bac7ca4efc37d4d2b839436582659cd49c6a43eacb3fe3050896a105d1 - languageName: node - linkType: hard - -"merge-descriptors@npm:^2.0.0": - version: 2.0.0 - resolution: "merge-descriptors@npm:2.0.0" - checksum: e383332e700a94682d0125a36c8be761142a1320fc9feeb18e6e36647c9edf064271645f5669b2c21cf352116e561914fd8aa831b651f34db15ef4038c86696a - languageName: node - linkType: hard - -"merge-refs@npm:^1.3.0": - version: 1.3.0 - resolution: "merge-refs@npm:1.3.0" - peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 8400f716a77857dac6b5d49cd5ef69cec7bff6c5555785c5e91a5142fbb5f3e6fe81282bc5be1f01c0c0843ed29f5b4169bfa9838ec69c459b4538f3fef3e79c - languageName: node - linkType: hard - -"merge-stream@npm:^2.0.0": - version: 2.0.0 - resolution: "merge-stream@npm:2.0.0" - checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 - languageName: node - linkType: hard - -"merge2@npm:^1.3.0, merge2@npm:^1.4.1": - version: 1.4.1 - resolution: "merge2@npm:1.4.1" - checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + ssri: ^10.0.0 + checksum: 7c7a6d381ce919dd83af398b66459a10e2fe8f4504f340d1d090d3fa3d1b0c93750220e1d898114c64467223504bd258612ba83efbc16f31b075cd56de24b4af languageName: node linkType: hard -"methods@npm:^1.1.2, methods@npm:~1.1.2": - version: 1.1.2 - resolution: "methods@npm:1.1.2" - checksum: 0917ff4041fa8e2f2fda5425a955fe16ca411591fbd123c0d722fcf02b73971ed6f764d85f0a6f547ce49ee0221ce2c19a5fa692157931cecb422984f1dcd13a +"makeerror@npm:1.0.12": + version: 1.0.12 + resolution: "makeerror@npm:1.0.12" + dependencies: + tmpl: 1.0.5 + checksum: b38a025a12c8146d6eeea5a7f2bf27d51d8ad6064da8ca9405fcf7bf9b54acd43e3b30ddd7abb9b1bfa4ddb266019133313482570ddb207de568f71ecfcf6060 languageName: node linkType: hard -"micromark-core-commonmark@npm:^2.0.0": - version: 2.0.3 - resolution: "micromark-core-commonmark@npm:2.0.3" - dependencies: - decode-named-character-reference: ^1.0.0 - devlop: ^1.0.0 - micromark-factory-destination: ^2.0.0 - micromark-factory-label: ^2.0.0 - micromark-factory-space: ^2.0.0 - micromark-factory-title: ^2.0.0 - micromark-factory-whitespace: ^2.0.0 - micromark-util-character: ^2.0.0 - micromark-util-chunked: ^2.0.0 - micromark-util-classify-character: ^2.0.0 - micromark-util-html-tag-name: ^2.0.0 - micromark-util-normalize-identifier: ^2.0.0 - micromark-util-resolve-all: ^2.0.0 - micromark-util-subtokenize: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: cfb0fd9c895f86a4e9344f7f0344fe6bd1018945798222835248146a42430b8c7bc0b2857af574cf4e1b4ce4e5c1a35a1479942421492e37baddde8de85814dc - languageName: node - linkType: hard - -"micromark-factory-destination@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-destination@npm:2.0.1" - dependencies: - micromark-util-character: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: 9c4baa9ca2ed43c061bbf40ddd3d85154c2a0f1f485de9dea41d7dd2ad994ebb02034a003b2c1dbe228ba83a0576d591f0e90e0bf978713f84ee7d7f3aa98320 +"map-cache@npm:^0.2.2": + version: 0.2.2 + resolution: "map-cache@npm:0.2.2" + checksum: 3067cea54285c43848bb4539f978a15dedc63c03022abeec6ef05c8cb6829f920f13b94bcaf04142fc6a088318e564c4785704072910d120d55dbc2e0c421969 languageName: node linkType: hard -"micromark-factory-label@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-label@npm:2.0.1" +"map-visit@npm:^1.0.0": + version: 1.0.0 + resolution: "map-visit@npm:1.0.0" dependencies: - devlop: ^1.0.0 - micromark-util-character: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: bd03f5a75f27cdbf03b894ddc5c4480fc0763061fecf9eb927d6429233c930394f223969a99472df142d570c831236134de3dc23245d23d9f046f9d0b623b5c2 + object-visit: ^1.0.0 + checksum: c27045a5021c344fc19b9132eb30313e441863b2951029f8f8b66f79d3d8c1e7e5091578075a996f74e417479506fe9ede28c44ca7bc351a61c9d8073daec36a languageName: node linkType: hard -"micromark-factory-space@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-space@npm:2.0.1" +"match-sorter@npm:^6.0.2": + version: 6.3.4 + resolution: "match-sorter@npm:6.3.4" dependencies: - micromark-util-character: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: 1bd68a017c1a66f4787506660c1e1c5019169aac3b1cb075d49ac5e360e0b2065e984d4e1d6e9e52a9d44000f2fa1c98e66a743d7aae78b4b05616bf3242ed71 + "@babel/runtime": ^7.23.8 + remove-accents: 0.5.0 + checksum: 950c1600173a639e216947559a389b64258d52f33aea3a6ddb97500589888b83c976a028f731f40bc08d9d8af20de7916992fabb403f38330183a1df44c7634b languageName: node linkType: hard -"micromark-factory-title@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-title@npm:2.0.1" +"md5.js@npm:^1.3.4": + version: 1.3.5 + resolution: "md5.js@npm:1.3.5" dependencies: - micromark-factory-space: ^2.0.0 - micromark-util-character: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: b4d2e4850a8ba0dff25ce54e55a3eb0d43dda88a16293f53953153288f9d84bcdfa8ca4606b2cfbb4f132ea79587bbb478a73092a349f893f5264fbcdbce2ee1 + hash-base: ^3.0.0 + inherits: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: 098494d885684bcc4f92294b18ba61b7bd353c23147fbc4688c75b45cb8590f5a95fd4584d742415dcc52487f7a1ef6ea611cfa1543b0dc4492fe026357f3f0c languageName: node linkType: hard -"micromark-factory-whitespace@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-whitespace@npm:2.0.1" +"mdast-util-definitions@npm:^4.0.0": + version: 4.0.0 + resolution: "mdast-util-definitions@npm:4.0.0" dependencies: - micromark-factory-space: ^2.0.0 - micromark-util-character: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: 67b3944d012a42fee9e10e99178254a04d48af762b54c10a50fcab988688799993efb038daf9f5dbc04001a97b9c1b673fc6f00e6a56997877ab25449f0c8650 + unist-util-visit: ^2.0.0 + checksum: 2325f20b82b3fb8cb5fda77038ee0bbdd44f82cfca7c48a854724b58bc1fe5919630a3ce7c45e210726df59d46c881d020b2da7a493bfd1ee36eb2bbfef5d78e languageName: node linkType: hard -"micromark-util-character@npm:^2.0.0": - version: 2.1.1 - resolution: "micromark-util-character@npm:2.1.1" +"mdast-util-from-markdown@npm:^0.8.0": + version: 0.8.5 + resolution: "mdast-util-from-markdown@npm:0.8.5" dependencies: - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: e9e409efe4f2596acd44587e8591b722bfc041c1577e8fe0d9c007a4776fb800f9b3637a22862ad2ba9489f4bdf72bb547fce5767dbbfe0a5e6760e2a21c6495 + "@types/mdast": ^3.0.0 + mdast-util-to-string: ^2.0.0 + micromark: ~2.11.0 + parse-entities: ^2.0.0 + unist-util-stringify-position: ^2.0.0 + checksum: 5a9d0d753a42db763761e874c22365d0c7c9934a5a18b5ff76a0643610108a208a041ffdb2f3d3dd1863d3d915225a4020a0aade282af0facfd0df110601eee6 languageName: node linkType: hard -"micromark-util-chunked@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-chunked@npm:2.0.1" +"mdast-util-to-hast@npm:^10.2.0": + version: 10.2.0 + resolution: "mdast-util-to-hast@npm:10.2.0" dependencies: - micromark-util-symbol: ^2.0.0 - checksum: f8cb2a67bcefe4bd2846d838c97b777101f0043b9f1de4f69baf3e26bb1f9885948444e3c3aec66db7595cad8173bd4567a000eb933576c233d54631f6323fe4 + "@types/mdast": ^3.0.0 + "@types/unist": ^2.0.0 + mdast-util-definitions: ^4.0.0 + mdurl: ^1.0.0 + unist-builder: ^2.0.0 + unist-util-generated: ^1.0.0 + unist-util-position: ^3.0.0 + unist-util-visit: ^2.0.0 + checksum: 72df2dd9bfa2d07b4750a333444f82e0f3752dae75b6e300cf0a716407a185eb75095a54ecad90cbd6f6d133b20dea8844ff76c1ea78612550de170b43d4fa85 languageName: node linkType: hard -"micromark-util-classify-character@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-classify-character@npm:2.0.1" - dependencies: - micromark-util-character: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: 4d8bbe3a6dbf69ac0fc43516866b5bab019fe3f4568edc525d4feaaaf78423fa54e6b6732b5bccbeed924455279a3758ffc9556954aafb903982598a95a02704 +"mdast-util-to-string@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-to-string@npm:2.0.0" + checksum: 0b2113ada10e002fbccb014170506dabe2f2ddacaacbe4bc1045c33f986652c5a162732a2c057c5335cdb58419e2ad23e368e5be226855d4d4e280b81c4e9ec2 languageName: node linkType: hard -"micromark-util-combine-extensions@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-combine-extensions@npm:2.0.1" - dependencies: - micromark-util-chunked: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: 5d22fb9ee37e8143adfe128a72b50fa09568c2cc553b3c76160486c96dbbb298c5802a177a10a215144a604b381796071b5d35be1f2c2b2ee17995eda92f0c8e +"mdn-data@npm:2.0.14": + version: 2.0.14 + resolution: "mdn-data@npm:2.0.14" + checksum: 9d0128ed425a89f4cba8f787dca27ad9408b5cb1b220af2d938e2a0629d17d879a34d2cb19318bdb26c3f14c77dd5dfbae67211f5caaf07b61b1f2c5c8c7dc16 languageName: node linkType: hard -"micromark-util-decode-numeric-character-reference@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-util-decode-numeric-character-reference@npm:2.0.2" - dependencies: - micromark-util-symbol: ^2.0.0 - checksum: ee11c8bde51e250e302050474c4a2adca094bca05c69f6cdd241af12df285c48c88d19ee6e022b9728281c280be16328904adca994605680c43af56019f4b0b6 +"mdn-data@npm:2.0.4": + version: 2.0.4 + resolution: "mdn-data@npm:2.0.4" + checksum: add3c95e6d03d301b8a8bcfee3de33f4d07e4c5eee5b79f18d6d737de717e22472deadf67c1a8563983c0b603e10d7df40aa8e5fddf18884dfe118ccec7ae329 languageName: node linkType: hard -"micromark-util-decode-string@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-decode-string@npm:2.0.1" - dependencies: - decode-named-character-reference: ^1.0.0 - micromark-util-character: ^2.0.0 - micromark-util-decode-numeric-character-reference: ^2.0.0 - micromark-util-symbol: ^2.0.0 - checksum: e9546ae53f9b5a4f9aa6aaf3e750087100d3429485ca80dbacec99ff2bb15a406fa7d93784a0fc2fe05ad7296b9295e75160ef71faec9e90110b7be2ae66241a +"mdurl@npm:^1.0.0": + version: 1.0.1 + resolution: "mdurl@npm:1.0.1" + checksum: 71731ecba943926bfbf9f9b51e28b5945f9411c4eda80894221b47cc105afa43ba2da820732b436f0798fd3edbbffcd1fc1415843c41a87fea08a41cc1e3d02b languageName: node linkType: hard -"micromark-util-encode@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-encode@npm:2.0.1" - checksum: be890b98e78dd0cdd953a313f4148c4692cc2fb05533e56fef5f421287d3c08feee38ca679f318e740530791fc251bfe8c80efa926fcceb4419b269c9343d226 +"media-typer@npm:0.3.0": + version: 0.3.0 + resolution: "media-typer@npm:0.3.0" + checksum: af1b38516c28ec95d6b0826f6c8f276c58aec391f76be42aa07646b4e39d317723e869700933ca6995b056db4b09a78c92d5440dc23657e6764be5d28874bba1 languageName: node linkType: hard -"micromark-util-html-tag-name@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-html-tag-name@npm:2.0.1" - checksum: dea365f5ad28ad74ff29fcb581f7b74fc1f80271c5141b3b2bc91c454cbb6dfca753f28ae03730d657874fcbd89d0494d0e3965dfdca06d9855f467c576afa9d +"memory-fs@npm:^0.4.1": + version: 0.4.1 + resolution: "memory-fs@npm:0.4.1" + dependencies: + errno: ^0.1.3 + readable-stream: ^2.0.1 + checksum: 6db6c8682eff836664ca9b5b6052ae38d21713dda9d0ef4700fa5c0599a8bc16b2093bee75ac3dedbe59fb2222d368f25bafaa62ba143c41051359cbcb005044 languageName: node linkType: hard -"micromark-util-normalize-identifier@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-normalize-identifier@npm:2.0.1" +"memory-fs@npm:^0.5.0": + version: 0.5.0 + resolution: "memory-fs@npm:0.5.0" dependencies: - micromark-util-symbol: ^2.0.0 - checksum: 1eb9a289d7da067323df9fdc78bfa90ca3207ad8fd893ca02f3133e973adcb3743b233393d23d95c84ccaf5d220ae7f5a28402a644f135dcd4b8cfa60a7b5f84 + errno: ^0.1.3 + readable-stream: ^2.0.1 + checksum: a9f25b0a8ecfb7324277393f19ef68e6ba53b9e6e4b526bbf2ba23055c5440fbf61acc7bf66bfd980e9eb4951a4790f6f777a9a3abd36603f22c87e8a64d3d6b languageName: node linkType: hard -"micromark-util-resolve-all@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-resolve-all@npm:2.0.1" - dependencies: - micromark-util-types: ^2.0.0 - checksum: 9275f3ddb6c26f254dd2158e66215d050454b279707a7d9ce5a3cd0eba23201021cedcb78ae1a746c1b23227dcc418ee40dd074ade195359506797a5493550cc +"merge-descriptors@npm:1.0.1": + version: 1.0.1 + resolution: "merge-descriptors@npm:1.0.1" + checksum: 5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 languageName: node linkType: hard -"micromark-util-sanitize-uri@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-sanitize-uri@npm:2.0.1" - dependencies: - micromark-util-character: ^2.0.0 - micromark-util-encode: ^2.0.0 - micromark-util-symbol: ^2.0.0 - checksum: d01517840c17de67aaa0b0f03bfe05fac8a41d99723cd8ce16c62f6810e99cd3695364a34c335485018e5e2c00e69031744630a1b85c6868aa2f2ca1b36daa2f +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 languageName: node linkType: hard -"micromark-util-subtokenize@npm:^2.0.0": - version: 2.1.0 - resolution: "micromark-util-subtokenize@npm:2.1.0" - dependencies: - devlop: ^1.0.0 - micromark-util-chunked: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: 2e194bc8a5279d256582020500e5072a95c1094571be49043704343032e1fffbe09c862ef9c131cf5c762e296ddb54ff8bc767b3786a798524a68d1db6942934 +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 languageName: node linkType: hard -"micromark-util-symbol@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-symbol@npm:2.0.1" - checksum: fb7346950550bc85a55793dda94a8b3cb3abc068dbd7570d1162db7aee803411d06c0a5de4ae59cd945f46143bdeadd4bba02a02248fa0d18cc577babaa00044 +"methods@npm:^1.1.2, methods@npm:~1.1.2": + version: 1.1.2 + resolution: "methods@npm:1.1.2" + checksum: 0917ff4041fa8e2f2fda5425a955fe16ca411591fbd123c0d722fcf02b73971ed6f764d85f0a6f547ce49ee0221ce2c19a5fa692157931cecb422984f1dcd13a languageName: node linkType: hard -"micromark-util-types@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-util-types@npm:2.0.2" - checksum: 884f7974839e4bc6d2bd662e57c973a9164fd5c0d8fe16cddf07472b86a7e6726747c00674952c0321d17685d700cd3295e9f58a842a53acdf6c6d55ab051aab +"microevent.ts@npm:~0.1.1": + version: 0.1.1 + resolution: "microevent.ts@npm:0.1.1" + checksum: 7874fcdb3f0dfa4e996d3ea63b3b9882874ae7d22be28d51ae20da24c712e9e28e5011d988095c27dd2b32e37c0ad7425342a71b89adb8e808ec7194fadf4a7a languageName: node linkType: hard -"micromark@npm:^4.0.0": - version: 4.0.2 - resolution: "micromark@npm:4.0.2" +"micromark@npm:~2.11.0": + version: 2.11.4 + resolution: "micromark@npm:2.11.4" dependencies: - "@types/debug": ^4.0.0 debug: ^4.0.0 - decode-named-character-reference: ^1.0.0 - devlop: ^1.0.0 - micromark-core-commonmark: ^2.0.0 - micromark-factory-space: ^2.0.0 - micromark-util-character: ^2.0.0 - micromark-util-chunked: ^2.0.0 - micromark-util-combine-extensions: ^2.0.0 - micromark-util-decode-numeric-character-reference: ^2.0.0 - micromark-util-encode: ^2.0.0 - micromark-util-normalize-identifier: ^2.0.0 - micromark-util-resolve-all: ^2.0.0 - micromark-util-sanitize-uri: ^2.0.0 - micromark-util-subtokenize: ^2.0.0 - micromark-util-symbol: ^2.0.0 - micromark-util-types: ^2.0.0 - checksum: 5306c15dd12f543755bc627fc361d4255dfc430e7af6069a07ac0eacc338fbd761fe8e93f02a8bfab6097bab12ee903192fe31389222459d5029242a5aaba3b8 - languageName: node - linkType: hard - -"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5, micromatch@npm:^4.0.8": - version: 4.0.8 - resolution: "micromatch@npm:4.0.8" + parse-entities: ^2.0.0 + checksum: f8a5477d394908a5d770227aea71657a76423d420227c67ea0699e659a5f62eb39d504c1f7d69ec525a6af5aaeb6a7bffcdba95614968c03d41d3851edecb0d6 + languageName: node + linkType: hard + +"micromatch@npm:^3.1.10, micromatch@npm:^3.1.4": + version: 3.1.10 + resolution: "micromatch@npm:3.1.10" + dependencies: + arr-diff: ^4.0.0 + array-unique: ^0.3.2 + braces: ^2.3.1 + define-property: ^2.0.2 + extend-shallow: ^3.0.2 + extglob: ^2.0.4 + fragment-cache: ^0.2.1 + kind-of: ^6.0.2 + nanomatch: ^1.2.9 + object.pick: ^1.3.0 + regex-not: ^1.0.0 + snapdragon: ^0.8.1 + to-regex: ^3.0.2 + checksum: ad226cba4daa95b4eaf47b2ca331c8d2e038d7b41ae7ed0697cde27f3f1d6142881ab03d4da51b65d9d315eceb5e4cdddb3fbb55f5f72cfa19cf3ea469d054dc + languageName: node + linkType: hard + +"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" dependencies: - braces: ^3.0.3 + braces: ^3.0.2 picomatch: ^2.3.1 - checksum: 79920eb634e6f400b464a954fcfa589c4e7c7143209488e44baf627f9affc8b1e306f41f4f0deedde97e69cb725920879462d3e750ab3bd3c1aed675bb3a8966 + checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc languageName: node linkType: hard @@ -15359,21 +13698,26 @@ __metadata: languageName: node linkType: hard -"mime-db@npm:1.52.0": - version: 1.52.0 - resolution: "mime-db@npm:1.52.0" - checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f +"miller-rabin@npm:^4.0.0": + version: 4.0.1 + resolution: "miller-rabin@npm:4.0.1" + dependencies: + bn.js: ^4.0.0 + brorand: ^1.0.1 + bin: + miller-rabin: bin/miller-rabin + checksum: 00cd1ab838ac49b03f236cc32a14d29d7d28637a53096bf5c6246a032a37749c9bd9ce7360cbf55b41b89b7d649824949ff12bc8eee29ac77c6b38eada619ece languageName: node linkType: hard -"mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.54.0": - version: 1.54.0 - resolution: "mime-db@npm:1.54.0" - checksum: e99aaf2f23f5bd607deb08c83faba5dd25cf2fec90a7cc5b92d8260867ee08dab65312e1a589e60093dc7796d41e5fae013268418482f1db4c7d52d0a0960ac9 +"mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:^2.1.35, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -15382,15 +13726,6 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^3.0.0, mime-types@npm:^3.0.1": - version: 3.0.1 - resolution: "mime-types@npm:3.0.1" - dependencies: - mime-db: ^1.54.0 - checksum: 8d497ad5cb2dd1210ac7d049b5de94af0b24b45a314961e145b44389344604d54752f03bc00bf880c0da60a214be6fb6d423d318104f02c28d95dd8ebeea4fb4 - languageName: node - linkType: hard - "mime@npm:1.6.0": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -15400,7 +13735,7 @@ __metadata: languageName: node linkType: hard -"mime@npm:2.6.0": +"mime@npm:2.6.0, mime@npm:^2.4.4": version: 2.6.0 resolution: "mime@npm:2.6.0" bin: @@ -15416,13 +13751,6 @@ __metadata: languageName: node linkType: hard -"mimic-response@npm:^3.1.0": - version: 3.1.0 - resolution: "mimic-response@npm:3.1.0" - checksum: 25739fee32c17f433626bf19f016df9036b75b3d84a3046c7d156e72ec963dd29d7fc8a302f55a3d6c5a4ff24259676b15d915aad6480815a969ff2ec0836867 - languageName: node - linkType: hard - "min-indent@npm:^1.0.0": version: 1.0.1 resolution: "min-indent@npm:1.0.1" @@ -15430,68 +13758,77 @@ __metadata: languageName: node linkType: hard -"mini-css-extract-plugin@npm:^2.4.5": - version: 2.9.4 - resolution: "mini-css-extract-plugin@npm:2.9.4" +"mini-css-extract-plugin@npm:0.11.3": + version: 0.11.3 + resolution: "mini-css-extract-plugin@npm:0.11.3" dependencies: - schema-utils: ^4.0.0 - tapable: ^2.2.1 + loader-utils: ^1.1.0 + normalize-url: 1.9.1 + schema-utils: ^1.0.0 + webpack-sources: ^1.1.0 peerDependencies: - webpack: ^5.0.0 - checksum: 4ec46ebdcb5dae4b1c012debca90fea27b1e8e7790d408154232d77d25f56f839e7b1ec5401a962d6356e7b9301c760d2ef62e1cb0d4d7b6ec8209f812733dda + webpack: ^4.4.0 || ^5.0.0 + checksum: 14fbdf1338fe0264a2f7f87b3fc640809b7443f6434c6532bdbec1c5ab113502325fec958e9cf0667c3790087dc1e83c02e1f4d7463c10c956b0d6ebe56ea99e languageName: node linkType: hard -"minimalistic-assert@npm:^1.0.0": +"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": version: 1.0.1 resolution: "minimalistic-assert@npm:1.0.1" checksum: cc7974a9268fbf130fb055aff76700d7e2d8be5f761fb5c60318d0ed010d839ab3661a533ad29a5d37653133385204c503bfac995aaa4236f4e847461ea32ba7 languageName: node linkType: hard -"minimatch@npm:^10.0.3": - version: 10.0.3 - resolution: "minimatch@npm:10.0.3" - dependencies: - "@isaacs/brace-expansion": ^5.0.0 - checksum: 20bfb708095a321cb43c20b78254e484cb7d23aad992e15ca3234a3331a70fa9cd7a50bc1a7c7b2b9c9890c37ff0685f8380028fcc28ea5e6de75b1d4f9374aa +"minimalistic-crypto-utils@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-crypto-utils@npm:1.0.1" + checksum: 6e8a0422b30039406efd4c440829ea8f988845db02a3299f372fceba56ffa94994a9c0f2fd70c17f9969eedfbd72f34b5070ead9656a34d3f71c0bd72583a0ed languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" +"minimatch@npm:3.0.4": + version: 3.0.4 + resolution: "minimatch@npm:3.0.4" dependencies: brace-expansion: ^1.1.7 - checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a + checksum: 66ac295f8a7b59788000ea3749938b0970344c841750abd96694f80269b926ebcafad3deeb3f1da2522978b119e6ae3a5869b63b13a7859a456b3408bd18a078 languageName: node linkType: hard -"minimatch@npm:^5.0.1": - version: 5.1.6 - resolution: "minimatch@npm:5.1.6" +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" dependencies: - brace-expansion: ^2.0.1 - checksum: 7564208ef81d7065a370f788d337cd80a689e981042cb9a1d0e6580b6c6a8c9279eba80010516e258835a988363f99f54a6f711a315089b8b42694f5da9d0d77 + brace-expansion: ^1.1.7 + checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a languageName: node linkType: hard -"minimatch@npm:^9.0.4": - version: 9.0.5 - resolution: "minimatch@npm:9.0.5" +"minimatch@npm:^9.0.1": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" dependencies: brace-expansion: ^2.0.1 - checksum: 2c035575eda1e50623c731ec6c14f65a85296268f749b9337005210bb2b34e2705f8ef1a358b188f69892286ab99dc42c8fb98a57bde55c8d81b3023c19cea28 + checksum: cf717f597ec3eed7dabc33153482a2e8d49f4fd3c26e58fd9c71a94c5029a0838728841b93f46bf1263b65a8010e2ee800d0dc9b004ab8ba8b6d1ec07cc115b5 languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6": +"minimist@npm:^1.1.1, minimist@npm:^1.2.0, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 languageName: node linkType: hard +"minipass-collect@npm:^1.0.2": + version: 1.0.2 + resolution: "minipass-collect@npm:1.0.2" + dependencies: + minipass: ^3.0.0 + checksum: 14df761028f3e47293aee72888f2657695ec66bd7d09cae7ad558da30415fdc4752bbfee66287dcc6fd5e6a2fa3466d6c484dc1cbd986525d9393b9523d97f10 + languageName: node + linkType: hard + "minipass-collect@npm:^2.0.1": version: 2.0.1 resolution: "minipass-collect@npm:2.0.1" @@ -15501,18 +13838,18 @@ __metadata: languageName: node linkType: hard -"minipass-fetch@npm:^4.0.0": - version: 4.0.1 - resolution: "minipass-fetch@npm:4.0.1" +"minipass-fetch@npm:^3.0.0": + version: 3.0.4 + resolution: "minipass-fetch@npm:3.0.4" dependencies: encoding: ^0.1.13 minipass: ^7.0.3 minipass-sized: ^1.0.3 - minizlib: ^3.0.1 + minizlib: ^2.1.2 dependenciesMeta: encoding: optional: true - checksum: 3dfca705ce887ca9ff14d73e8d8593996dea1a1ecd8101fdbb9c10549d1f9670bc8fb66ad0192769ead4c2dc01b4f9ca1cf567ded365adff17827a303b948140 + checksum: af7aad15d5c128ab1ebe52e043bdf7d62c3c6f0cecb9285b40d7b395e1375b45dcdfd40e63e93d26a0e8249c9efd5c325c65575aceee192883970ff8cb11364a languageName: node linkType: hard @@ -15525,7 +13862,7 @@ __metadata: languageName: node linkType: hard -"minipass-pipeline@npm:^1.2.4": +"minipass-pipeline@npm:^1.2.2, minipass-pipeline@npm:^1.2.4": version: 1.2.4 resolution: "minipass-pipeline@npm:1.2.4" dependencies: @@ -15543,7 +13880,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^3.0.0": +"minipass@npm:^3.0.0, minipass@npm:^3.1.1": version: 3.3.6 resolution: "minipass@npm:3.3.6" dependencies: @@ -15552,37 +13889,68 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": - version: 7.1.2 - resolution: "minipass@npm:7.1.2" - checksum: 2bfd325b95c555f2b4d2814d49325691c7bee937d753814861b0b49d5edcda55cbbf22b6b6a60bb91eddac8668771f03c5ff647dcd9d0f798e9548b9cdc46ee3 +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea languageName: node linkType: hard -"minizlib@npm:^3.0.1": - version: 3.0.2 - resolution: "minizlib@npm:3.0.2" +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": + version: 7.0.4 + resolution: "minipass@npm:7.0.4" + checksum: 87585e258b9488caf2e7acea242fd7856bbe9a2c84a7807643513a338d66f368c7d518200ad7b70a508664d408aa000517647b2930c259a8b1f9f0984f344a21 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" dependencies: - minipass: ^7.1.2 - checksum: 493bed14dcb6118da7f8af356a8947cf1473289c09658e5aabd69a737800a8c3b1736fb7d7931b722268a9c9bc038a6d53c049b6a6af24b34a121823bb709996 + minipass: ^3.0.0 + yallist: ^4.0.0 + checksum: f1fdeac0b07cf8f30fcf12f4b586795b97be856edea22b5e9072707be51fc95d41487faec3f265b42973a304fe3a64acd91a44a3826a963e37b37bafde0212c3 languageName: node linkType: hard -"mitt@npm:^3.0.1": - version: 3.0.1 - resolution: "mitt@npm:3.0.1" - checksum: b55a489ac9c2949ab166b7f060601d3b6d893a852515ae9eca4e11df01c013876df777ea109317622b5c1c60e8aae252558e33c8c94e14124db38f64a39614b1 +"mississippi@npm:^3.0.0": + version: 3.0.0 + resolution: "mississippi@npm:3.0.0" + dependencies: + concat-stream: ^1.5.0 + duplexify: ^3.4.2 + end-of-stream: ^1.1.0 + flush-write-stream: ^1.0.0 + from2: ^2.1.0 + parallel-transform: ^1.1.0 + pump: ^3.0.0 + pumpify: ^1.3.3 + stream-each: ^1.1.0 + through2: ^2.0.0 + checksum: 84b3d9889621d293f9a596bafe60df863b330c88fc19215ced8f603c605fc7e1bf06f8e036edf301bd630a03fd5d9d7d23d5d6b9a4802c30ca864d800f0bd9f8 languageName: node linkType: hard -"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": - version: 0.5.3 - resolution: "mkdirp-classic@npm:0.5.3" - checksum: 3f4e088208270bbcc148d53b73e9a5bd9eef05ad2cbf3b3d0ff8795278d50dd1d11a8ef1875ff5aea3fa888931f95bfcb2ad5b7c1061cfefd6284d199e6776ac +"mixin-deep@npm:^1.2.0": + version: 1.3.2 + resolution: "mixin-deep@npm:1.3.2" + dependencies: + for-in: ^1.0.2 + is-extendable: ^1.0.1 + checksum: 820d5a51fcb7479f2926b97f2c3bb223546bc915e6b3a3eb5d906dda871bba569863595424a76682f2b15718252954644f3891437cb7e3f220949bed54b1750d + languageName: node + linkType: hard + +"mkdirp@npm:1.x, mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: a96865108c6c3b1b8e1d5e9f11843de1e077e57737602de1b82030815f311be11f96f09cce59bd5b903d0b29834733e5313f9301e3ed6d6f6fba2eae0df4298f languageName: node linkType: hard -"mkdirp@npm:^0.5.4, mkdirp@npm:~0.5.1": +"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.3, mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.6, mkdirp@npm:~0.5.1": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" dependencies: @@ -15593,12 +13961,29 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^3.0.1": - version: 3.0.1 - resolution: "mkdirp@npm:3.0.1" - bin: - mkdirp: dist/cjs/src/bin.js - checksum: 972deb188e8fb55547f1e58d66bd6b4a3623bf0c7137802582602d73e6480c1c2268dcbafbfb1be466e00cc7e56ac514d7fd9334b7cf33e3e2ab547c16f83a8d +"mlly@npm:^1.4.0, mlly@npm:^1.6.1": + version: 1.6.1 + resolution: "mlly@npm:1.6.1" + dependencies: + acorn: ^8.11.3 + pathe: ^1.1.2 + pkg-types: ^1.0.3 + ufo: ^1.3.2 + checksum: c40a547dba8f6b2a5a840899d49f4c9550c233d47fd7bd75f4ac27f388047bad655ad86684329809c1640df4373b45bec77304f73530ca4354bc1199700e2a46 + languageName: node + linkType: hard + +"move-concurrently@npm:^1.0.1": + version: 1.0.1 + resolution: "move-concurrently@npm:1.0.1" + dependencies: + aproba: ^1.1.1 + copy-concurrently: ^1.0.0 + fs-write-stream-atomic: ^1.0.8 + mkdirp: ^0.5.1 + rimraf: ^2.5.4 + run-queue: ^1.0.3 + checksum: 4ea3296c150b09e798177847f673eb5783f8ca417ba806668d2c631739f653e1a735f19fb9b6e2f5e25ee2e4c0a6224732237a8e4f84c764e99d7462d258209e languageName: node linkType: hard @@ -15609,50 +13994,58 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.3, ms@npm:^2.1.1, ms@npm:^2.1.3": +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"ms@npm:2.1.3, ms@npm:^2.1.1": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d languageName: node linkType: hard -"msw@npm:^2.7.0": - version: 2.11.2 - resolution: "msw@npm:2.11.2" - dependencies: - "@bundled-es-modules/cookie": ^2.0.1 - "@bundled-es-modules/statuses": ^1.0.1 - "@inquirer/confirm": ^5.0.0 - "@mswjs/interceptors": ^0.39.1 - "@open-draft/deferred-promise": ^2.2.0 - "@open-draft/until": ^2.1.0 - "@types/cookie": ^0.6.0 - "@types/statuses": ^2.0.4 - graphql: ^16.8.1 - headers-polyfill: ^4.0.2 - is-node-process: ^1.2.0 - outvariant: ^1.4.3 - path-to-regexp: ^6.3.0 - picocolors: ^1.1.1 - rettime: ^0.7.0 - strict-event-emitter: ^0.5.1 - tough-cookie: ^6.0.0 - type-fest: ^4.26.1 - yargs: ^17.7.2 +"msw@npm:^0.44.2": + version: 0.44.2 + resolution: "msw@npm:0.44.2" + dependencies: + "@mswjs/cookies": ^0.2.2 + "@mswjs/interceptors": ^0.17.2 + "@open-draft/until": ^1.0.3 + "@types/cookie": ^0.4.1 + "@types/js-levenshtein": ^1.1.1 + chalk: 4.1.1 + chokidar: ^3.4.2 + cookie: ^0.4.2 + graphql: ^16.3.0 + headers-polyfill: ^3.0.4 + inquirer: ^8.2.0 + is-node-process: ^1.0.1 + js-levenshtein: ^1.1.6 + node-fetch: ^2.6.7 + outvariant: ^1.3.0 + path-to-regexp: ^6.2.0 + statuses: ^2.0.0 + strict-event-emitter: ^0.2.0 + type-fest: ^1.2.2 + yargs: ^17.3.1 peerDependencies: - typescript: ">= 4.8.x" + typescript: ">= 4.2.x <= 4.7.x" peerDependenciesMeta: typescript: optional: true bin: msw: cli/index.js - checksum: 599aa3ed6e5043479bef473fa427a7aaf343d32aedba301ec62cac1a30c50b2a2898c4b9fe11b939ab03768807860eff64ce2fbdd28f78d0c6be4f4318d8b276 + checksum: 739d536ee09d1c0a2cbc9dbe917f167c42115a6548f99780850ce9a63a5e7c377cf9b5f1a3b497e85ce7304025ab22966e997fe73adbd8d2ab968b8685f15a24 languageName: node linkType: hard "multer@npm:^1.4.5-lts.1": - version: 1.4.5-lts.2 - resolution: "multer@npm:1.4.5-lts.2" + version: 1.4.5-lts.1 + resolution: "multer@npm:1.4.5-lts.1" dependencies: append-field: ^1.0.0 busboy: ^1.0.0 @@ -15661,37 +14054,42 @@ __metadata: object-assign: ^4.1.1 type-is: ^1.6.4 xtend: ^4.0.0 - checksum: b6f76a24c8fbc4d3ed5696ff8c98e126e7831d26f85e0ce17ab8d77e33a9ec14e33e4d05ea5e4e748e63a1b695cf450c2b05d8eee58484a74a1c13f459429713 + checksum: d6dfa78a6ec592b74890412f8962da8a87a3dcfe20f612e039b735b8e0faa72c735516c447f7de694ee0d981eb0a1b892fb9e2402a0348dc6091d18c38d89ecc + languageName: node + linkType: hard + +"multicast-dns-service-types@npm:^1.1.0": + version: 1.1.0 + resolution: "multicast-dns-service-types@npm:1.1.0" + checksum: 0979fca1cce85484d256e4db3af591d941b41a61f134da3607213d2624c12ed5b8a246565cb19a9b3cb542819e8fbc71a90b07e77023ee6a9515540fe1d371f7 languageName: node linkType: hard -"multicast-dns@npm:^7.2.5": - version: 7.2.5 - resolution: "multicast-dns@npm:7.2.5" +"multicast-dns@npm:^6.0.1": + version: 6.2.3 + resolution: "multicast-dns@npm:6.2.3" dependencies: - dns-packet: ^5.2.2 + dns-packet: ^1.3.1 thunky: ^1.0.2 bin: multicast-dns: cli.js - checksum: 00b8a57df152d4cd0297946320a94b7c3cdf75a46a2247f32f958a8927dea42958177f9b7fdae69fab2e4e033fb3416881af1f5e9055a3e1542888767139e2fb + checksum: f515b49ca964429ab48a4ac8041fcf969c927aeb49ab65288bd982e52c849a870fc3b03565780b0d194a1a02da8821f28b6425e48e95b8107bc9fcc92f571a6f languageName: node linkType: hard -"mute-stream@npm:^2.0.0": - version: 2.0.0 - resolution: "mute-stream@npm:2.0.0" - checksum: d2e4fd2f5aa342b89b98134a8d899d8ef9b0a6d69274c4af9df46faa2d97aeb1f2ce83d867880d6de63643c52386579b99139801e24e7526c3b9b0a6d1e18d6c +"mute-stream@npm:0.0.8": + version: 0.0.8 + resolution: "mute-stream@npm:0.0.8" + checksum: ff48d251fc3f827e5b1206cda0ffdaec885e56057ee86a3155e1951bc940fd5f33531774b1cc8414d7668c10a8907f863f6561875ee6e8768931a62121a531a1 languageName: node linkType: hard -"mz@npm:^2.7.0": - version: 2.7.0 - resolution: "mz@npm:2.7.0" +"nan@npm:^2.12.1": + version: 2.19.0 + resolution: "nan@npm:2.19.0" dependencies: - any-promise: ^1.0.0 - object-assign: ^4.0.1 - thenify-all: ^1.0.0 - checksum: 8427de0ece99a07e9faed3c0c6778820d7543e3776f9a84d22cf0ec0a8eb65f6e9aee9c9d353ff9a105ff62d33a9463c6ca638974cc652ee8140cd1e35951c87 + node-gyp: latest + checksum: 29a894a003c1954c250d690768c30e69cd91017e2e5eb21b294380f7cace425559508f5ffe3e329a751307140b0bd02f83af040740fa4def1a3869be6af39600 languageName: node linkType: hard @@ -15704,26 +14102,47 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.11": - version: 3.3.11 - resolution: "nanoid@npm:3.3.11" +"nanoclone@npm:^0.2.1": + version: 0.2.1 + resolution: "nanoclone@npm:0.2.1" + checksum: 96b2954e22f70561f41e20d69856266c65583c2a441dae108f1dc71b716785d2c8038dac5f1d5e92b117aed3825f526b53139e2e5d6e6db8a77cfa35b3b8bf40 + languageName: node + linkType: hard + +"nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" bin: nanoid: bin/nanoid.cjs - checksum: 3be20d8866a57a6b6d218e82549711c8352ed969f9ab3c45379da28f405363ad4c9aeb0b39e9abc101a529ca65a72ff9502b00bf74a912c4b64a9d62dfd26c29 + checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2 languageName: node linkType: hard -"napi-build-utils@npm:^2.0.0": - version: 2.0.0 - resolution: "napi-build-utils@npm:2.0.0" - checksum: 532121efd2dd2272595580bca48859e404bdd4ed455a72a28432ba44868c38d0e64fac3026a8f82bf8563d2a18b32eb9a1d59e601a9da4e84ba4d45b922297f5 +"nanomatch@npm:^1.2.9": + version: 1.2.13 + resolution: "nanomatch@npm:1.2.13" + dependencies: + arr-diff: ^4.0.0 + array-unique: ^0.3.2 + define-property: ^2.0.2 + extend-shallow: ^3.0.2 + fragment-cache: ^0.2.1 + is-windows: ^1.0.2 + kind-of: ^6.0.2 + object.pick: ^1.3.0 + regex-not: ^1.0.0 + snapdragon: ^0.8.1 + to-regex: ^3.0.1 + checksum: 54d4166d6ef08db41252eb4e96d4109ebcb8029f0374f9db873bd91a1f896c32ec780d2a2ea65c0b2d7caf1f28d5e1ea33746a470f32146ac8bba821d80d38d8 languageName: node linkType: hard -"natural-compare-lite@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare-lite@npm:1.4.0" - checksum: 5222ac3986a2b78dd6069ac62cbb52a7bf8ffc90d972ab76dfe7b01892485d229530ed20d0c62e79a6b363a663b273db3bde195a1358ce9e5f779d4453887225 +"native-url@npm:^0.2.6": + version: 0.2.6 + resolution: "native-url@npm:0.2.6" + dependencies: + querystring: ^0.2.0 + checksum: d56a67b32e635c4944985f551a9976dfe609a3947810791c50f5c37cff1d9dd5fe040184989d104be8752582b79dc4e726f2a9c075d691ecce86b31ae9387f1b languageName: node linkType: hard @@ -15734,31 +14153,31 @@ __metadata: languageName: node linkType: hard -"negotiator@npm:0.6.3": +"negotiator@npm:0.6.3, negotiator@npm:^0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" checksum: b8ffeb1e262eff7968fc90a2b6767b04cfd9842582a9d0ece0af7049537266e7b2506dfb1d107a32f06dd849ab2aea834d5830f7f4d0e5cb7d36e1ae55d021d9 languageName: node linkType: hard -"negotiator@npm:^1.0.0": - version: 1.0.0 - resolution: "negotiator@npm:1.0.0" - checksum: 20ebfe79b2d2e7cf9cbc8239a72662b584f71164096e6e8896c8325055497c96f6b80cd22c258e8a2f2aa382a787795ec3ee8b37b422a302c7d4381b0d5ecfbb +"neo-async@npm:^2.5.0, neo-async@npm:^2.6.1, neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 languageName: node linkType: hard -"negotiator@npm:~0.6.4": - version: 0.6.4 - resolution: "negotiator@npm:0.6.4" - checksum: 7ded10aa02a0707d1d12a9973fdb5954f98547ca7beb60e31cb3a403cc6e8f11138db7a3b0128425cf836fc85d145ec4ce983b2bdf83dca436af879c2d683510 +"next-tick@npm:^1.1.0": + version: 1.1.0 + resolution: "next-tick@npm:1.1.0" + checksum: 83b5cf36027a53ee6d8b7f9c0782f2ba87f4858d977342bfc3c20c21629290a2111f8374d13a81221179603ffc4364f38374b5655d17b6a8f8a8c77bdea4fe8b languageName: node linkType: hard -"neo-async@npm:^2.6.2": - version: 2.6.2 - resolution: "neo-async@npm:2.6.2" - checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 +"nice-try@npm:^1.0.4": + version: 1.0.5 + resolution: "nice-try@npm:1.0.5" + checksum: 0b4af3b5bb5d86c289f7a026303d192a7eb4417231fe47245c460baeabae7277bcd8fd9c728fb6bd62c30b3e15cd6620373e2cf33353b095d8b403d3e8a15aff languageName: node linkType: hard @@ -15772,25 +14191,7 @@ __metadata: languageName: node linkType: hard -"node-abi@npm:^3.3.0": - version: 3.77.0 - resolution: "node-abi@npm:3.77.0" - dependencies: - semver: ^7.3.5 - checksum: 62ab12fe90e2c2081c1e0dfc3819d60dc181aff36c5dd2ca99cece3f1f19efb284be90353bd0cb911c44f77a23ce111635937e8c6b48dd8cfaa24e34221d4a9f - languageName: node - linkType: hard - -"node-addon-api@npm:^7.0.0": - version: 7.1.1 - resolution: "node-addon-api@npm:7.1.1" - dependencies: - node-gyp: latest - checksum: 46051999e3289f205799dfaf6bcb017055d7569090f0004811110312e2db94cb4f8654602c7eb77a60a1a05142cc2b96e1b5c56ca4622c41a5c6370787faaf30 - languageName: node - linkType: hard - -"node-fetch@npm:^2.6.9": +"node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -15804,7 +14205,14 @@ __metadata: languageName: node linkType: hard -"node-forge@npm:^1, node-forge@npm:^1.3.1": +"node-forge@npm:^0.10.0": + version: 0.10.0 + resolution: "node-forge@npm:0.10.0" + checksum: 5aa6dc9922e424a20ef101d2f517418e2bc9cfc0255dd22e0701c0fad1568445f510ee67f6f3fcdf085812c4ca1b847b8ba45683b34776828e41f5c1794e42e1 + languageName: node + linkType: hard + +"node-forge@npm:^1.3.1": version: 1.3.1 resolution: "node-forge@npm:1.3.1" checksum: 08fb072d3d670599c89a1704b3e9c649ff1b998256737f0e06fbd1a5bf41cae4457ccaee32d95052d80bbafd9ffe01284e078c8071f0267dc9744e51c5ed42a9 @@ -15812,22 +14220,22 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 11.4.2 - resolution: "node-gyp@npm:11.4.2" + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" dependencies: env-paths: ^2.2.0 exponential-backoff: ^3.1.1 + glob: ^10.3.10 graceful-fs: ^4.2.6 - make-fetch-happen: ^14.0.3 - nopt: ^8.0.0 - proc-log: ^5.0.0 + make-fetch-happen: ^13.0.0 + nopt: ^7.0.0 + proc-log: ^3.0.0 semver: ^7.3.5 - tar: ^7.4.3 - tinyglobby: ^0.2.12 - which: ^5.0.0 + tar: ^6.1.2 + which: ^4.0.0 bin: node-gyp: bin/node-gyp.js - checksum: d8041cee7ec60c86fb2961d77c12a2d083a481fb28b08e6d9583153186c0e7766044dc30bdb1f3ac01ddc5763b83caeed3d1ea35787ec4ffd8cc4aeedfc34f2b + checksum: 72e2ab4b23fc32007a763da94018f58069fc0694bf36115d49a2b195c8831e12cf5dd1e7a3718fa85c06969aedf8fc126722d3b672ec1cb27e06ed33caee3c60 languageName: node linkType: hard @@ -15838,17 +14246,69 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.21": - version: 2.0.21 - resolution: "node-releases@npm:2.0.21" - checksum: 191f8245e18272971650eb45151c5891313bca27507a8f634085bd8c98a9cb9492686ef6182176866ceebff049646ef6cd5fb5ca46d5b5ca00ce2c69185d84c4 +"node-libs-browser@npm:^2.2.1": + version: 2.2.1 + resolution: "node-libs-browser@npm:2.2.1" + dependencies: + assert: ^1.1.1 + browserify-zlib: ^0.2.0 + buffer: ^4.3.0 + console-browserify: ^1.1.0 + constants-browserify: ^1.0.0 + crypto-browserify: ^3.11.0 + domain-browser: ^1.1.1 + events: ^3.0.0 + https-browserify: ^1.0.0 + os-browserify: ^0.3.0 + path-browserify: 0.0.1 + process: ^0.11.10 + punycode: ^1.2.4 + querystring-es3: ^0.2.0 + readable-stream: ^2.3.3 + stream-browserify: ^2.0.1 + stream-http: ^2.7.2 + string_decoder: ^1.0.0 + timers-browserify: ^2.0.4 + tty-browserify: 0.0.0 + url: ^0.11.0 + util: ^0.11.0 + vm-browserify: ^1.0.1 + checksum: 41fa7927378edc0cb98a8cc784d3f4a47e43378d3b42ec57a23f81125baa7287c4b54d6d26d062072226160a3ce4d8b7a62e873d2fb637aceaddf71f5a26eca0 + languageName: node + linkType: hard + +"node-notifier@npm:^8.0.0": + version: 8.0.2 + resolution: "node-notifier@npm:8.0.2" + dependencies: + growly: ^1.3.0 + is-wsl: ^2.2.0 + semver: ^7.3.2 + shellwords: ^0.1.1 + uuid: ^8.3.0 + which: ^2.0.2 + checksum: 7db1683003f6aaa4324959dfa663cd56e301ccc0165977a9e7737989ffe3b4763297f9fc85f44d0662b63a4fd85516eda43411b492a4d2fae207afb23773f912 + languageName: node + linkType: hard + +"node-releases@npm:^1.1.61": + version: 1.1.77 + resolution: "node-releases@npm:1.1.77" + checksum: eb2fcb45310e7d77f82bfdadeca546a698d258e011f15d88ad9a452a5e838a672ec532906581096ca19c66284a788330c3b09227ffc540e67228730f41b9c2e2 + languageName: node + linkType: hard + +"node-releases@npm:^2.0.14": + version: 2.0.14 + resolution: "node-releases@npm:2.0.14" + checksum: 59443a2f77acac854c42d321bf1b43dea0aef55cd544c6a686e9816a697300458d4e82239e2d794ea05f7bbbc8a94500332e2d3ac3f11f52e4b16cbe638b3c41 languageName: node linkType: hard "nodemailer@npm:^6.9.1": - version: 6.10.1 - resolution: "nodemailer@npm:6.10.1" - checksum: 39e9208e13c40b58c59242205bce855e74def25d953070ab6a5b1c23b0bf37df0725b3c6dea52d4220e2e60dd1fffcd486a697dece79afdf98842aae6395d393 + version: 6.9.13 + resolution: "nodemailer@npm:6.9.13" + checksum: 1b591ef480be2ff69480127cbff819e6593b1ef263b6f920e1a4e83e40280582daf7a14a809ef92f9828e2a70bdb3ce22b11924e209f2afe4975f9ff37e08e9d languageName: node linkType: hard @@ -15872,14 +14332,46 @@ __metadata: languageName: node linkType: hard -"nopt@npm:^8.0.0": - version: 8.1.0 - resolution: "nopt@npm:8.1.0" +"nopt@npm:^7.0.0": + version: 7.2.0 + resolution: "nopt@npm:7.2.0" dependencies: - abbrev: ^3.0.0 + abbrev: ^2.0.0 bin: nopt: bin/nopt.js - checksum: 49cfd3eb6f565e292bf61f2ff1373a457238804d5a5a63a8d786c923007498cba89f3648e3b952bc10203e3e7285752abf5b14eaf012edb821e84f24e881a92a + checksum: a9c0f57fb8cb9cc82ae47192ca2b7ef00e199b9480eed202482c962d61b59a7fbe7541920b2a5839a97b42ee39e288c0aed770e38057a608d7f579389dfde410 + languageName: node + linkType: hard + +"nopt@npm:~1.0.10": + version: 1.0.10 + resolution: "nopt@npm:1.0.10" + dependencies: + abbrev: 1 + bin: + nopt: ./bin/nopt.js + checksum: f62575aceaa3be43f365bf37a596b89bbac2e796b001b6d2e2a85c2140a4e378ff919e2753ccba959c4fd344776fc88c29b393bc167fa939fb1513f126f4cd45 + languageName: node + linkType: hard + +"normalize-package-data@npm:^2.3.2, normalize-package-data@npm:^2.5.0": + version: 2.5.0 + resolution: "normalize-package-data@npm:2.5.0" + dependencies: + hosted-git-info: ^2.1.4 + resolve: ^1.10.0 + semver: 2 || 3 || 4 || 5 + validate-npm-package-license: ^3.0.1 + checksum: 7999112efc35a6259bc22db460540cae06564aa65d0271e3bdfa86876d08b0e578b7b5b0028ee61b23f1cae9fc0e7847e4edc0948d3068a39a2a82853efc8499 + languageName: node + linkType: hard + +"normalize-path@npm:^2.1.1": + version: 2.1.1 + resolution: "normalize-path@npm:2.1.1" + dependencies: + remove-trailing-separator: ^1.0.1 + checksum: 7e9cbdcf7f5b8da7aa191fbfe33daf290cdcd8c038f422faf1b8a83c972bf7a6d94c5be34c4326cb00fb63bc0fd97d9fbcfaf2e5d6142332c2cd36d2e1b86cea languageName: node linkType: hard @@ -15897,14 +14389,35 @@ __metadata: languageName: node linkType: hard -"normalize-url@npm:^6.0.1": - version: 6.1.0 - resolution: "normalize-url@npm:6.1.0" - checksum: 4a4944631173e7d521d6b80e4c85ccaeceb2870f315584fa30121f505a6dfd86439c5e3fdd8cd9e0e291290c41d0c3599f0cb12ab356722ed242584c30348e50 +"normalize-url@npm:1.9.1": + version: 1.9.1 + resolution: "normalize-url@npm:1.9.1" + dependencies: + object-assign: ^4.0.1 + prepend-http: ^1.0.0 + query-string: ^4.1.0 + sort-keys: ^1.0.0 + checksum: 4b03c22bebbb822874ce3b9204367ad1f27c314ae09b13aa201de730b3cf95f00dadf378277a56062322968c95c06e5764d01474d26af8b43d20bc4c8c491f84 + languageName: node + linkType: hard + +"normalize-url@npm:^3.0.0": + version: 3.3.0 + resolution: "normalize-url@npm:3.3.0" + checksum: f6aa4a1a94c3b799812f3e7fc987fb4599d869bfa8e9a160b6f2c5a2b4e62ada998d64dca30d9e20769d8bd95d3da1da3d4841dba2cc3c4d85364e1eb46219a2 + languageName: node + linkType: hard + +"npm-run-path@npm:^2.0.0": + version: 2.0.2 + resolution: "npm-run-path@npm:2.0.2" + dependencies: + path-key: ^2.0.0 + checksum: acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 languageName: node linkType: hard -"npm-run-path@npm:^4.0.1": +"npm-run-path@npm:^4.0.0": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" dependencies: @@ -15931,31 +14444,52 @@ __metadata: languageName: node linkType: hard +"num2fraction@npm:^1.2.2": + version: 1.2.2 + resolution: "num2fraction@npm:1.2.2" + checksum: 1da9c6797b505d3f5b17c7f694c4fa31565bdd5c0e5d669553253aed848a580804cd285280e8a73148bd9628839267daee4967f24b53d4e893e44b563e412635 + languageName: node + linkType: hard + "nwsapi@npm:^2.2.0": - version: 2.2.22 - resolution: "nwsapi@npm:2.2.22" - checksum: 9491f0396d8aaf7fd1f9ebbbbff5d9bb9090e5d200263cf31b117bbaad7eb79da86b4c9b9bcd64c4b35f6d7e1630d14ee21c0959c01131e89c1c5e22d72530bf + version: 2.2.9 + resolution: "nwsapi@npm:2.2.9" + checksum: 3ab2bc47d5507a76e2fdee5aae7ea2875c6def912d0401126cad3e39825a7decb7a02622810c855a7902bd31e917e606b37882dca12b0ae54b4d3b70275de927 languageName: node linkType: hard -"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": +"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f languageName: node linkType: hard -"object-hash@npm:^3.0.0": - version: 3.0.0 - resolution: "object-hash@npm:3.0.0" - checksum: 80b4904bb3857c52cc1bfd0b52c0352532ca12ed3b8a6ff06a90cd209dfda1b95cee059a7625eb9da29537027f68ac4619363491eedb2f5d3dddbba97494fd6c +"object-copy@npm:^0.1.0": + version: 0.1.0 + resolution: "object-copy@npm:0.1.0" + dependencies: + copy-descriptor: ^0.1.0 + define-property: ^0.2.5 + kind-of: ^3.0.3 + checksum: a9e35f07e3a2c882a7e979090360d1a20ab51d1fa19dfdac3aa8873b328a7c4c7683946ee97c824ae40079d848d6740a3788fa14f2185155dab7ed970a72c783 + languageName: node + linkType: hard + +"object-inspect@npm:^1.13.1": + version: 1.13.1 + resolution: "object-inspect@npm:1.13.1" + checksum: 7d9fa9221de3311dcb5c7c307ee5dc011cdd31dc43624b7c184b3840514e118e05ef0002be5388304c416c0eb592feb46e983db12577fc47e47d5752fbbfb61f languageName: node linkType: hard -"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": - version: 1.13.4 - resolution: "object-inspect@npm:1.13.4" - checksum: 582810c6a8d2ef988ea0a39e69e115a138dad8f42dd445383b394877e5816eb4268489f316a6f74ee9c4e0a984b3eab1028e3e79d62b1ed67c726661d55c7a8b +"object-is@npm:^1.1.5": + version: 1.1.6 + resolution: "object-is@npm:1.1.6" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + checksum: 3ea22759967e6f2380a2cbbd0f737b42dc9ddb2dfefdb159a1b927fea57335e1b058b564bfa94417db8ad58cddab33621a035de6f5e5ad56d89f2dd03e66c6a1 languageName: node linkType: hard @@ -15966,33 +14500,39 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.1.4, object.assign@npm:^4.1.7": - version: 4.1.7 - resolution: "object.assign@npm:4.1.7" +"object-visit@npm:^1.0.0": + version: 1.0.1 + resolution: "object-visit@npm:1.0.1" + dependencies: + isobject: ^3.0.0 + checksum: b0ee07f5bf3bb881b881ff53b467ebbde2b37ebb38649d6944a6cd7681b32eedd99da9bd1e01c55facf81f54ed06b13af61aba6ad87f0052982995e09333f790 + languageName: node + linkType: hard + +"object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": + version: 4.1.5 + resolution: "object.assign@npm:4.1.5" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.3 + call-bind: ^1.0.5 define-properties: ^1.2.1 - es-object-atoms: ^1.0.0 - has-symbols: ^1.1.0 + has-symbols: ^1.0.3 object-keys: ^1.1.1 - checksum: 60e07d2651cf4f5528c485f1aa4dbded9b384c47d80e8187cefd11320abb1aebebf78df5483451dfa549059f8281c21f7b4bf7d19e9e5e97d8d617df0df298de + checksum: f9aeac0541661370a1fc86e6a8065eb1668d3e771f7dbb33ee54578201336c057b21ee61207a186dd42db0c62201d91aac703d20d12a79fc79c353eed44d4e25 languageName: node linkType: hard -"object.entries@npm:^1.1.9": - version: 1.1.9 - resolution: "object.entries@npm:1.1.9" +"object.entries@npm:^1.1.0, object.entries@npm:^1.1.7": + version: 1.1.8 + resolution: "object.entries@npm:1.1.8" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.4 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-object-atoms: ^1.1.1 - checksum: 0ab2ef331c4d6a53ff600a5d69182948d453107c3a1f7fd91bc29d387538c2aba21d04949a74f57c21907208b1f6fb175567fd1f39f1a7a4046ba1bca762fb41 + es-object-atoms: ^1.0.0 + checksum: 5314877cb637ef3437a30bba61d9bacdb3ce74bf73ac101518be0633c37840c8cc67407edb341f766e8093b3d7516d5c3358f25adfee4a2c697c0ec4c8491907 languageName: node linkType: hard -"object.fromentries@npm:^2.0.8": +"object.fromentries@npm:^2.0.7": version: 2.0.8 resolution: "object.fromentries@npm:2.0.8" dependencies: @@ -16004,7 +14544,7 @@ __metadata: languageName: node linkType: hard -"object.getownpropertydescriptors@npm:^2.1.0": +"object.getownpropertydescriptors@npm:^2.0.3, object.getownpropertydescriptors@npm:^2.1.0": version: 2.1.8 resolution: "object.getownpropertydescriptors@npm:2.1.8" dependencies: @@ -16019,7 +14559,7 @@ __metadata: languageName: node linkType: hard -"object.groupby@npm:^1.0.3": +"object.groupby@npm:^1.0.1": version: 1.0.3 resolution: "object.groupby@npm:1.0.3" dependencies: @@ -16030,15 +14570,34 @@ __metadata: languageName: node linkType: hard -"object.values@npm:^1.1.0, object.values@npm:^1.1.6, object.values@npm:^1.2.1": - version: 1.2.1 - resolution: "object.values@npm:1.2.1" +"object.hasown@npm:^1.1.3": + version: 1.1.4 + resolution: "object.hasown@npm:1.1.4" + dependencies: + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-object-atoms: ^1.0.0 + checksum: bc46eb5ca22106fcd07aab1411508c2c68b7565fe8fb272f166fb9bf203972e8b5c86a5a4b2c86204beead0626a7a4119d32cefbaf7c5dd57b400bf9e6363cb6 + languageName: node + linkType: hard + +"object.pick@npm:^1.3.0": + version: 1.3.0 + resolution: "object.pick@npm:1.3.0" + dependencies: + isobject: ^3.0.1 + checksum: 77fb6eed57c67adf75e9901187e37af39f052ef601cb4480386436561357eb9e459e820762f01fd02c5c1b42ece839ad393717a6d1850d848ee11fbabb3e580a + languageName: node + linkType: hard + +"object.values@npm:^1.1.0, object.values@npm:^1.1.6, object.values@npm:^1.1.7": + version: 1.2.0 + resolution: "object.values@npm:1.2.0" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.3 + call-bind: ^1.0.7 define-properties: ^1.2.1 es-object-atoms: ^1.0.0 - checksum: f9b9a2a125ccf8ded29414d7c056ae0d187b833ee74919821fc60d7e216626db220d9cb3cf33f965c84aaaa96133626ca13b80f3c158b673976dc8cfcfcd26bb + checksum: 51fef456c2a544275cb1766897f34ded968b22adfc13ba13b5e4815fdaf4304a90d42a3aee114b1f1ede048a4890381d47a5594d84296f2767c6a0364b9da8fa languageName: node linkType: hard @@ -16056,7 +14615,7 @@ __metadata: languageName: node linkType: hard -"on-finished@npm:2.4.1, on-finished@npm:^2.4.1": +"on-finished@npm:2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -16065,10 +14624,10 @@ __metadata: languageName: node linkType: hard -"on-headers@npm:~1.1.0": - version: 1.1.0 - resolution: "on-headers@npm:1.1.0" - checksum: 98aa64629f986fb8cc4517dd8bede73c980e31208cba97f4442c330959f60ced3dc6214b83420491f5111fc7c4f4343abe2ea62c85f505cf041d67850f238776 +"on-headers@npm:~1.0.2": + version: 1.0.2 + resolution: "on-headers@npm:1.0.2" + checksum: 2bf13467215d1e540a62a75021e8b318a6cfc5d4fc53af8e8f84ad98dbcea02d506c6d24180cd62e1d769c44721ba542f3154effc1f7579a8288c9f7873ed8e5 languageName: node linkType: hard @@ -16081,7 +14640,7 @@ __metadata: languageName: node linkType: hard -"onetime@npm:^5.1.2": +"onetime@npm:^5.1.0": version: 5.1.2 resolution: "onetime@npm:5.1.2" dependencies: @@ -16090,14 +14649,34 @@ __metadata: languageName: node linkType: hard -"open@npm:^8.0.9, open@npm:^8.4.0": - version: 8.4.2 - resolution: "open@npm:8.4.2" +"open@npm:^7.0.2": + version: 7.4.2 + resolution: "open@npm:7.4.2" dependencies: - define-lazy-prop: ^2.0.0 - is-docker: ^2.1.1 - is-wsl: ^2.2.0 - checksum: 6388bfff21b40cb9bd8f913f9130d107f2ed4724ea81a8fd29798ee322b361ca31fa2cdfb491a5c31e43a3996cfe9566741238c7a741ada8d7af1cb78d85cf26 + is-docker: ^2.0.0 + is-wsl: ^2.1.1 + checksum: 3333900ec0e420d64c23b831bc3467e57031461d843c801f569b2204a1acc3cd7b3ec3c7897afc9dde86491dfa289708eb92bba164093d8bd88fb2c231843c91 + languageName: node + linkType: hard + +"opn@npm:^5.5.0": + version: 5.5.0 + resolution: "opn@npm:5.5.0" + dependencies: + is-wsl: ^1.1.0 + checksum: 35b677b5a1fd6c8cb1996b0607671ba79f7ce9fa029217d54eafaf6bee13eb7e700691c6a415009140fd02a435fffdfd143875f3b233b60f3f9d631c6f6b81a0 + languageName: node + linkType: hard + +"optimize-css-assets-webpack-plugin@npm:5.0.4": + version: 5.0.4 + resolution: "optimize-css-assets-webpack-plugin@npm:5.0.4" + dependencies: + cssnano: ^4.1.10 + last-call-webpack-plugin: ^3.0.0 + peerDependencies: + webpack: ^4.0.0 + checksum: bcd509eaab2a6f0ed8396fe847f4f0da73655a54f4c418fa30dc1fc4a0b1b620f38e2fcd6bcb369e2a6cf4530995b371e9d12011566ac7ffe6ac6aec2ab0a4fb languageName: node linkType: hard @@ -16115,35 +14694,62 @@ __metadata: languageName: node linkType: hard -"optionator@npm:^0.9.1, optionator@npm:^0.9.3": - version: 0.9.4 - resolution: "optionator@npm:0.9.4" +"optionator@npm:^0.9.1": + version: 0.9.3 + resolution: "optionator@npm:0.9.3" dependencies: + "@aashutoshrathi/word-wrap": ^1.2.3 deep-is: ^0.1.3 fast-levenshtein: ^2.0.6 levn: ^0.4.1 prelude-ls: ^1.2.1 type-check: ^0.4.0 - word-wrap: ^1.2.5 - checksum: ecbd010e3dc73e05d239976422d9ef54a82a13f37c11ca5911dff41c98a6c7f0f163b27f922c37e7f8340af9d36febd3b6e9cef508f3339d4c393d7276d716bb + checksum: 09281999441f2fe9c33a5eeab76700795365a061563d66b098923eb719251a42bdbe432790d35064d0816ead9296dbeb1ad51a733edf4167c96bd5d0882e428a languageName: node linkType: hard -"outvariant@npm:^1.4.0, outvariant@npm:^1.4.3": - version: 1.4.3 - resolution: "outvariant@npm:1.4.3" - checksum: 4a3551fb2b45309e585eebf88bad094dbe56ac6d3a28d59dd2e4050b431aa2beb6097a0763fce3cd82ca0f077026f380a9b60fffc306aaf430141421e7a7b6ed +"ora@npm:^5.4.1": + version: 5.4.1 + resolution: "ora@npm:5.4.1" + 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 + checksum: 28d476ee6c1049d68368c0dc922e7225e3b5600c3ede88fade8052837f9ed342625fdaa84a6209302587c8ddd9b664f71f0759833cbdb3a4cf81344057e63c63 languageName: node linkType: hard -"own-keys@npm:^1.0.1": - version: 1.0.1 - resolution: "own-keys@npm:1.0.1" - dependencies: - get-intrinsic: ^1.2.6 - object-keys: ^1.1.1 - safe-push-apply: ^1.0.0 - checksum: cc9dd7d85c4ccfbe8109fce307d581ac7ede7b26de892b537873fbce2dc6a206d89aea0630dbb98e47ce0873517cefeaa7be15fcf94aaf4764a3b34b474a5b61 +"os-browserify@npm:^0.3.0": + version: 0.3.0 + resolution: "os-browserify@npm:0.3.0" + checksum: 16e37ba3c0e6a4c63443c7b55799ce4066d59104143cb637ecb9fce586d5da319cdca786ba1c867abbe3890d2cbf37953f2d51eea85e20dd6c4570d6c54bfebf + languageName: node + linkType: hard + +"os-tmpdir@npm:~1.0.2": + version: 1.0.2 + resolution: "os-tmpdir@npm:1.0.2" + checksum: 5666560f7b9f10182548bf7013883265be33620b1c1b4a4d405c25be2636f970c5488ff3e6c48de75b55d02bde037249fe5dbfbb4c0fb7714953d56aed062e6d + languageName: node + linkType: hard + +"outvariant@npm:^1.2.1, outvariant@npm:^1.3.0": + version: 1.4.2 + resolution: "outvariant@npm:1.4.2" + checksum: 5d9e2b3edb1cc8be9cbfc1c8c97e8b05137c4384bbfc56e0a465de26c5d2f023e65732ddcda9d46599b06d667fbc0de32c30d2ecd11f6f3f43bcf8ce0d320918 + languageName: node + linkType: hard + +"p-each-series@npm:^2.1.0": + version: 2.2.0 + resolution: "p-each-series@npm:2.2.0" + checksum: 5fbe2f1f1966f55833bd401fe36f7afe410707d5e9fb6032c6dde8aa716d50521c3bb201fdb584130569b5941d5e84993e09e0b3f76a474288e0ede8f632983c languageName: node linkType: hard @@ -16172,6 +14778,15 @@ __metadata: languageName: node linkType: hard +"p-limit@npm:^4.0.0": + version: 4.0.0 + resolution: "p-limit@npm:4.0.0" + dependencies: + yocto-queue: ^1.0.0 + checksum: 01d9d70695187788f984226e16c903475ec6a947ee7b21948d6f597bed788e3112cc7ec2e171c1d37125057a5f45f3da21d8653e04a3a793589e12e9e80e756b + languageName: node + linkType: hard + "p-locate@npm:^3.0.0": version: 3.0.0 resolution: "p-locate@npm:3.0.0" @@ -16190,23 +14805,23 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^5.0.0": - version: 5.0.0 - resolution: "p-locate@npm:5.0.0" - dependencies: - p-limit: ^3.0.2 - checksum: 1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 +"p-map@npm:^2.0.0": + version: 2.1.0 + resolution: "p-map@npm:2.1.0" + checksum: 9e3ad3c9f6d75a5b5661bcad78c91f3a63849189737cd75e4f1225bf9ac205194e5c44aac2ef6f09562b1facdb9bd1425584d7ac375bfaa17b3f1a142dab936d languageName: node linkType: hard -"p-map@npm:^7.0.2": - version: 7.0.3 - resolution: "p-map@npm:7.0.3" - checksum: 8c92d533acf82f0d12f7e196edccff773f384098bbb048acdd55a08778ce4fc8889d8f1bde72969487bd96f9c63212698d79744c20bedfce36c5b00b46d369f8 +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: ^3.0.0 + checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c languageName: node linkType: hard -"p-queue@npm:^6": +"p-queue@npm:^6.6.1": version: 6.6.2 resolution: "p-queue@npm:6.6.2" dependencies: @@ -16216,7 +14831,16 @@ __metadata: languageName: node linkType: hard -"p-retry@npm:^4, p-retry@npm:^4.5.0": +"p-retry@npm:^3.0.1": + version: 3.0.1 + resolution: "p-retry@npm:3.0.1" + dependencies: + retry: ^0.12.0 + checksum: 702efc63fc13ef7fc0bab9a1b08432ab38a0236efcbce64af0cf692030ba6ed8009f29ba66e3301cb98dc69ef33e7ccab29ba1ac2bea897f802f81f4f7e468dd + languageName: node + linkType: hard + +"p-retry@npm:^4.0.0": version: 4.6.2 resolution: "p-retry@npm:4.6.2" dependencies: @@ -16242,21 +14866,25 @@ __metadata: languageName: node linkType: hard -"package-json-from-dist@npm:^1.0.0": - version: 1.0.1 - resolution: "package-json-from-dist@npm:1.0.1" - checksum: 58ee9538f2f762988433da00e26acc788036914d57c71c246bf0be1b60cdbd77dd60b6a3e1a30465f0b248aeb80079e0b34cb6050b1dfa18c06953bb1cbc7602 - languageName: node - linkType: hard - -"pako@npm:^1.0.10, pako@npm:^1.0.11, pako@npm:^1.0.6": +"pako@npm:^1.0.10, pako@npm:^1.0.11, pako@npm:^1.0.6, pako@npm:~1.0.5": version: 1.0.11 resolution: "pako@npm:1.0.11" checksum: 1be2bfa1f807608c7538afa15d6f25baa523c30ec870a3228a89579e474a4d992f4293859524e46d5d87fd30fa17c5edf34dbef0671251d9749820b488660b16 languageName: node linkType: hard -"param-case@npm:^3.0.4": +"parallel-transform@npm:^1.1.0": + version: 1.2.0 + resolution: "parallel-transform@npm:1.2.0" + dependencies: + cyclist: ^1.0.1 + inherits: ^2.0.3 + readable-stream: ^2.1.5 + checksum: ab6ddc1a662cefcfb3d8d546a111763d3b223f484f2e9194e33aefd8f6760c319d0821fd22a00a3adfbd45929b50d2c84cc121389732f013c2ae01c226269c27 + languageName: node + linkType: hard + +"param-case@npm:^3.0.3, param-case@npm:^3.0.4": version: 3.0.4 resolution: "param-case@npm:3.0.4" dependencies: @@ -16275,22 +14903,45 @@ __metadata: languageName: node linkType: hard -"parse-entities@npm:^4.0.0": - version: 4.0.2 - resolution: "parse-entities@npm:4.0.2" +"parse-asn1@npm:^5.0.0, parse-asn1@npm:^5.1.7": + version: 5.1.7 + resolution: "parse-asn1@npm:5.1.7" dependencies: - "@types/unist": ^2.0.0 - character-entities-legacy: ^3.0.0 - character-reference-invalid: ^2.0.0 - decode-named-character-reference: ^1.0.0 - is-alphanumerical: ^2.0.0 - is-decimal: ^2.0.0 - is-hexadecimal: ^2.0.0 - checksum: db22b46da1a62af00409c929ac49fbd306b5ebf0dbacf4646d2ae2b58616ef90a40eedc282568a3cf740fac2a7928bc97146973a628f6977ca274dedc2ad6edc + asn1.js: ^4.10.1 + browserify-aes: ^1.2.0 + evp_bytestokey: ^1.0.3 + hash-base: ~3.0 + pbkdf2: ^3.1.2 + safe-buffer: ^5.2.1 + checksum: 93c7194c1ed63a13e0b212d854b5213ad1aca0ace41c66b311e97cca0519cf9240f79435a0306a3b412c257f0ea3f1953fd0d9549419a0952c9e995ab361fd6c + languageName: node + linkType: hard + +"parse-entities@npm:^2.0.0": + version: 2.0.0 + resolution: "parse-entities@npm:2.0.0" + dependencies: + character-entities: ^1.0.0 + character-entities-legacy: ^1.0.0 + character-reference-invalid: ^1.0.0 + is-alphanumerical: ^1.0.0 + is-decimal: ^1.0.0 + is-hexadecimal: ^1.0.0 + checksum: 7addfd3e7d747521afac33c8121a5f23043c6973809756920d37e806639b4898385d386fcf4b3c8e2ecf1bc28aac5ae97df0b112d5042034efbe80f44081ebce + languageName: node + linkType: hard + +"parse-json@npm:^4.0.0": + version: 4.0.0 + resolution: "parse-json@npm:4.0.0" + dependencies: + error-ex: ^1.3.1 + json-parse-better-errors: ^1.0.1 + checksum: 0fe227d410a61090c247e34fa210552b834613c006c2c64d9a05cfe9e89cf8b4246d1246b1a99524b53b313e9ac024438d0680f67e33eaed7e6f38db64cfe7b5 languageName: node linkType: hard -"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": +"parse-json@npm:^5.0.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" dependencies: @@ -16309,7 +14960,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": +"parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 @@ -16326,6 +14977,20 @@ __metadata: languageName: node linkType: hard +"pascalcase@npm:^0.1.1": + version: 0.1.1 + resolution: "pascalcase@npm:0.1.1" + checksum: f83681c3c8ff75fa473a2bb2b113289952f802ff895d435edd717e7cb898b0408cbdb247117a938edcbc5d141020909846cc2b92c47213d764e2a94d2ad2b925 + languageName: node + linkType: hard + +"path-browserify@npm:0.0.1": + version: 0.0.1 + resolution: "path-browserify@npm:0.0.1" + checksum: ae8dcd45d0d3cfbaf595af4f206bf3ed82d77f72b4877ae7e77328079e1468c84f9386754bb417d994d5a19bf47882fd253565c18441cd5c5c90ae5187599e35 + languageName: node + linkType: hard + "path-case@npm:^3.0.4": version: 3.0.4 resolution: "path-case@npm:3.0.4" @@ -16336,6 +15001,13 @@ __metadata: languageName: node linkType: hard +"path-dirname@npm:^1.0.0": + version: 1.0.2 + resolution: "path-dirname@npm:1.0.2" + checksum: 0d2f6604ae05a252a0025318685f290e2764ecf9c5436f203cdacfc8c0b17c24cdedaa449d766beb94ab88cc7fc70a09ec21e7933f31abc2b719180883e5e33f + languageName: node + linkType: hard + "path-exists@npm:^3.0.0": version: 3.0.0 resolution: "path-exists@npm:3.0.0" @@ -16357,6 +15029,20 @@ __metadata: languageName: node linkType: hard +"path-is-inside@npm:^1.0.2": + version: 1.0.2 + resolution: "path-is-inside@npm:1.0.2" + checksum: 0b5b6c92d3018b82afb1f74fe6de6338c4c654de4a96123cb343f2b747d5606590ac0c890f956ed38220a4ab59baddfd7b713d78a62d240b20b14ab801fa02cb + languageName: node + linkType: hard + +"path-key@npm:^2.0.0, path-key@npm:^2.0.1": + version: 2.0.1 + resolution: "path-key@npm:2.0.1" + checksum: f7ab0ad42fe3fb8c7f11d0c4f849871e28fbd8e1add65c370e422512fc5887097b9cf34d09c1747d45c942a8c1e26468d6356e2df3f740bf177ab8ca7301ebfd + languageName: node + linkType: hard + "path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -16364,60 +15050,43 @@ __metadata: languageName: node linkType: hard -"path-parse@npm:^1.0.7": +"path-parse@npm:^1.0.6, path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a languageName: node linkType: hard -"path-scurry@npm:^1.11.1": - version: 1.11.1 - resolution: "path-scurry@npm:1.11.1" +"path-scurry@npm:^1.10.2": + version: 1.10.2 + resolution: "path-scurry@npm:1.10.2" dependencies: lru-cache: ^10.2.0 minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 - checksum: 890d5abcd593a7912dcce7cf7c6bf7a0b5648e3dee6caf0712c126ca0a65c7f3d7b9d769072a4d1baf370f61ce493ab5b038d59988688e0c5f3f646ee3c69023 - languageName: node - linkType: hard - -"path-scurry@npm:^2.0.0": - version: 2.0.0 - resolution: "path-scurry@npm:2.0.0" - dependencies: - lru-cache: ^11.0.0 - minipass: ^7.1.2 - checksum: 9953ce3857f7e0796b187a7066eede63864b7e1dfc14bf0484249801a5ab9afb90d9a58fc533ebb1b552d23767df8aa6a2c6c62caf3f8a65f6ce336a97bbb484 + checksum: 6739b4290f7d1a949c61c758b481c07ac7d1a841964c68cf5e1fa153d7e18cbde4872b37aadf9c5173c800d627f219c47945859159de36c977dd82419997b9b8 languageName: node linkType: hard -"path-to-regexp@npm:0.1.12": - version: 0.1.12 - resolution: "path-to-regexp@npm:0.1.12" - checksum: ab237858bee7b25ecd885189f175ab5b5161e7b712b360d44f5c4516b8d271da3e4bf7bf0a7b9153ecb04c7d90ce8ff5158614e1208819cf62bac2b08452722e +"path-to-regexp@npm:0.1.7": + version: 0.1.7 + resolution: "path-to-regexp@npm:0.1.7" + checksum: 69a14ea24db543e8b0f4353305c5eac6907917031340e5a8b37df688e52accd09e3cebfe1660b70d76b6bd89152f52183f28c74813dbf454ba1a01c82a38abce languageName: node linkType: hard "path-to-regexp@npm:^1.7.0": - version: 1.9.0 - resolution: "path-to-regexp@npm:1.9.0" + version: 1.8.0 + resolution: "path-to-regexp@npm:1.8.0" dependencies: isarray: 0.0.1 - checksum: 5b2ac9cab2a9f82effd30a35164b20998b18d99d96608281dd2cab6e66c0e4536187970369b185ab21d3815da1ecb7dcb2d5f97a4bf0ee6e31a9612299fca147 - languageName: node - linkType: hard - -"path-to-regexp@npm:^6.3.0": - version: 6.3.0 - resolution: "path-to-regexp@npm:6.3.0" - checksum: eca78602e6434a1b6799d511d375ec044e8d7e28f5a48aa5c28d57d8152fb52f3fc62fb1cfc5dfa2198e1f041c2a82ed14043d75740a2fe60e91b5089a153250 + checksum: 709f6f083c0552514ef4780cb2e7e4cf49b0cc89a97439f2b7cc69a608982b7690fb5d1720a7473a59806508fc2dae0be751ba49f495ecf89fd8fbc62abccbcd languageName: node linkType: hard -"path-to-regexp@npm:^8.0.0": - version: 8.3.0 - resolution: "path-to-regexp@npm:8.3.0" - checksum: 73e0d3db449f9899692b10be8480bbcfa294fd575be2d09bce3e63f2f708d1fccd3aaa8591709f8b82062c528df116e118ff9df8f5c52ccc4c2443a90be73e10 +"path-to-regexp@npm:^6.2.0": + version: 6.2.2 + resolution: "path-to-regexp@npm:6.2.2" + checksum: b7b0005c36f5099f9ed1fb20a820d2e4ed1297ffe683ea1d678f5e976eb9544f01debb281369dabdc26da82e6453901bf71acf2c7ed14b9243536c2a45286c33 languageName: node linkType: hard @@ -16428,31 +15097,30 @@ __metadata: languageName: node linkType: hard -"path2d@npm:^0.2.1": - version: 0.2.2 - resolution: "path2d@npm:0.2.2" - checksum: 06f07f20797163d9807c211bc3e2b4edac462790c0cbe774bc681f18cfeba27a7cdd2d539e62a6863ff8d0fcfe4c5f6f20463b608f3dd32e44bba7be6f632f04 - languageName: node - linkType: hard - -"pathe@npm:^1.1.2": +"pathe@npm:^1.1.1, pathe@npm:^1.1.2": version: 1.1.2 resolution: "pathe@npm:1.1.2" checksum: ec5f778d9790e7b9ffc3e4c1df39a5bb1ce94657a4e3ad830c1276491ca9d79f189f47609884671db173400256b005f4955f7952f52a2aeb5834ad5fb4faf134 languageName: node linkType: hard -"pathe@npm:^2.0.3": - version: 2.0.3 - resolution: "pathe@npm:2.0.3" - checksum: 0602bdd4acb54d91044e0c56f1fb63467ae7d44ab3afea1f797947b0eb2b4d1d91cf0d58d065fdb0a8ab0c4acbbd8d3a5b424983eaf10dd5285d37a16f6e3ee9 +"pathval@npm:^1.1.1": + version: 1.1.1 + resolution: "pathval@npm:1.1.1" + checksum: 090e3147716647fb7fb5b4b8c8e5b55e5d0a6086d085b6cd23f3d3c01fcf0ff56fd3cc22f2f4a033bd2e46ed55d61ed8379e123b42afe7d531a2a5fc8bb556d6 languageName: node linkType: hard -"pathval@npm:^2.0.0": - version: 2.0.1 - resolution: "pathval@npm:2.0.1" - checksum: 280e71cfd86bb5d7ff371fe2752997e5fa82901fcb209abf19d4457b7814f1b4a17845dfb17bd28a596ccdb0ecea178720ce23dacfa9c841f37804b700647810 +"pbkdf2@npm:^3.0.3, pbkdf2@npm:^3.1.2": + version: 3.1.2 + resolution: "pbkdf2@npm:3.1.2" + dependencies: + create-hash: ^1.1.2 + create-hmac: ^1.1.4 + ripemd160: ^2.0.1 + safe-buffer: ^5.0.1 + sha.js: ^2.4.8 + checksum: 2c950a100b1da72123449208e231afc188d980177d021d7121e96a2de7f2abbc96ead2b87d03d8fe5c318face097f203270d7e27908af9f471c165a4e8e69c92 languageName: node linkType: hard @@ -16468,21 +15136,6 @@ __metadata: languageName: node linkType: hard -"pdfjs-dist@npm:4.8.69": - version: 4.8.69 - resolution: "pdfjs-dist@npm:4.8.69" - dependencies: - canvas: ^3.0.0-rc2 - path2d: ^0.2.1 - dependenciesMeta: - canvas: - optional: true - path2d: - optional: true - checksum: 6c26d79a3f8796c7bb9f9ecabbf4c356edac3fb32e5ecb86b8ca649b4a217221c486df416b704a52ea0643aad9f29ad30b05ec6f894b3f95194fb001b7841058 - languageName: node - linkType: hard - "performance-now@npm:^2.1.0": version: 2.1.0 resolution: "performance-now@npm:2.1.0" @@ -16490,13 +15143,6 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:1.1.1, picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": - version: 1.1.1 - resolution: "picocolors@npm:1.1.1" - checksum: e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 - languageName: node - linkType: hard - "picocolors@npm:^0.2.1": version: 0.2.1 resolution: "picocolors@npm:0.2.1" @@ -16504,908 +15150,997 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf +"picocolors@npm:^1.0.0": + version: 1.0.0 + resolution: "picocolors@npm:1.0.0" + checksum: a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 + languageName: node + linkType: hard + +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf + languageName: node + linkType: hard + +"pify@npm:^2.0.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + languageName: node + linkType: hard + +"pify@npm:^3.0.0": + version: 3.0.0 + resolution: "pify@npm:3.0.0" + checksum: 6cdcbc3567d5c412450c53261a3f10991665d660961e06605decf4544a61a97a54fefe70a68d5c37080ff9d6f4cf51444c90198d1ba9f9309a6c0d6e9f5c4fde + languageName: node + linkType: hard + +"pify@npm:^4.0.1": + version: 4.0.1 + resolution: "pify@npm:4.0.1" + checksum: 9c4e34278cb09987685fa5ef81499c82546c033713518f6441778fbec623fc708777fe8ac633097c72d88470d5963094076c7305cafc7ad340aae27cfacd856b + languageName: node + linkType: hard + +"pinkie-promise@npm:^2.0.0": + version: 2.0.1 + resolution: "pinkie-promise@npm:2.0.1" + dependencies: + pinkie: ^2.0.0 + checksum: b53a4a2e73bf56b6f421eef711e7bdcb693d6abb474d57c5c413b809f654ba5ee750c6a96dd7225052d4b96c4d053cdcb34b708a86fceed4663303abee52fcca + languageName: node + linkType: hard + +"pinkie@npm:^2.0.0": + version: 2.0.4 + resolution: "pinkie@npm:2.0.4" + checksum: b12b10afea1177595aab036fc220785488f67b4b0fc49e7a27979472592e971614fa1c728e63ad3e7eb748b4ec3c3dbd780819331dad6f7d635c77c10537b9db + languageName: node + linkType: hard + +"pirates@npm:^4.0.1": + version: 4.0.6 + resolution: "pirates@npm:4.0.6" + checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 + languageName: node + linkType: hard + +"pkg-dir@npm:^3.0.0": + version: 3.0.0 + resolution: "pkg-dir@npm:3.0.0" + dependencies: + find-up: ^3.0.0 + checksum: 70c9476ffefc77552cc6b1880176b71ad70bfac4f367604b2b04efd19337309a4eec985e94823271c7c0e83946fa5aeb18cd360d15d10a5d7533e19344bfa808 + languageName: node + linkType: hard + +"pkg-dir@npm:^4.1.0, pkg-dir@npm:^4.2.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: ^4.0.0 + checksum: 9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 + languageName: node + linkType: hard + +"pkg-types@npm:^1.0.3": + version: 1.1.0 + resolution: "pkg-types@npm:1.1.0" + dependencies: + confbox: ^0.1.7 + mlly: ^1.6.1 + pathe: ^1.1.2 + checksum: 9cd3684e308c622db79efc8edc9291662e01cb42ed624ea2fa5400fb6eab94679b4e5b28808e9b763298a023c2381fd72a363a1c84a9073c96609af4c5c59f8f + languageName: node + linkType: hard + +"pkg-up@npm:3.1.0": + version: 3.1.0 + resolution: "pkg-up@npm:3.1.0" + dependencies: + find-up: ^3.0.0 + checksum: 5bac346b7c7c903613c057ae3ab722f320716199d753f4a7d053d38f2b5955460f3e6ab73b4762c62fd3e947f58e04f1343e92089e7bb6091c90877406fcd8c8 + languageName: node + linkType: hard + +"pnp-webpack-plugin@npm:1.6.4": + version: 1.6.4 + resolution: "pnp-webpack-plugin@npm:1.6.4" + dependencies: + ts-pnp: ^1.1.6 + checksum: 0606a63db96400b07f182300168298da9518727a843f9e10cf5045d2a102a4be06bb18c73dc481281e3e0f1ed8d04ef0d285a342b6dcd0eff1340e28e5d2328d + languageName: node + linkType: hard + +"portfinder@npm:^1.0.26": + version: 1.0.32 + resolution: "portfinder@npm:1.0.32" + dependencies: + async: ^2.6.4 + debug: ^3.2.7 + mkdirp: ^0.5.6 + checksum: 116b4aed1b9e16f6d5503823d966d9ffd41b1c2339e27f54c06cd2f3015a9d8ef53e2a53b57bc0a25af0885977b692007353aa28f9a0a98a44335cb50487240d + languageName: node + linkType: hard + +"posix-character-classes@npm:^0.1.0": + version: 0.1.1 + resolution: "posix-character-classes@npm:0.1.1" + checksum: dedb99913c60625a16050cfed2fb5c017648fc075be41ac18474e1c6c3549ef4ada201c8bd9bd006d36827e289c571b6092e1ef6e756cdbab2fd7046b25c6442 + languageName: node + linkType: hard + +"possible-typed-array-names@npm:^1.0.0": + version: 1.0.0 + resolution: "possible-typed-array-names@npm:1.0.0" + checksum: b32d403ece71e042385cc7856385cecf1cd8e144fa74d2f1de40d1e16035dba097bc189715925e79b67bdd1472796ff168d3a90d296356c9c94d272d5b95f3ae languageName: node linkType: hard -"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": - version: 4.0.3 - resolution: "picomatch@npm:4.0.3" - checksum: 6817fb74eb745a71445debe1029768de55fd59a42b75606f478ee1d0dc1aa6e78b711d041a7c9d5550e042642029b7f373dc1a43b224c4b7f12d23436735dba0 +"postcss-attribute-case-insensitive@npm:^4.0.1": + version: 4.0.2 + resolution: "postcss-attribute-case-insensitive@npm:4.0.2" + dependencies: + postcss: ^7.0.2 + postcss-selector-parser: ^6.0.2 + checksum: e9cf4b61f443bf302dcd1110ef38d6a808fa38ae5d85bfd0aaaa6d35bef3825e0434f1aed8eb9596a5d88f21580ce8b9cd0098414d8490293ef71149695cae9a languageName: node linkType: hard -"pify@npm:^2.3.0": - version: 2.3.0 - resolution: "pify@npm:2.3.0" - checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba +"postcss-browser-comments@npm:^3.0.0": + version: 3.0.0 + resolution: "postcss-browser-comments@npm:3.0.0" + dependencies: + postcss: ^7 + peerDependencies: + browserslist: ^4 + checksum: 6e8cfae4c71cf7b5d4741e19021f3e3d81d772372a9e12f5c675e25bc3ea45fe5154fd0ee055ee041aee8b484c59875fdf15df3cec5e7fd4cf3209bc5ef0b515 languageName: node linkType: hard -"pirates@npm:^4.0.1, pirates@npm:^4.0.4": - version: 4.0.7 - resolution: "pirates@npm:4.0.7" - checksum: 3dcbaff13c8b5bc158416feb6dc9e49e3c6be5fddc1ea078a05a73ef6b85d79324bbb1ef59b954cdeff000dbf000c1d39f32dc69310c7b78fbada5171b583e40 +"postcss-calc@npm:^7.0.1": + version: 7.0.5 + resolution: "postcss-calc@npm:7.0.5" + dependencies: + postcss: ^7.0.27 + postcss-selector-parser: ^6.0.2 + postcss-value-parser: ^4.0.2 + checksum: 03640d493fb0e557634ab23e5d1eb527b014fb491ac3e62b45e28f5a6ef57e25a209f82040ce54c40d5a1a7307597a55d3fa6e8cece0888261a66bc75e39a68b languageName: node linkType: hard -"pkg-dir@npm:^4.1.0, pkg-dir@npm:^4.2.0": - version: 4.2.0 - resolution: "pkg-dir@npm:4.2.0" +"postcss-color-functional-notation@npm:^2.0.1": + version: 2.0.1 + resolution: "postcss-color-functional-notation@npm:2.0.1" dependencies: - find-up: ^4.0.0 - checksum: 9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 + postcss: ^7.0.2 + postcss-values-parser: ^2.0.0 + checksum: 0bfd1fa93bc54a07240d821d091093256511f70f0df5349e27e4d8b034ee3345f0ae58674ce425be6a91cc934325b2ce36ecddbf958fa8805fed6647cf671348 languageName: node linkType: hard -"pkg-up@npm:^3.1.0": - version: 3.1.0 - resolution: "pkg-up@npm:3.1.0" +"postcss-color-gray@npm:^5.0.0": + version: 5.0.0 + resolution: "postcss-color-gray@npm:5.0.0" dependencies: - find-up: ^3.0.0 - checksum: 5bac346b7c7c903613c057ae3ab722f320716199d753f4a7d053d38f2b5955460f3e6ab73b4762c62fd3e947f58e04f1343e92089e7bb6091c90877406fcd8c8 + "@csstools/convert-colors": ^1.4.0 + postcss: ^7.0.5 + postcss-values-parser: ^2.0.0 + checksum: 81a62b3e2c170ffadc085c1643a7b5f1c153837d7ca228b07df88b9aeb0ec9088a92f8d919a748137ead3936e8dac2606e32b14b5166a59143642c8573949db5 languageName: node linkType: hard -"possible-typed-array-names@npm:^1.0.0": - version: 1.1.0 - resolution: "possible-typed-array-names@npm:1.1.0" - checksum: cfcd4f05264eee8fd184cd4897a17890561d1d473434b43ab66ad3673d9c9128981ec01e0cb1d65a52cd6b1eebfb2eae1e53e39b2e0eca86afc823ede7a4f41b +"postcss-color-hex-alpha@npm:^5.0.3": + version: 5.0.3 + resolution: "postcss-color-hex-alpha@npm:5.0.3" + dependencies: + postcss: ^7.0.14 + postcss-values-parser: ^2.0.1 + checksum: 0a0ccb42c7c6a271ffd3c8b123b9c67744827d4b810b759731bc702fea1e00f05f08479ec7cbd8dfa47bc20510830a69f1e316a5724b9e53d5fdc6fabf90afc4 languageName: node linkType: hard -"postcss-attribute-case-insensitive@npm:^5.0.2": - version: 5.0.2 - resolution: "postcss-attribute-case-insensitive@npm:5.0.2" +"postcss-color-mod-function@npm:^3.0.3": + version: 3.0.3 + resolution: "postcss-color-mod-function@npm:3.0.3" dependencies: - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.2 - checksum: c0b8139f37e68dba372724cba03a53c30716224f0085f98485cada99489beb7c3da9d598ffc1d81519b59d9899291712c9041c250205e6ec0b034bb2c144dcf9 + "@csstools/convert-colors": ^1.4.0 + postcss: ^7.0.2 + postcss-values-parser: ^2.0.0 + checksum: ecbf74e9395527aaf3e83b90b1a6c9bba0a1904038d8acef1f530d50a68d912d6b1af8df690342f942be8b89fa7dfaa35ae67cb5fb48013cb389ecb8c74deadb languageName: node linkType: hard -"postcss-browser-comments@npm:^4": - version: 4.0.0 - resolution: "postcss-browser-comments@npm:4.0.0" - peerDependencies: - browserslist: ">=4" - postcss: ">=8" - checksum: 9b8e7094838c2d7bd1ab3ca9cb8d0a78a9a6c8e22f43133ba02db8862fb6c141630e9f590e46f7125cfa4723cacd27b74fa00c05a9907b364dc1f6f17cf13f6f +"postcss-color-rebeccapurple@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-color-rebeccapurple@npm:4.0.1" + dependencies: + postcss: ^7.0.2 + postcss-values-parser: ^2.0.0 + checksum: a7b1a204dfc5163ac4195cc3cb0c7b1bba9561feab49d24be8a17d695d6b69fd92f3da23d638260fe7e9d5076cf81bb798b25134fa2a2fbf7f74b0dda2829a96 languageName: node linkType: hard -"postcss-calc@npm:^8.2.3": - version: 8.2.4 - resolution: "postcss-calc@npm:8.2.4" +"postcss-colormin@npm:^4.0.3": + version: 4.0.3 + resolution: "postcss-colormin@npm:4.0.3" dependencies: - postcss-selector-parser: ^6.0.9 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.2 - checksum: 314b4cebb0c4ed0cf8356b4bce71eca78f5a7842e6a3942a3bba49db168d5296b2bd93c3f735ae1c616f2651d94719ade33becc03c73d2d79c7394fb7f73eabb + browserslist: ^4.0.0 + color: ^3.0.0 + has: ^1.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 9b2eab73cd227cbf296f1a2a6466047f6c70b918c3844535531fd87f31d7878e1a8d81e8803ffe2ee8c3330ea5bec65e358a0e0f33defcd758975064e07fe928 languageName: node linkType: hard -"postcss-clamp@npm:^4.1.0": - version: 4.1.0 - resolution: "postcss-clamp@npm:4.1.0" +"postcss-convert-values@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-convert-values@npm:4.0.1" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4.6 - checksum: 118eec936b3b035dc8d75c89973408f15c5a3de3d1ee210a2b3511e3e431d9c56e6f354b509a90540241e2225ffe3caaa2fdf25919c63348ce4583a28ada642c + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 71cac73f5befeb8bc16274e2aaabe1b8e0cb42a8b8641dc2aa61b1c502697b872a682c36f370cce325553bbfc859c38f2b064fae6f6469b1cada79e733559261 languageName: node linkType: hard -"postcss-color-functional-notation@npm:^4.2.4": - version: 4.2.4 - resolution: "postcss-color-functional-notation@npm:4.2.4" +"postcss-custom-media@npm:^7.0.8": + version: 7.0.8 + resolution: "postcss-custom-media@npm:7.0.8" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: b763e164fe3577a1de96f75e4bf451585c4f80b8ce60799763a51582cc9402d76faed57324a5d5e5556d90ca7ea0ebde565acb820c95e04bee6f36a91b019831 + postcss: ^7.0.14 + checksum: 3786eb10f238b22dc620cfcc9257779e27d8cee4510b3209d0ab67310e07dc68b69f3359db7a911f5e76df466f73d078fc80100943fe2e8fa9bcacf226705a2d languageName: node linkType: hard -"postcss-color-hex-alpha@npm:^8.0.4": - version: 8.0.4 - resolution: "postcss-color-hex-alpha@npm:8.0.4" +"postcss-custom-properties@npm:^8.0.11": + version: 8.0.11 + resolution: "postcss-custom-properties@npm:8.0.11" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: a2f3173a60176cf0aea3b7ebbc799b2cb08229127f0fff708fa31efa14e4ded47ca49aff549d8ed92e74ffe24adee32d5b9d557dbde0524fde5fe389bc520b4e + postcss: ^7.0.17 + postcss-values-parser: ^2.0.1 + checksum: cb1b47459a23ff2e48714c5d48d50070d573ef829dc7e57189d1b38c6fba0de7084f1acefbd84c61dd67e30bd9a7d154b22f195547728a9dc5f76f7d3f03ffea languageName: node linkType: hard -"postcss-color-rebeccapurple@npm:^7.1.1": - version: 7.1.1 - resolution: "postcss-color-rebeccapurple@npm:7.1.1" +"postcss-custom-selectors@npm:^5.1.2": + version: 5.1.2 + resolution: "postcss-custom-selectors@npm:5.1.2" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 03482f9b8170da0fa014c41a5d88bce7b987471fb73fc456d397222a2455c89ac7f974dd6ddf40fd31907e768aad158057164b7c5f62cee63a6ecf29d47d7467 + postcss: ^7.0.2 + postcss-selector-parser: ^5.0.0-rc.3 + checksum: 26c83d348448f4ab5931cc1621606b09a6b1171e25fac2404073f3e298e77494ac87d4a21009679503b4895452810e93e618b5af26b4c7180a9013f283bb8088 languageName: node linkType: hard -"postcss-colormin@npm:^5.3.1": - version: 5.3.1 - resolution: "postcss-colormin@npm:5.3.1" +"postcss-dir-pseudo-class@npm:^5.0.0": + version: 5.0.0 + resolution: "postcss-dir-pseudo-class@npm:5.0.0" dependencies: - browserslist: ^4.21.4 - caniuse-api: ^3.0.0 - colord: ^2.9.1 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: e5778baab30877cd1f51e7dc9d2242a162aeca6360a52956acd7f668c5bc235c2ccb7e4df0370a804d65ebe00c5642366f061db53aa823f9ed99972cebd16024 + postcss: ^7.0.2 + postcss-selector-parser: ^5.0.0-rc.3 + checksum: 703156fc65f259ec2e86ba51d18370a6d3b71f2e6473c7d65694676a8f0152137b1997bc0a53f7f373c8c3e4d63c72f7b5e2049f2ef3a7276b49409395722044 languageName: node linkType: hard -"postcss-convert-values@npm:^5.1.3": - version: 5.1.3 - resolution: "postcss-convert-values@npm:5.1.3" +"postcss-discard-comments@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-discard-comments@npm:4.0.2" dependencies: - browserslist: ^4.21.4 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: df48cdaffabf9737f9cfdc58a3dc2841cf282506a7a944f6c70236cff295d3a69f63de6e0935eeb8a9d3f504324e5b4e240abc29e21df9e35a02585d3060aeb5 + postcss: ^7.0.0 + checksum: b087d47649160b7c6236aba028d27f1796a0dcb21e9ffd0da62271171fc31b7f150ee6c7a24fa97e3f5cd1af92e0dc41cb2e2680a175da53f1e536c441bda56a languageName: node linkType: hard -"postcss-custom-media@npm:^8.0.2": - version: 8.0.2 - resolution: "postcss-custom-media@npm:8.0.2" +"postcss-discard-duplicates@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-discard-duplicates@npm:4.0.2" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.3 - checksum: 887bbbacf6f8fab688123796e5dc1e8283b99f21e4c674235bd929dc8018c50df8634ea08932033ec93baaca32670ef2b87e6632863e0b4d84847375dbde9366 + postcss: ^7.0.0 + checksum: bd83647a8e5ea34b0cfe563d0c1410a0c9e742011aa67955709c5ecd2d2bb03b7016053781e975e4c802127d2f9a0cd9c22f1f2783b9d7b1c35487d60f7ea540 languageName: node linkType: hard -"postcss-custom-properties@npm:^12.1.10": - version: 12.1.11 - resolution: "postcss-custom-properties@npm:12.1.11" +"postcss-discard-empty@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-discard-empty@npm:4.0.1" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 421f9d8d6b9c9066919f39251859232efc4dc5dd406c01e62e08734319a6ccda6d03dd6b46063ba0971053ac6ad3f7abade56d67650b3e370851b2291e8e45e6 + postcss: ^7.0.0 + checksum: 529b177bd2417fa5c8887891369b4538b858d767461192974a796814265794e08e0e624a9f4c566ed9f841af3faddb7e7a9c05c45cbbe2fb1f092f65bd227f5c languageName: node linkType: hard -"postcss-custom-selectors@npm:^6.0.3": - version: 6.0.3 - resolution: "postcss-custom-selectors@npm:6.0.3" +"postcss-discard-overridden@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-discard-overridden@npm:4.0.1" dependencies: - postcss-selector-parser: ^6.0.4 - peerDependencies: - postcss: ^8.3 - checksum: 18080d60a8a77a76d8ddff185104d65418fffd02bbf9824499f807ced7941509ba63828ab8fe3ec1d6b0d6c72a482bb90a79d79cdef58e5f4b30113cca16e69b + postcss: ^7.0.0 + checksum: b34d8cf58e4d13d99a3a9459f4833f1248ca897316bbb927375590feba35c24a0304084a6174a7bf3fe4ba3d5e5e9baf15ea938e7e5744e56915fa7ef6d91ee0 languageName: node linkType: hard -"postcss-dir-pseudo-class@npm:^6.0.5": - version: 6.0.5 - resolution: "postcss-dir-pseudo-class@npm:6.0.5" +"postcss-double-position-gradients@npm:^1.0.0": + version: 1.0.0 + resolution: "postcss-double-position-gradients@npm:1.0.0" dependencies: - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.2 - checksum: 7810c439d8d1a9072c00f8ab39261a1492873ad170425745bd2819c59767db2f352f906588fc2a7d814e91117900563d7e569ecd640367c7332b26b9829927ef + postcss: ^7.0.5 + postcss-values-parser: ^2.0.0 + checksum: d2c4515b38a131ece44dba331aea2b3f9de646e30873b49f03fa8906179a3c43ddc43183bc4df609d8af0834e7c266ec3a63eaa4b3e96aa445d98ecdc12d2544 languageName: node linkType: hard -"postcss-discard-comments@npm:^5.1.2": - version: 5.1.2 - resolution: "postcss-discard-comments@npm:5.1.2" - peerDependencies: - postcss: ^8.2.15 - checksum: abfd064ebc27aeaf5037643dd51ffaff74d1fa4db56b0523d073ace4248cbb64ffd9787bd6924b0983a9d0bd0e9bf9f10d73b120e50391dc236e0d26c812fa2a +"postcss-env-function@npm:^2.0.2": + version: 2.0.2 + resolution: "postcss-env-function@npm:2.0.2" + dependencies: + postcss: ^7.0.2 + postcss-values-parser: ^2.0.0 + checksum: 0cfa2e6cad5123cce39dcf5af332ec3b0e3e09b54d5142225f255914079d2afda3f1052e60f4b6d3bccf7eb9d592325b7421f1ecc6674ccb13c267a721fc3128 languageName: node linkType: hard -"postcss-discard-duplicates@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-discard-duplicates@npm:5.1.0" - peerDependencies: - postcss: ^8.2.15 - checksum: 88d6964201b1f4ed6bf7a32cefe68e86258bb6e42316ca01d9b32bdb18e7887d02594f89f4a2711d01b51ea6e3fcca8c54be18a59770fe5f4521c61d3eb6ca35 +"postcss-flexbugs-fixes@npm:4.2.1": + version: 4.2.1 + resolution: "postcss-flexbugs-fixes@npm:4.2.1" + dependencies: + postcss: ^7.0.26 + checksum: 51a626bc80dbe42fcc8b0895b4f23a558bb809ec52cdc05aa27fb24cdffd4c9dc53f25218085ddf407c53d76573bc6d7568219c912161609f02532a8f5f59b43 languageName: node linkType: hard -"postcss-discard-empty@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-discard-empty@npm:5.1.1" - peerDependencies: - postcss: ^8.2.15 - checksum: 970adb12fae5c214c0768236ad9a821552626e77dedbf24a8213d19cc2c4a531a757cd3b8cdd3fc22fb1742471b8692a1db5efe436a71236dec12b1318ee8ff4 +"postcss-focus-visible@npm:^4.0.0": + version: 4.0.0 + resolution: "postcss-focus-visible@npm:4.0.0" + dependencies: + postcss: ^7.0.2 + checksum: a3c93fbb578608f60c5256d0989ae32fd9100f76fa053880e82bfeb43751e81a3a9e69bd8338e06579b7f56b230a80fb2cc671eff134f2682dcbec9bbb8658ae languageName: node linkType: hard -"postcss-discard-overridden@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-discard-overridden@npm:5.1.0" - peerDependencies: - postcss: ^8.2.15 - checksum: d64d4a545aa2c81b22542895cfcddc787d24119f294d35d29b0599a1c818b3cc51f4ee80b80f5a0a09db282453dd5ac49f104c2117cc09112d0ac9b40b499a41 +"postcss-focus-within@npm:^3.0.0": + version: 3.0.0 + resolution: "postcss-focus-within@npm:3.0.0" + dependencies: + postcss: ^7.0.2 + checksum: 2a31292cd9b929a2dd3171fc4ed287ea4a93c6ec8df1d634503fb97b8b30b33a2970b5e0df60634c60ff887923ab28641b624d566533096950e0a384705e9b90 languageName: node linkType: hard -"postcss-double-position-gradients@npm:^3.1.2": - version: 3.1.2 - resolution: "postcss-double-position-gradients@npm:3.1.2" +"postcss-font-variant@npm:^4.0.0": + version: 4.0.1 + resolution: "postcss-font-variant@npm:4.0.1" dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: ca09bf2aefddc180f1c1413f379eef30d492b8147543413f7251216f23f413c394b2ed10b7cd255e87b18e0c8efe36087ea8b9bfb26a09813f9607a0b8e538b6 + postcss: ^7.0.2 + checksum: d09836cd848e8c24d144484b6b9b175df26dca59e1a1579e790c7f3dcaea00944a8d0b6ac543f4c128de7b30fab9a0aef544d54789b3b55fd850770b172d980d languageName: node linkType: hard -"postcss-env-function@npm:^4.0.6": - version: 4.0.6 - resolution: "postcss-env-function@npm:4.0.6" +"postcss-gap-properties@npm:^2.0.0": + version: 2.0.0 + resolution: "postcss-gap-properties@npm:2.0.0" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.4 - checksum: 645b2363cfa21be9dcce7fe4a0f172f0af70c00d6a4c1eb3d7ff7e9cfe26d569e291ec2533114d77b12d610023cd168a92d62c38f2fc969fa333b5ae2bff5ffe + postcss: ^7.0.2 + checksum: c842d105c9403e34a8fac7bdef33a63fcb6bde038b04b20cae1e719e1966632887545576af99a4a6f302c98ca029c6f0d746419f498ef7f6821177ba676e6c25 languageName: node linkType: hard -"postcss-flexbugs-fixes@npm:^5.0.2": - version: 5.0.2 - resolution: "postcss-flexbugs-fixes@npm:5.0.2" - peerDependencies: - postcss: ^8.1.4 - checksum: 022ddbcca8987303b9be75ff259e9de81b98643adac87a5fc6b52a0fcbbf95e1ac9fd508c4ed67cad76ac5d039b7123de8a0832329481b3c626f5d63f7a28f47 +"postcss-image-set-function@npm:^3.0.1": + version: 3.0.1 + resolution: "postcss-image-set-function@npm:3.0.1" + dependencies: + postcss: ^7.0.2 + postcss-values-parser: ^2.0.0 + checksum: 43958d7c1f80077e60e066bdf61bc326bcac64c272f17fd7a0585a6934fb1ffc7ba7f560a39849f597e4d28b8ae3addd9279c7145b9478d2d91a7c54c2fefd8b languageName: node linkType: hard -"postcss-focus-visible@npm:^6.0.4": - version: 6.0.4 - resolution: "postcss-focus-visible@npm:6.0.4" +"postcss-initial@npm:^3.0.0": + version: 3.0.4 + resolution: "postcss-initial@npm:3.0.4" dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 - checksum: acd010b9ddef9b86ffb5fa604c13515ba83e18bc5118dad0a1281150f412aa0ece056c2c5ac56b55e2599f53ab0f740f5ebfdc51e1f5cfe43b8130bac0096fcc + postcss: ^7.0.2 + checksum: 710ab6cabc5970912c04314099f5334e7d901235014bb1462657e29f8dc97b6e51caa35f0beba7e5dbe440589ef9c1df13a89bc53d6e6aa664573b945f1630bb languageName: node linkType: hard -"postcss-focus-within@npm:^5.0.4": - version: 5.0.4 - resolution: "postcss-focus-within@npm:5.0.4" +"postcss-lab-function@npm:^2.0.1": + version: 2.0.1 + resolution: "postcss-lab-function@npm:2.0.1" dependencies: - postcss-selector-parser: ^6.0.9 - peerDependencies: - postcss: ^8.4 - checksum: f23d8ab757345a6deaa807d76e10c88caf4b771c38b60e1593b24aee161c503b5823620e89302226a6ae5e7afdb6ac31809241291912e4176eb594a7ddcc9521 + "@csstools/convert-colors": ^1.4.0 + postcss: ^7.0.2 + postcss-values-parser: ^2.0.0 + checksum: 598229a7a05803b18cccde28114833e910367c5954341bea03c7d7b7b5a667dfb6a77ef9dd4a16d80fdff8b10dd44c478602a7d56e43687c8687af3710b4706f languageName: node linkType: hard -"postcss-font-variant@npm:^5.0.0": - version: 5.0.0 - resolution: "postcss-font-variant@npm:5.0.0" - peerDependencies: - postcss: ^8.1.0 - checksum: a19286589261c2bc3e20470486e1ee3b4daf34271c5020167f30856c9b30c26f23264307cb97a184d503814e1b8c5d8a1f9f64a14fd4fd9551c173dca9424695 +"postcss-load-config@npm:^2.0.0": + version: 2.1.2 + resolution: "postcss-load-config@npm:2.1.2" + dependencies: + cosmiconfig: ^5.0.0 + import-cwd: ^2.0.0 + checksum: 2e6d3a499512a03c19b0090f4143861612d613511d57122879d9fd545558d2a9fcbe85a2b0faf2ec32bbce0e62d22d2b544d91cbc4d4dfb3f22f841f8271fbc6 languageName: node linkType: hard -"postcss-gap-properties@npm:^3.0.5": - version: 3.0.5 - resolution: "postcss-gap-properties@npm:3.0.5" - peerDependencies: - postcss: ^8.2 - checksum: aed559d6d375203a08a006c9ae8cf5ae90d9edaec5cadd20fe65c1b8ce63c2bc8dfe752d4331880a6e24a300541cde61058be790b7bd9b5d04d470c250fbcd39 +"postcss-loader@npm:3.0.0": + version: 3.0.0 + resolution: "postcss-loader@npm:3.0.0" + dependencies: + loader-utils: ^1.1.0 + postcss: ^7.0.0 + postcss-load-config: ^2.0.0 + schema-utils: ^1.0.0 + checksum: a6a922cbcc225ef57fb88c8248f91195869cd11e0d2b0b0fe84bc89a3074437d592d79a9fc39e50218677b7ba3a41b0e1c7e8f9666e59d41a196d7ab022c5805 languageName: node linkType: hard -"postcss-image-set-function@npm:^4.0.7": - version: 4.0.7 - resolution: "postcss-image-set-function@npm:4.0.7" +"postcss-logical@npm:^3.0.0": + version: 3.0.0 + resolution: "postcss-logical@npm:3.0.0" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 7e509330986de14250ead1a557e8da8baaf66ebe8a40354a5dff60ab40d99a483d92aa57d52713251ca1adbf0055ef476c5702b0d0ba5f85a4f407367cdabac0 + postcss: ^7.0.2 + checksum: 5278661b78a093661c9cac8c04666d457734bf156f83d8c67f6034c00e8d4b3a26fce32a8a4a251feae3c7587f42556412dca980e100d0c920ee55e878f7b8ee languageName: node linkType: hard -"postcss-import@npm:^15.1.0": - version: 15.1.0 - resolution: "postcss-import@npm:15.1.0" +"postcss-media-minmax@npm:^4.0.0": + version: 4.0.0 + resolution: "postcss-media-minmax@npm:4.0.0" dependencies: - postcss-value-parser: ^4.0.0 - read-cache: ^1.0.0 - resolve: ^1.1.7 - peerDependencies: - postcss: ^8.0.0 - checksum: 7bd04bd8f0235429009d0022cbf00faebc885de1d017f6d12ccb1b021265882efc9302006ba700af6cab24c46bfa2f3bc590be3f9aee89d064944f171b04e2a3 + postcss: ^7.0.2 + checksum: 8a4d94e25089bb5a66c6742bcdd263fce2fea391438151a85b442b7f8b66323bbca552b59a93efd6bcabcfd41845ddd4149bd56d156b008f8d7d04bc84d9fb11 languageName: node linkType: hard -"postcss-initial@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-initial@npm:4.0.1" - peerDependencies: - postcss: ^8.0.0 - checksum: 6956953853865de79c39d11533a2860e9f38b770bb284d0010d98a00b9469e22de344e4e5fd8208614d797030487e8918dd2f2c37d9e24d4dd59d565d4fc3e12 +"postcss-merge-longhand@npm:^4.0.11": + version: 4.0.11 + resolution: "postcss-merge-longhand@npm:4.0.11" + dependencies: + css-color-names: 0.0.4 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + stylehacks: ^4.0.0 + checksum: 45082b492d4d771c1607707d04dbcaece85a100011109886af9460a7868720de1121e290a6442360e2668db510edef579194197d1b534e9fb6c8df7a6cb86a4d languageName: node linkType: hard -"postcss-js@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-js@npm:4.0.1" +"postcss-merge-rules@npm:^4.0.3": + version: 4.0.3 + resolution: "postcss-merge-rules@npm:4.0.3" dependencies: - camelcase-css: ^2.0.1 - peerDependencies: - postcss: ^8.4.21 - checksum: 5c1e83efeabeb5a42676193f4357aa9c88f4dc1b3c4a0332c132fe88932b33ea58848186db117cf473049fc233a980356f67db490bd0a7832ccba9d0b3fd3491 + browserslist: ^4.0.0 + caniuse-api: ^3.0.0 + cssnano-util-same-parent: ^4.0.0 + postcss: ^7.0.0 + postcss-selector-parser: ^3.0.0 + vendors: ^1.0.0 + checksum: ed0f3880e1076e5b2a08e4cff35b50dc7dfbd337e6ba16a0ca157e28268cfa1d6c6d821e902d319757f32a7d36f944cad51be76f8b34858d1d7a637e7b585919 languageName: node linkType: hard -"postcss-lab-function@npm:^4.2.1": - version: 4.2.1 - resolution: "postcss-lab-function@npm:4.2.1" +"postcss-minify-font-values@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-minify-font-values@npm:4.0.2" dependencies: - "@csstools/postcss-progressive-custom-properties": ^1.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 26ac74b430011271b5581beba69b2cd788f56375fcb64c90f6ec1577379af85f6022dc38c410ff471dac520c7ddc289160a6a16cca3c7ff76f5af7e90d31eaa3 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: add296b3bc88501283d65b54ad83552f47c98dd403740a70d8dfeef6d30a21d4a1f40191ffef1029a9474e9580a73e84ef644e99ede76c5a2474579b583f4b34 languageName: node linkType: hard -"postcss-load-config@npm:^4.0.2": +"postcss-minify-gradients@npm:^4.0.2": version: 4.0.2 - resolution: "postcss-load-config@npm:4.0.2" + resolution: "postcss-minify-gradients@npm:4.0.2" dependencies: - lilconfig: ^3.0.0 - yaml: ^2.3.4 - peerDependencies: - postcss: ">=8.0.9" - ts-node: ">=9.0.0" - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - checksum: 7c27dd3801db4eae207a5116fed2db6b1ebb780b40c3dd62a3e57e087093a8e6a14ee17ada729fee903152d6ef4826c6339eb135bee6208e0f3140d7e8090185 + cssnano-util-get-arguments: ^4.0.0 + is-color-stop: ^1.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: b83de019cc392192d64182fa6f609383904ef69013d71cda5d06fadab92b4daa73f5be0d0254c5eb0805405e5e1b9c44e49ca6bc629c4c7a24a8164a30b40d46 languageName: node linkType: hard -"postcss-loader@npm:^6.2.1": - version: 6.2.1 - resolution: "postcss-loader@npm:6.2.1" +"postcss-minify-params@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-minify-params@npm:4.0.2" dependencies: - cosmiconfig: ^7.0.0 - klona: ^2.0.5 - semver: ^7.3.5 - peerDependencies: - postcss: ^7.0.0 || ^8.0.1 - webpack: ^5.0.0 - checksum: e40ae79c3e39df37014677a817b001bd115d8b10dedf53a07b97513d93b1533cd702d7a48831bdd77b9a9484b1ec84a5d4a723f80e83fb28682c75b5e65e8a90 + alphanum-sort: ^1.0.0 + browserslist: ^4.0.0 + cssnano-util-get-arguments: ^4.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + uniqs: ^2.0.0 + checksum: 15e7f196b3408ab3f55f1a7c9fa8aeea7949fdd02be28af232dd2e47bb7722e0e0a416d6b2c4550ba333a485b775da1bc35c19c9be7b6de855166d2e85d7b28f languageName: node linkType: hard -"postcss-logical@npm:^5.0.4": - version: 5.0.4 - resolution: "postcss-logical@npm:5.0.4" - peerDependencies: - postcss: ^8.4 - checksum: 17c71291ed6a03883a5aa54b9923b874c32710707d041a0f0752e6febdb09dee5d2abf4ef271978d932e4a4c948f349bb23edf633c03e3427ba15e71bfc66ac7 +"postcss-minify-selectors@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-minify-selectors@npm:4.0.2" + dependencies: + alphanum-sort: ^1.0.0 + has: ^1.0.0 + postcss: ^7.0.0 + postcss-selector-parser: ^3.0.0 + checksum: a214809b620e50296417838804c3978d5f0a5ddfd48916780d77c1e0348c9ed0baa4b1f3905511b0f06b77340b5378088cc3188517c0848e8b7a53a71ef36c2b languageName: node linkType: hard -"postcss-media-minmax@npm:^5.0.0": - version: 5.0.0 - resolution: "postcss-media-minmax@npm:5.0.0" - peerDependencies: - postcss: ^8.1.0 - checksum: 2cd7283e07a1ac1acdcc3ecbaa0e9932f8d1e7647e7aeb14d91845fcb890d60d7257ec70c825cae8d48ae80a08cc77ebc4021a0dfa32360e0cd991e2bc021607 +"postcss-modules-extract-imports@npm:1.1.0": + version: 1.1.0 + resolution: "postcss-modules-extract-imports@npm:1.1.0" + dependencies: + postcss: ^6.0.1 + checksum: 3dc9ed98509f654c1220bb8ec7489b30fa4441f2797eb5c894badfd6f4ab1b086f8002f59d47845d827a3f23a40400ba4c18959c7a3702285d4e5bfcfcd180d4 languageName: node linkType: hard -"postcss-merge-longhand@npm:^5.1.7": - version: 5.1.7 - resolution: "postcss-merge-longhand@npm:5.1.7" +"postcss-modules-extract-imports@npm:^2.0.0": + version: 2.0.0 + resolution: "postcss-modules-extract-imports@npm:2.0.0" dependencies: - postcss-value-parser: ^4.2.0 - stylehacks: ^5.1.1 - peerDependencies: - postcss: ^8.2.15 - checksum: 81c3fc809f001b9b71a940148e242bdd6e2d77713d1bfffa15eb25c1f06f6648d5e57cb21645746d020a2a55ff31e1740d2b27900442913a9d53d8a01fb37e1b + postcss: ^7.0.5 + checksum: 154790fe5954aaa12f300aa9aa782fae8b847138459c8f533ea6c8f29439dd66b4d9a49e0bf6f8388fa0df898cc03d61c84678e3b0d4b47cac5a4334a7151a9f languageName: node linkType: hard -"postcss-merge-rules@npm:^5.1.4": - version: 5.1.4 - resolution: "postcss-merge-rules@npm:5.1.4" +"postcss-modules-local-by-default@npm:1.2.0": + version: 1.2.0 + resolution: "postcss-modules-local-by-default@npm:1.2.0" dependencies: - browserslist: ^4.21.4 - caniuse-api: ^3.0.0 - cssnano-utils: ^3.1.0 - postcss-selector-parser: ^6.0.5 - peerDependencies: - postcss: ^8.2.15 - checksum: 8ab6a569babe6cb412d6612adee74f053cea7edb91fa013398515ab36754b1fec830d68782ed8cdfb44cffdc6b78c79eab157bff650f428aa4460d3f3857447e + css-selector-tokenizer: ^0.7.0 + postcss: ^6.0.1 + checksum: c8bbe0a9584e0a02339f4143125bf5febbcbfdbabedc33a5f2debdc5b0089f5c238b236101dbf923ea66c11637c0dee8bcf91d1692ed0443762203286b864ea2 languageName: node linkType: hard -"postcss-minify-font-values@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-minify-font-values@npm:5.1.0" +"postcss-modules-local-by-default@npm:^3.0.3": + version: 3.0.3 + resolution: "postcss-modules-local-by-default@npm:3.0.3" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 35e858fa41efa05acdeb28f1c76579c409fdc7eabb1744c3bd76e895bb9fea341a016746362a67609688ab2471f587202b9a3e14ea28ad677754d663a2777ece + icss-utils: ^4.1.1 + postcss: ^7.0.32 + postcss-selector-parser: ^6.0.2 + postcss-value-parser: ^4.1.0 + checksum: 0267633eaf80e72a3abf391b6e34c5b344a1bdfb1421543d3ed43fc757e053e0fcc1a2eb06d959a8f435776e8dc80288b59bfc34d61e5e021d47b747c417c5a1 languageName: node linkType: hard -"postcss-minify-gradients@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-minify-gradients@npm:5.1.1" +"postcss-modules-scope@npm:1.1.0": + version: 1.1.0 + resolution: "postcss-modules-scope@npm:1.1.0" dependencies: - colord: ^2.9.1 - cssnano-utils: ^3.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 27354072a07c5e6dab36731103b94ca2354d4ed3c5bc6aacfdf2ede5a55fa324679d8fee5450800bc50888dbb5e9ed67569c0012040c2be128143d0cebb36d67 + css-selector-tokenizer: ^0.7.0 + postcss: ^6.0.1 + checksum: e1b7dd8b1aabb0dc719015352835c6865a5b80ef469cf956749540847b751ccac860d7f0f5659aa2c4b8a484c4a9291098895e5c91c9707e02c7f79a7288297e languageName: node linkType: hard -"postcss-minify-params@npm:^5.1.4": - version: 5.1.4 - resolution: "postcss-minify-params@npm:5.1.4" +"postcss-modules-scope@npm:^2.2.0": + version: 2.2.0 + resolution: "postcss-modules-scope@npm:2.2.0" dependencies: - browserslist: ^4.21.4 - cssnano-utils: ^3.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: bd63e2cc89edcf357bb5c2a16035f6d02ef676b8cede4213b2bddd42626b3d428403849188f95576fc9f03e43ebd73a29bf61d33a581be9a510b13b7f7f100d5 + postcss: ^7.0.6 + postcss-selector-parser: ^6.0.0 + checksum: c611181df924275ca1ffea261149c229488d6921054896879ca98feeb0913f9b00f4f160654beb2cb243a2989036c269baa96778eeacaaa399a4604b6e2fea17 languageName: node linkType: hard -"postcss-minify-selectors@npm:^5.2.1": - version: 5.2.1 - resolution: "postcss-minify-selectors@npm:5.2.1" +"postcss-modules-values@npm:1.3.0": + version: 1.3.0 + resolution: "postcss-modules-values@npm:1.3.0" dependencies: - postcss-selector-parser: ^6.0.5 - peerDependencies: - postcss: ^8.2.15 - checksum: 6fdbc84f99a60d56b43df8930707da397775e4c36062a106aea2fd2ac81b5e24e584a1892f4baa4469fa495cb87d1422560eaa8f6c9d500f9f0b691a5f95bab5 + icss-replace-symbols: ^1.1.0 + postcss: ^6.0.1 + checksum: c1d542f71df43ec8b998808ea8de5e74e215a2428e92a8c157da436724aacf246b77440da1cd3d5daae610c875b46e7f8a845b52e1a49afdc37668093de8e3e7 languageName: node linkType: hard -"postcss-modules-extract-imports@npm:^3.1.0": - version: 3.1.0 - resolution: "postcss-modules-extract-imports@npm:3.1.0" - peerDependencies: - postcss: ^8.1.0 - checksum: b9192e0f4fb3d19431558be6f8af7ca45fc92baaad9b2778d1732a5880cd25c3df2074ce5484ae491e224f0d21345ffc2d419bd51c25b019af76d7a7af88c17f +"postcss-modules-values@npm:^3.0.0": + version: 3.0.0 + resolution: "postcss-modules-values@npm:3.0.0" + dependencies: + icss-utils: ^4.0.0 + postcss: ^7.0.6 + checksum: f1aea0b9c6798b39ec02a6d2310924bb9bfbddb4579668c2d4e2205ca7a68c656b85d5720f9bba3629d611f36667fe04ab889ea3f9a6b569a0a0d57b4f2f4e99 languageName: node linkType: hard -"postcss-modules-local-by-default@npm:^4.0.5": - version: 4.2.0 - resolution: "postcss-modules-local-by-default@npm:4.2.0" +"postcss-nesting@npm:^7.0.0": + version: 7.0.1 + resolution: "postcss-nesting@npm:7.0.1" dependencies: - icss-utils: ^5.0.0 - postcss-selector-parser: ^7.0.0 - postcss-value-parser: ^4.1.0 - peerDependencies: - postcss: ^8.1.0 - checksum: 720d145453f82ad5f1c1d0ff7386d64722f0812808e4132e573c1a49909745e109fcce3792a0b0cb18770dbeb3d9741867e81c698dc8353a18bc664b7d6d9533 + postcss: ^7.0.2 + checksum: 4056be95759e8b25477f19aff7202b57dd27eeef41d31f7ca14e4c87d16ffb40e4db3f518fc85bd28b20e183f5e5399b56b52fcc79affd556e13a98bbc678169 languageName: node linkType: hard -"postcss-modules-scope@npm:^3.2.0": - version: 3.2.1 - resolution: "postcss-modules-scope@npm:3.2.1" +"postcss-normalize-charset@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-normalize-charset@npm:4.0.1" dependencies: - postcss-selector-parser: ^7.0.0 - peerDependencies: - postcss: ^8.1.0 - checksum: 085f65863bb7d8bf08209a979ceb22b2b07bb466574e0e698d34aaad832d614957bb05f2418348a14e4035f65e23b2be2951369d26ea429dd5762c6a020f0f7c + postcss: ^7.0.0 + checksum: f233f48d61eb005da217e5bfa58f4143165cb525ceea2de4fd88e4172a33712e8b63258ffa089c867875a498c408f293a380ea9e6f40076de550d8053f50e5bc languageName: node linkType: hard -"postcss-modules-values@npm:^4.0.0": - version: 4.0.0 - resolution: "postcss-modules-values@npm:4.0.0" +"postcss-normalize-display-values@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-normalize-display-values@npm:4.0.2" dependencies: - icss-utils: ^5.0.0 - peerDependencies: - postcss: ^8.1.0 - checksum: f7f2cdf14a575b60e919ad5ea52fed48da46fe80db2733318d71d523fc87db66c835814940d7d05b5746b0426e44661c707f09bdb83592c16aea06e859409db6 + cssnano-util-get-match: ^4.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: c5b857ca05f30a3efc6211cdaa5c9306f3eb0dbac141047d451a418d2bfd3e54be0bd4481d61c640096152d3078881a8dc3dec61913ff7f01ab4fc6df1a14732 languageName: node linkType: hard -"postcss-modules@npm:^6.0.0": - version: 6.0.1 - resolution: "postcss-modules@npm:6.0.1" - dependencies: - generic-names: ^4.0.0 - icss-utils: ^5.1.0 - lodash.camelcase: ^4.3.0 - 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 - string-hash: ^1.1.3 - peerDependencies: - postcss: ^8.0.0 - checksum: bdbf1e2babfb5a6ff13c86c36b8b431b655472cc9e16098cea0b960ed1fe8fa8f298292f939548bf00cc664c66e954d1b4c5a8634a7b57c58bc06d8f54cdd5a0 +"postcss-normalize-positions@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-normalize-positions@npm:4.0.2" + dependencies: + cssnano-util-get-arguments: ^4.0.0 + has: ^1.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 291612d0879e6913010937f1193ab56ae1cfd8a274665330ccbedbe72f59c36db3f688b0a3faa4c6689cfd03dff0c27702c6acfce9b1f697a022bfcee3cd4fc4 languageName: node linkType: hard -"postcss-nested@npm:^6.2.0": - version: 6.2.0 - resolution: "postcss-nested@npm:6.2.0" +"postcss-normalize-repeat-style@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-normalize-repeat-style@npm:4.0.2" dependencies: - postcss-selector-parser: ^6.1.1 - peerDependencies: - postcss: ^8.2.14 - checksum: 2c86ecf2d0ce68f27c87c7e24ae22dc6dd5515a89fcaf372b2627906e11f5c1f36e4a09e4c15c20fd4a23d628b3d945c35839f44496fbee9a25866258006671b + cssnano-util-get-arguments: ^4.0.0 + cssnano-util-get-match: ^4.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 2160b2a6fe4f9671ad5d044755f0e04cfb5f255db607505fd4c74e7c806315c9dca914e74bb02f5f768de7b70939359d05c3f9b23ae8f72551d8fdeabf79a1fb languageName: node linkType: hard -"postcss-nesting@npm:^10.2.0": - version: 10.2.0 - resolution: "postcss-nesting@npm:10.2.0" +"postcss-normalize-string@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-normalize-string@npm:4.0.2" dependencies: - "@csstools/selector-specificity": ^2.0.0 - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.2 - checksum: 25e6e66186bd7f18bc4628cf0f43e02189268f28a449aa4a63b33b8f2c33745af99acfcd4ce2ac69319dc850e83b28dbaabcf517e3977dfe20e37fed0e032c7d + has: ^1.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 9d40753ceb4f7854ed690ecd5fe4ea142280b14441dd11e188e573e58af93df293efdc77311f1c599431df785a3bb614dfe4bdacc3081ee3fe8c95916c849b2f languageName: node linkType: hard -"postcss-normalize-charset@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-charset@npm:5.1.0" - peerDependencies: - postcss: ^8.2.15 - checksum: e79d92971fc05b8b3c9b72f3535a574e077d13c69bef68156a0965f397fdf157de670da72b797f57b0e3bac8f38155b5dd1735ecab143b9cc4032d72138193b4 +"postcss-normalize-timing-functions@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-normalize-timing-functions@npm:4.0.2" + dependencies: + cssnano-util-get-match: ^4.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 8dfd711f5cdb49b823a92d1cd56d40f66f3686e257804495ef59d5d7f71815b6d19412a1ff25d40971bf6e146b1fa0517a6cc1a4c286b36c5cee6ed08a1952db languageName: node linkType: hard -"postcss-normalize-display-values@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-display-values@npm:5.1.0" +"postcss-normalize-unicode@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-normalize-unicode@npm:4.0.1" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: b6eb7b9b02c3bdd62bbc54e01e2b59733d73a1c156905d238e178762962efe0c6f5104544da39f32cade8a4fb40f10ff54b63a8ebfbdff51e8780afb9fbdcf86 + browserslist: ^4.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 2b1da17815f8402651a72012fd385b5111e84002baf98b649e0c1fc91298b65bb0e431664f6df8a99b23217259ecec242b169c0f18bf26e727af02eaf475fb07 languageName: node linkType: hard -"postcss-normalize-positions@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-normalize-positions@npm:5.1.1" +"postcss-normalize-url@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-normalize-url@npm:4.0.1" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: d9afc233729c496463c7b1cdd06732469f401deb387484c3a2422125b46ec10b4af794c101f8c023af56f01970b72b535e88373b9058ecccbbf88db81662b3c4 + is-absolute-url: ^2.0.0 + normalize-url: ^3.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: fcaab832d8b773568197b41406517a9e5fc7704f2fac7185bd0e13b19961e1ce9f1c762e4ffa470de7baa6a82ae8ae5ccf6b1bbeec6e95216d22ce6ab514fe04 languageName: node linkType: hard -"postcss-normalize-repeat-style@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-normalize-repeat-style@npm:5.1.1" +"postcss-normalize-whitespace@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-normalize-whitespace@npm:4.0.2" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 2c6ad2b0ae10a1fda156b948c34f78c8f1e185513593de4d7e2480973586675520edfec427645fa168c337b0a6b3ceca26f92b96149741ca98a9806dad30d534 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 378a6eadb09ccc5ca2289e8daf98ce7366ae53342c4df7898ef5fae68138884d6c1241493531635458351b2805218bf55ceecae0fd289e5696ab15c78966abbb languageName: node linkType: hard -"postcss-normalize-string@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-string@npm:5.1.0" +"postcss-normalize@npm:8.0.1": + version: 8.0.1 + resolution: "postcss-normalize@npm:8.0.1" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 6e549c6e5b2831e34c7bdd46d8419e2278f6af1d5eef6d26884a37c162844e60339340c57e5e06058cdbe32f27fc6258eef233e811ed2f71168ef2229c236ada + "@csstools/normalize.css": ^10.1.0 + browserslist: ^4.6.2 + postcss: ^7.0.17 + postcss-browser-comments: ^3.0.0 + sanitize.css: ^10.0.0 + checksum: 3109075389b91a09a790c3cd62a4e8c147bab2113cffa7ea2e776982352796816bc56b7f08ed7f7175c24e5d9c46171a07f95eeee00cfecddac6e3b4c9888dd0 languageName: node linkType: hard -"postcss-normalize-timing-functions@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-timing-functions@npm:5.1.0" +"postcss-ordered-values@npm:^4.1.2": + version: 4.1.2 + resolution: "postcss-ordered-values@npm:4.1.2" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: da550f50e90b0b23e17b67449a7d1efd1aa68288e66d4aa7614ca6f5cc012896be1972b7168eee673d27da36504faccf7b9f835c0f7e81243f966a42c8c030aa + cssnano-util-get-arguments: ^4.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: 4a6f6a427a0165e1fa4f04dbe53a88708c73ea23e5b23ce312366ca8d85d83af450154a54f0e5df6c5712f945c180b6a364c3682dc995940b93228bb26658a96 languageName: node linkType: hard -"postcss-normalize-unicode@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-normalize-unicode@npm:5.1.1" +"postcss-overflow-shorthand@npm:^2.0.0": + version: 2.0.0 + resolution: "postcss-overflow-shorthand@npm:2.0.0" dependencies: - browserslist: ^4.21.4 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 4c24d26cc9f4b19a9397db4e71dd600dab690f1de8e14a3809e2aa1452dbc3791c208c38a6316bbc142f29e934fdf02858e68c94038c06174d78a4937e0f273c + postcss: ^7.0.2 + checksum: 553be1b7f9645017d33b654f9a436ce4f4406066c3056ca4c7ee06c21c2964fbe3437a9a3f998137efb6a17c1a79ee7e8baa39332c7dd9874aac8b69a3ad08b0 languageName: node linkType: hard -"postcss-normalize-url@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-url@npm:5.1.0" +"postcss-page-break@npm:^2.0.0": + version: 2.0.0 + resolution: "postcss-page-break@npm:2.0.0" dependencies: - normalize-url: ^6.0.1 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 3bd4b3246d6600230bc827d1760b24cb3101827ec97570e3016cbe04dc0dd28f4dbe763245d1b9d476e182c843008fbea80823061f1d2219b96f0d5c724a24c0 + postcss: ^7.0.2 + checksum: 65a4453883e904ca0f337d3a988a1b5a090e2e8bc2855913cb0b4b741158e6ea2e4eed9b33f5989e7ae55faa0f7b83cdc09693d600ac4c86ce804ae381ec48a4 languageName: node linkType: hard -"postcss-normalize-whitespace@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-normalize-whitespace@npm:5.1.1" +"postcss-place@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-place@npm:4.0.1" + dependencies: + postcss: ^7.0.2 + postcss-values-parser: ^2.0.0 + checksum: 26b2a443b0a8fcb6774d00036fa351633798a655ccd609da2d561fbd6561b0ba6f6b6d89e15fb074389fadb7da4cbc59c48ba75f1f5fdc478c020febb4e2b557 + languageName: node + linkType: hard + +"postcss-preset-env@npm:6.7.0": + version: 6.7.0 + resolution: "postcss-preset-env@npm:6.7.0" + dependencies: + autoprefixer: ^9.6.1 + browserslist: ^4.6.4 + caniuse-lite: ^1.0.30000981 + css-blank-pseudo: ^0.1.4 + css-has-pseudo: ^0.10.0 + css-prefers-color-scheme: ^3.1.1 + cssdb: ^4.4.0 + postcss: ^7.0.17 + postcss-attribute-case-insensitive: ^4.0.1 + postcss-color-functional-notation: ^2.0.1 + postcss-color-gray: ^5.0.0 + postcss-color-hex-alpha: ^5.0.3 + postcss-color-mod-function: ^3.0.3 + postcss-color-rebeccapurple: ^4.0.1 + postcss-custom-media: ^7.0.8 + postcss-custom-properties: ^8.0.11 + postcss-custom-selectors: ^5.1.2 + postcss-dir-pseudo-class: ^5.0.0 + postcss-double-position-gradients: ^1.0.0 + postcss-env-function: ^2.0.2 + postcss-focus-visible: ^4.0.0 + postcss-focus-within: ^3.0.0 + postcss-font-variant: ^4.0.0 + postcss-gap-properties: ^2.0.0 + postcss-image-set-function: ^3.0.1 + postcss-initial: ^3.0.0 + postcss-lab-function: ^2.0.1 + postcss-logical: ^3.0.0 + postcss-media-minmax: ^4.0.0 + postcss-nesting: ^7.0.0 + postcss-overflow-shorthand: ^2.0.0 + postcss-page-break: ^2.0.0 + postcss-place: ^4.0.1 + postcss-pseudo-class-any-link: ^6.0.0 + postcss-replace-overflow-wrap: ^3.0.0 + postcss-selector-matches: ^4.0.0 + postcss-selector-not: ^4.0.0 + checksum: 209cbb63443a1631aa97ccfc3b95b1ff519ddaeb672f84d6af501bd9e9ad6727680b5b1bffb8209322e47d93029a69df6064f75cd0b7633b6df943cbef33f22e + languageName: node + linkType: hard + +"postcss-pseudo-class-any-link@npm:^6.0.0": + version: 6.0.0 + resolution: "postcss-pseudo-class-any-link@npm:6.0.0" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 12d8fb6d1c1cba208cc08c1830959b7d7ad447c3f5581873f7e185f99a9a4230c43d3af21ca12c818e4690a5085a95b01635b762ad4a7bef69d642609b4c0e19 + postcss: ^7.0.2 + postcss-selector-parser: ^5.0.0-rc.3 + checksum: d7dc3bba45df2966f8512c082a9cc341e63edac14d915ad9f41c62c452cd306d82da6baeee757dd4e7deafe3fa33b26c16e5236c670916bbb7ff4b4723453541 languageName: node linkType: hard -"postcss-normalize@npm:^10.0.1": - version: 10.0.1 - resolution: "postcss-normalize@npm:10.0.1" +"postcss-reduce-initial@npm:^4.0.3": + version: 4.0.3 + resolution: "postcss-reduce-initial@npm:4.0.3" dependencies: - "@csstools/normalize.css": "*" - postcss-browser-comments: ^4 - sanitize.css: "*" - peerDependencies: - browserslist: ">= 4" - postcss: ">= 8" - checksum: af67ade84e5d65de0cf84cde479840da96ffb2037fe6bf86737788216f67e414622e718e7d84182885ad65fa948150e4a0c3e454ca63e619dd5c7b4eb4224c39 + browserslist: ^4.0.0 + caniuse-api: ^3.0.0 + has: ^1.0.0 + postcss: ^7.0.0 + checksum: 5ad1a955cb20f5b1792ff8cc35894621edc23ee77397cc7e9692d269882fb4451655633947e0407fe20bd127d09d0b7e693034c64417bf8bf1034a83c6e71668 languageName: node linkType: hard -"postcss-opacity-percentage@npm:^1.1.2": - version: 1.1.3 - resolution: "postcss-opacity-percentage@npm:1.1.3" - peerDependencies: - postcss: ^8.2 - checksum: 54d1b8ca68035bc1a5788aaabdbc3b66ffee34b5a2412cecf073627dad7e3f2bae07c01fac3bc7f46bbac5da3291ac9ddcf74bfee26dfd86f9f96c847a0afc13 +"postcss-reduce-transforms@npm:^4.0.2": + version: 4.0.2 + resolution: "postcss-reduce-transforms@npm:4.0.2" + dependencies: + cssnano-util-get-match: ^4.0.0 + has: ^1.0.0 + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + checksum: e6a351d5da7ecf276ddda350635b15bce8e14af08aee1c8a0e8d9c2ab2631eab33b06f3c2f31c6f9c76eedbfc23f356d86da3539e011cde3e335a2cac9d91dc1 languageName: node linkType: hard -"postcss-ordered-values@npm:^5.1.3": - version: 5.1.3 - resolution: "postcss-ordered-values@npm:5.1.3" +"postcss-replace-overflow-wrap@npm:^3.0.0": + version: 3.0.0 + resolution: "postcss-replace-overflow-wrap@npm:3.0.0" dependencies: - cssnano-utils: ^3.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 6f3ca85b6ceffc68aadaf319d9ee4c5ac16d93195bf8cba2d1559b631555ad61941461cda6d3909faab86e52389846b2b36345cff8f0c3f4eb345b1b8efadcf9 + postcss: ^7.0.2 + checksum: 8c5b512a1172dd3d7b4a06d56d3b64c76dea01ca0950b546f83ae993f83aa95f933239e18deed0a5f3d2ef47840de55fa73498c4a46bfbe7bd892eb0dd8b606c languageName: node linkType: hard -"postcss-overflow-shorthand@npm:^3.0.4": - version: 3.0.4 - resolution: "postcss-overflow-shorthand@npm:3.0.4" +"postcss-safe-parser@npm:5.0.2": + version: 5.0.2 + resolution: "postcss-safe-parser@npm:5.0.2" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 74009022491e3901263f8f5811630393480323e51f5d23ef17f3fdc7e03bf9c2502a632f3ba8fe6a468b57590f13b2fa3b17a68ef19653589e76277607696743 + postcss: ^8.1.0 + checksum: b786eca091f856f2d31856d903c24c1b591ecbc0b607af0824e1cf12b9b254b5e1f24bc842cc2b95bc561f097d8b358fb4c9e04c73c1ba9c118d21bde9a83253 languageName: node linkType: hard -"postcss-page-break@npm:^3.0.4": - version: 3.0.4 - resolution: "postcss-page-break@npm:3.0.4" - peerDependencies: - postcss: ^8 - checksum: a7d08c945fc691f62c77ac701e64722218b14ec5c8fc1972b8af9c21553492d40808cf95e61b9697b1dacaf7e6180636876d7fee314f079e6c9e39ac1b1edc6f +"postcss-selector-matches@npm:^4.0.0": + version: 4.0.0 + resolution: "postcss-selector-matches@npm:4.0.0" + dependencies: + balanced-match: ^1.0.0 + postcss: ^7.0.2 + checksum: 724f6cb345477691909468268a456f978ad3bae9ecd9908b2bb55c55c5f3c6d54a1fe50ce3956d93b122d05fc36677a8e4a34eed07bccda969c3f8baa43669a6 languageName: node linkType: hard -"postcss-place@npm:^7.0.5": - version: 7.0.5 - resolution: "postcss-place@npm:7.0.5" +"postcss-selector-not@npm:^4.0.0": + version: 4.0.1 + resolution: "postcss-selector-not@npm:4.0.1" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 903fec0c313bb7ec20f2c8f0a125866fb7804aa3186b5b2c7c2d58cb9039ff301461677a060e9db643d1aaffaf80a0ff71e900a6da16705dad6b49c804cb3c73 + balanced-match: ^1.0.0 + postcss: ^7.0.2 + checksum: 08fbd3e5ca273f3b767bd35d6bd033647a68f59b596d8aec19a9089b750539bdf85121ed7fd00a7763174a55c75c22a309d75d306127e23dc396069781efbaa4 languageName: node linkType: hard -"postcss-preset-env@npm:^7.0.1": - version: 7.8.3 - resolution: "postcss-preset-env@npm:7.8.3" - dependencies: - "@csstools/postcss-cascade-layers": ^1.1.1 - "@csstools/postcss-color-function": ^1.1.1 - "@csstools/postcss-font-format-keywords": ^1.0.1 - "@csstools/postcss-hwb-function": ^1.0.2 - "@csstools/postcss-ic-unit": ^1.0.1 - "@csstools/postcss-is-pseudo-class": ^2.0.7 - "@csstools/postcss-nested-calc": ^1.0.0 - "@csstools/postcss-normalize-display-values": ^1.0.1 - "@csstools/postcss-oklab-function": ^1.1.1 - "@csstools/postcss-progressive-custom-properties": ^1.3.0 - "@csstools/postcss-stepped-value-functions": ^1.0.1 - "@csstools/postcss-text-decoration-shorthand": ^1.0.0 - "@csstools/postcss-trigonometric-functions": ^1.0.2 - "@csstools/postcss-unset-value": ^1.0.2 - autoprefixer: ^10.4.13 - browserslist: ^4.21.4 - css-blank-pseudo: ^3.0.3 - css-has-pseudo: ^3.0.4 - css-prefers-color-scheme: ^6.0.3 - cssdb: ^7.1.0 - postcss-attribute-case-insensitive: ^5.0.2 - postcss-clamp: ^4.1.0 - postcss-color-functional-notation: ^4.2.4 - postcss-color-hex-alpha: ^8.0.4 - postcss-color-rebeccapurple: ^7.1.1 - postcss-custom-media: ^8.0.2 - postcss-custom-properties: ^12.1.10 - postcss-custom-selectors: ^6.0.3 - postcss-dir-pseudo-class: ^6.0.5 - postcss-double-position-gradients: ^3.1.2 - postcss-env-function: ^4.0.6 - postcss-focus-visible: ^6.0.4 - postcss-focus-within: ^5.0.4 - postcss-font-variant: ^5.0.0 - postcss-gap-properties: ^3.0.5 - postcss-image-set-function: ^4.0.7 - postcss-initial: ^4.0.1 - postcss-lab-function: ^4.2.1 - postcss-logical: ^5.0.4 - postcss-media-minmax: ^5.0.0 - postcss-nesting: ^10.2.0 - postcss-opacity-percentage: ^1.1.2 - postcss-overflow-shorthand: ^3.0.4 - postcss-page-break: ^3.0.4 - postcss-place: ^7.0.5 - postcss-pseudo-class-any-link: ^7.1.6 - postcss-replace-overflow-wrap: ^4.0.0 - postcss-selector-not: ^6.0.1 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2 - checksum: 71bfb697ffc55e27895b2bf3a579dd9b4c1321872816091935e33d6f659cab60795a03bb022dc8a4cab48fd5680a419fe9ae5d61a3a3d8c785ec9308f323e787 +"postcss-selector-parser@npm:^3.0.0": + version: 3.1.2 + resolution: "postcss-selector-parser@npm:3.1.2" + dependencies: + dot-prop: ^5.2.0 + indexes-of: ^1.0.1 + uniq: ^1.0.1 + checksum: 85b754bf3b5f671cddd75a199589e5b03da114ec119aa4628ab7f35f76134b25296d18a68f745e39780c379d66d3919ae7a1b6129aeec5049cedb9ba4c660803 languageName: node linkType: hard -"postcss-pseudo-class-any-link@npm:^7.1.6": - version: 7.1.6 - resolution: "postcss-pseudo-class-any-link@npm:7.1.6" +"postcss-selector-parser@npm:^5.0.0-rc.3, postcss-selector-parser@npm:^5.0.0-rc.4": + version: 5.0.0 + resolution: "postcss-selector-parser@npm:5.0.0" dependencies: - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.2 - checksum: 43aa18ea1ef1b168f61310856dd92f46ceb3dc60b6cf820e079ca1a849df5cc0f12a1511bdc1811a23f03d60ddcc959200c80c3f9a7b57feebe32bab226afb39 + cssesc: ^2.0.0 + indexes-of: ^1.0.1 + uniq: ^1.0.1 + checksum: e49d21455e06d2cb9bf2a615bf3e605e0603c2c430a84c37a34f8baedaf3e8f9d0059a085d3e0483cbfa04c0d4153c7da28e7ac0ada319efdefe407df11dc1d4 languageName: node linkType: hard -"postcss-reduce-initial@npm:^5.1.2": - version: 5.1.2 - resolution: "postcss-reduce-initial@npm:5.1.2" +"postcss-selector-parser@npm:^6.0.0, postcss-selector-parser@npm:^6.0.2": + version: 6.0.16 + resolution: "postcss-selector-parser@npm:6.0.16" dependencies: - browserslist: ^4.21.4 - caniuse-api: ^3.0.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 55db697f85231a81f1969d54c894e4773912d9ddb914f9b03d2e73abc4030f2e3bef4d7465756d0c1acfcc2c2d69974bfb50a972ab27546a7d68b5a4fc90282b + cssesc: ^3.0.0 + util-deprecate: ^1.0.2 + checksum: e1cd68e33a39e3dc1e1e5bd8717be5bbe3cc23a4cecb466c3acb2f3a77daad7a47df4d6137a76f8db74cf160d2fb16b2cfdb4ccbebdfda844690f8d545fe281d languageName: node linkType: hard -"postcss-reduce-transforms@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-reduce-transforms@npm:5.1.0" +"postcss-svgo@npm:^4.0.3": + version: 4.0.3 + resolution: "postcss-svgo@npm:4.0.3" dependencies: - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 0c6af2cba20e3ff63eb9ad045e634ddfb9c3e5c0e614c020db2a02f3aa20632318c4ede9e0c995f9225d9a101e673de91c0a6e10bb2fa5da6d6c75d15a55882f + postcss: ^7.0.0 + postcss-value-parser: ^3.0.0 + svgo: ^1.0.0 + checksum: 6f5264241193ca3ba748fdf43c88ef692948d2ae38787398dc90089061fed884064ec14ee244fce07f19c419d1b058c77e135407d0932b09e93e528581ce3e10 languageName: node linkType: hard -"postcss-replace-overflow-wrap@npm:^4.0.0": - version: 4.0.0 - resolution: "postcss-replace-overflow-wrap@npm:4.0.0" - peerDependencies: - postcss: ^8.0.3 - checksum: 3ffe20b300a4c377a11c588b142740d8557e03c707474c45234c934190ac374750ddc92c7906c373471d273a20504a429c2062c21fdcaff830fb28e0a81ac1dc +"postcss-unique-selectors@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-unique-selectors@npm:4.0.1" + dependencies: + alphanum-sort: ^1.0.0 + postcss: ^7.0.0 + uniqs: ^2.0.0 + checksum: 272eb1fa17d6ea513b5f4d2f694ef30fa690795ce388aef7bf3967fd3bcec7a9a3c8da380e74961ded8d98253a6ed18fb380b29da00e2fe03e74813e7765ea71 languageName: node linkType: hard -"postcss-selector-not@npm:^6.0.1": - version: 6.0.1 - resolution: "postcss-selector-not@npm:6.0.1" - dependencies: - postcss-selector-parser: ^6.0.10 - peerDependencies: - postcss: ^8.2 - checksum: fe523a0219e4bd34f04498534bb9e8aec3193f3585eafe4c388d086955b41201cae71fd20980ca465acade7f182029b43dbd5ca7e9d50bf34bbcaf1d19fe3ee6 +"postcss-value-parser@npm:^3.0.0": + version: 3.3.1 + resolution: "postcss-value-parser@npm:3.3.1" + checksum: 62cd26e1cdbcf2dcc6bcedf3d9b409c9027bc57a367ae20d31dd99da4e206f730689471fd70a2abe866332af83f54dc1fa444c589e2381bf7f8054c46209ce16 languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.10, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.9, postcss-selector-parser@npm:^6.1.1, postcss-selector-parser@npm:^6.1.2": - version: 6.1.2 - resolution: "postcss-selector-parser@npm:6.1.2" - dependencies: - cssesc: ^3.0.0 - util-deprecate: ^1.0.2 - checksum: ce9440fc42a5419d103f4c7c1847cb75488f3ac9cbe81093b408ee9701193a509f664b4d10a2b4d82c694ee7495e022f8f482d254f92b7ffd9ed9dea696c6f84 +"postcss-value-parser@npm:^4.0.2, postcss-value-parser@npm:^4.1.0": + version: 4.2.0 + resolution: "postcss-value-parser@npm:4.2.0" + checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f languageName: node linkType: hard -"postcss-selector-parser@npm:^7.0.0": - version: 7.1.0 - resolution: "postcss-selector-parser@npm:7.1.0" +"postcss-values-parser@npm:^2.0.0, postcss-values-parser@npm:^2.0.1": + version: 2.0.1 + resolution: "postcss-values-parser@npm:2.0.1" dependencies: - cssesc: ^3.0.0 - util-deprecate: ^1.0.2 - checksum: 1300e7871dd60a5132ee5462cc6e94edd4f3df28462b2495ca9ff025bd83768a908e892a18fde62cae63ff63524641baa6d58c64120f04fe6884b916663ce737 + flatten: ^1.0.2 + indexes-of: ^1.0.1 + uniq: ^1.0.1 + checksum: 050877880937e15af8d18bf48902e547e2123d7cc32c1f215b392642bc5e2598a87a341995d62f38e450aab4186b8afeb2c9541934806d458ad8b117020b2ebf languageName: node linkType: hard -"postcss-svgo@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-svgo@npm:5.1.0" +"postcss@npm:6.0.1": + version: 6.0.1 + resolution: "postcss@npm:6.0.1" dependencies: - postcss-value-parser: ^4.2.0 - svgo: ^2.7.0 - peerDependencies: - postcss: ^8.2.15 - checksum: d86eb5213d9f700cf5efe3073799b485fb7cacae0c731db3d7749c9c2b1c9bc85e95e0baeca439d699ff32ea24815fc916c4071b08f67ed8219df229ce1129bd + chalk: ^1.1.3 + source-map: ^0.5.6 + supports-color: ^3.2.3 + checksum: 2533d218b6c23dad42fffb98979f3fd2b98bbe11c923e3245ed8f83da9591c176a5de2403ad3ebaedea819f50d5f6c88c40d322265c59b6b10ed8a02c12fd4bc languageName: node linkType: hard -"postcss-unique-selectors@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-unique-selectors@npm:5.1.1" +"postcss@npm:7.0.36": + version: 7.0.36 + resolution: "postcss@npm:7.0.36" dependencies: - postcss-selector-parser: ^6.0.5 - peerDependencies: - postcss: ^8.2.15 - checksum: 637e7b786e8558265775c30400c54b6b3b24d4748923f4a39f16a65fd0e394f564ccc9f0a1d3c0e770618a7637a7502ea1d0d79f731d429cb202255253c23278 + chalk: ^2.4.2 + source-map: ^0.6.1 + supports-color: ^6.1.0 + checksum: 4cfc0989b9ad5d0e8971af80d87f9c5beac5c84cb89ff22ad69852edf73c0a2fa348e7e0a135b5897bf893edad0fe86c428769050431ad9b532f072ff530828d languageName: node linkType: hard -"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0": - version: 4.2.0 - resolution: "postcss-value-parser@npm:4.2.0" - checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f +"postcss@npm:^6.0.1": + version: 6.0.23 + resolution: "postcss@npm:6.0.23" + dependencies: + chalk: ^2.4.1 + source-map: ^0.6.1 + supports-color: ^5.4.0 + checksum: cc6cb2c1dbcdefa6f57a71d67fe535c9e96543298bbe28f9a6a64c4f1e21b6127113890dd4cda8873d3f4e6613a0566b7b4bbb230204f3a9a309190bda065d81 languageName: node linkType: hard -"postcss@npm:^7.0.35": +"postcss@npm:^7, postcss@npm:^7.0.0, postcss@npm:^7.0.1, postcss@npm:^7.0.14, postcss@npm:^7.0.17, postcss@npm:^7.0.2, postcss@npm:^7.0.26, postcss@npm:^7.0.27, postcss@npm:^7.0.32, postcss@npm:^7.0.5, postcss@npm:^7.0.6": version: 7.0.39 resolution: "postcss@npm:7.0.39" dependencies: @@ -17415,36 +16150,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.3.5, postcss@npm:^8.4.27, postcss@npm:^8.4.33, postcss@npm:^8.4.4, postcss@npm:^8.4.43, postcss@npm:^8.4.47, postcss@npm:^8.4.49, postcss@npm:^8.5.6": - version: 8.5.6 - resolution: "postcss@npm:8.5.6" +"postcss@npm:^8.1.0, postcss@npm:^8.4.27": + version: 8.4.38 + resolution: "postcss@npm:8.4.38" dependencies: - nanoid: ^3.3.11 - picocolors: ^1.1.1 - source-map-js: ^1.2.1 - checksum: 20f3b5d673ffeec2b28d65436756d31ee33f65b0a8bedb3d32f556fbd5973be38c3a7fb5b959a5236c60a5db7b91b0a6b14ffaac0d717dce1b903b964ee1c1bb - languageName: node - linkType: hard - -"prebuild-install@npm:^7.1.3": - version: 7.1.3 - resolution: "prebuild-install@npm:7.1.3" - dependencies: - detect-libc: ^2.0.0 - expand-template: ^2.0.3 - github-from-package: 0.0.0 - minimist: ^1.2.3 - mkdirp-classic: ^0.5.3 - napi-build-utils: ^2.0.0 - node-abi: ^3.3.0 - pump: ^3.0.0 - rc: ^1.2.7 - simple-get: ^4.0.0 - tar-fs: ^2.0.0 - tunnel-agent: ^0.6.0 - bin: - prebuild-install: bin.js - checksum: 300740ca415e9ddbf2bd363f1a6d2673cc11dd0665c5ec431bbb5bf024c2f13c56791fb939ce2b2a2c12f2d2a09c91316169e8063a80eb4482a44b8fe5b265e1 + nanoid: ^3.3.7 + picocolors: ^1.0.0 + source-map-js: ^1.2.0 + checksum: 649f9e60a763ca4b5a7bbec446a069edf07f057f6d780a5a0070576b841538d1ecf7dd888f2fbfd1f76200e26c969e405aeeae66332e6927dbdc8bdcb90b9451 languageName: node linkType: hard @@ -17462,6 +16175,13 @@ __metadata: languageName: node linkType: hard +"prepend-http@npm:^1.0.0": + version: 1.0.4 + resolution: "prepend-http@npm:1.0.4" + checksum: 01e7baf4ad38af02257b99098543469332fc42ae50df33d97a124bf8172295907352fa6138c9b1610c10c6dd0847ca736e53fda736387cc5cf8fcffe96b47f29 + languageName: node + linkType: hard + "prettier-linter-helpers@npm:^1.0.0": version: 1.0.0 resolution: "prettier-linter-helpers@npm:1.0.0" @@ -17471,33 +16191,45 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^3.4.2": - version: 3.6.2 - resolution: "prettier@npm:3.6.2" +"prettier@npm:^2.0.5": + version: 2.8.8 + resolution: "prettier@npm:2.8.8" bin: - prettier: bin/prettier.cjs - checksum: 0206f5f437892e8858f298af8850bf9d0ef1c22e21107a213ba56bfb9c2387a2020bfda244a20161d8e3dad40c6b04101609a55d370dece53d0a31893b64f861 + prettier: bin-prettier.js + checksum: b49e409431bf129dd89238d64299ba80717b57ff5a6d1c1a8b1a28b590d998a34e083fa13573bc732bb8d2305becb4c9a4407f8486c81fa7d55100eb08263cf8 languageName: node linkType: hard -"pretty-bytes@npm:^5.3.0, pretty-bytes@npm:^5.4.1": +"pretty-bytes@npm:^5.3.0": version: 5.6.0 resolution: "pretty-bytes@npm:5.6.0" checksum: 9c082500d1e93434b5b291bd651662936b8bd6204ec9fa17d563116a192d6d86b98f6d328526b4e8d783c07d5499e2614a807520249692da9ec81564b2f439cd languageName: node linkType: hard -"pretty-error@npm:^4.0.0": - version: 4.0.0 - resolution: "pretty-error@npm:4.0.0" +"pretty-error@npm:^2.1.1": + version: 2.1.2 + resolution: "pretty-error@npm:2.1.2" dependencies: lodash: ^4.17.20 - renderkid: ^3.0.0 - checksum: a5b9137365690104ded6947dca2e33360bf55e62a4acd91b1b0d7baa3970e43754c628cc9e16eafbdd4e8f8bcb260a5865475d4fc17c3106ff2d61db4e72cdf3 + renderkid: ^2.0.4 + checksum: 16775d06f9a695d17103414d610b1281f9535ee1f2da1ce1e1b9be79584a114aa7eac6dcdcc5ef151756d3c014dfd4ac1c7303ed8016d0cec12437cfdf4021c6 languageName: node linkType: hard -"pretty-format@npm:^27.0.2, pretty-format@npm:^27.5.1": +"pretty-format@npm:^26.6.0, pretty-format@npm:^26.6.2": + version: 26.6.2 + resolution: "pretty-format@npm:26.6.2" + dependencies: + "@jest/types": ^26.6.2 + ansi-regex: ^5.0.0 + ansi-styles: ^4.0.0 + react-is: ^17.0.1 + checksum: e3b808404d7e1519f0df1aa1f25cee0054ab475775c6b2b8c5568ff23194a92d54bf93274139b6f584ca70fd773be4eaa754b0e03f12bb0a8d1426b07f079976 + languageName: node + linkType: hard + +"pretty-format@npm:^27.0.2": version: 27.5.1 resolution: "pretty-format@npm:27.5.1" dependencies: @@ -17508,7 +16240,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^28.1.3": +"pretty-format@npm:^28.0.0, pretty-format@npm:^28.1.3": version: 28.1.3 resolution: "pretty-format@npm:28.1.3" dependencies: @@ -17520,7 +16252,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": +"pretty-format@npm:^29.0.0, pretty-format@npm:^29.5.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" dependencies: @@ -17531,25 +16263,22 @@ __metadata: languageName: node linkType: hard -"prisma@npm:6.2.1": - version: 6.2.1 - resolution: "prisma@npm:6.2.1" +"prisma@npm:^4.4.0": + version: 4.16.2 + resolution: "prisma@npm:4.16.2" dependencies: - "@prisma/engines": 6.2.1 - fsevents: 2.3.3 - dependenciesMeta: - fsevents: - optional: true + "@prisma/engines": 4.16.2 bin: prisma: build/index.js - checksum: 04232e345506c0b0fe8c5c16b15c9f0a51179501ee7c00b6bf52ad193cf38222ff0eb1f04a02b1a24feb1445bc5796f612838e93be39fdec416576883f8c2ca7 + prisma2: build/index.js + checksum: 1d0ed616abd7f8de22441e333b976705f1cb05abcb206965df3fc6a7ea03911ef467dd484a4bc51fdc6cff72dd9857b9852be5f232967a444af0a98c49bfdb76 languageName: node linkType: hard -"proc-log@npm:^5.0.0": - version: 5.0.0 - resolution: "proc-log@npm:5.0.0" - checksum: c78b26ecef6d5cce4a7489a1e9923d7b4b1679028c8654aef0463b27f4a90b0946cd598f55799da602895c52feb085ec76381d007ab8dcceebd40b89c2f9dfe0 +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 languageName: node linkType: hard @@ -17560,6 +16289,13 @@ __metadata: languageName: node linkType: hard +"process@npm:^0.11.10": + version: 0.11.10 + resolution: "process@npm:0.11.10" + checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 + languageName: node + linkType: hard + "progress@npm:^2.0.0": version: 2.0.3 resolution: "progress@npm:2.0.3" @@ -17567,6 +16303,13 @@ __metadata: languageName: node linkType: hard +"promise-inflight@npm:^1.0.1": + version: 1.0.1 + resolution: "promise-inflight@npm:1.0.1" + checksum: 22749483091d2c594261517f4f80e05226d4d5ecc1fc917e1886929da56e22b5718b7f2a75f3807e7a7d471bc3be2907fe92e6e8f373ddf5c64bae35b5af3981 + languageName: node + linkType: hard + "promise-retry@npm:^2.0.1": version: 2.0.1 resolution: "promise-retry@npm:2.0.1" @@ -17586,7 +16329,17 @@ __metadata: languageName: node linkType: hard -"prompts@npm:^2.0.1, prompts@npm:^2.4.2": +"prompts@npm:2.4.0": + version: 2.4.0 + resolution: "prompts@npm:2.4.0" + dependencies: + kleur: ^3.0.3 + sisteransi: ^1.0.5 + checksum: 96c7bef8eb3c0bb2076d2bc5ee473f06e6d8ac01ac4d0f378dfeb0ddaf2f31c339360ec8f0f8486f78601d16ebef7c6bd9886d44b937ba01bab568b937190265 + languageName: node + linkType: hard + +"prompts@npm:^2.0.1": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: @@ -17596,7 +16349,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:^15.6.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -17607,21 +16360,23 @@ __metadata: languageName: node linkType: hard -"property-expr@npm:^2.0.5": +"property-expr@npm:^2.0.4": version: 2.0.6 resolution: "property-expr@npm:2.0.6" checksum: 89977f4bb230736c1876f460dd7ca9328034502fd92e738deb40516d16564b850c0bbc4e052c3df88b5b8cd58e51c93b46a94bea049a3f23f4a022c038864cab languageName: node linkType: hard -"property-information@npm:^7.0.0": - version: 7.1.0 - resolution: "property-information@npm:7.1.0" - checksum: 3875161d204bac89d75181f6d3ebc3ecaeb2699b4e2ecfcf5452201d7cdd275168c6742d7ff8cec5ab0c342fae72369ac705e1f8e9680a9acd911692e80dfb88 +"property-information@npm:^5.3.0": + version: 5.6.0 + resolution: "property-information@npm:5.6.0" + dependencies: + xtend: ^4.0.0 + checksum: fcf87c6542e59a8bbe31ca0b3255a4a63ac1059b01b04469680288998bcfa97f341ca989566adbb63975f4d85339030b82320c324a511532d390910d1c583893 languageName: node linkType: hard -"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7": +"proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -17638,12 +16393,17 @@ __metadata: languageName: node linkType: hard +"prr@npm:~1.0.1": + version: 1.0.1 + resolution: "prr@npm:1.0.1" + checksum: 3bca2db0479fd38f8c4c9439139b0c42dcaadcc2fbb7bb8e0e6afaa1383457f1d19aea9e5f961d5b080f1cfc05bfa1fe9e45c97a1d3fd6d421950a73d3108381 + languageName: node + linkType: hard + "psl@npm:^1.1.33": - version: 1.15.0 - resolution: "psl@npm:1.15.0" - dependencies: - punycode: ^2.3.1 - checksum: 6f777d82eecfe1c2406dadbc15e77467b186fec13202ec887a45d0209a2c6fca530af94a462a477c3c4a767ad892ec9ede7c482d98f61f653dd838b50e89dc15 + version: 1.9.0 + resolution: "psl@npm:1.9.0" + checksum: 20c4277f640c93d393130673f392618e9a8044c6c7bf61c53917a0fddb4952790f5f362c6c730a9c32b124813e173733f9895add8d26f566ed0ea0654b2e711d languageName: node linkType: hard @@ -17654,17 +16414,59 @@ __metadata: languageName: node linkType: hard +"public-encrypt@npm:^4.0.0": + version: 4.0.3 + resolution: "public-encrypt@npm:4.0.3" + dependencies: + bn.js: ^4.1.0 + browserify-rsa: ^4.0.0 + create-hash: ^1.1.0 + parse-asn1: ^5.0.0 + randombytes: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: 215d446e43cef021a20b67c1df455e5eea134af0b1f9b8a35f9e850abf32991b0c307327bc5b9bc07162c288d5cdb3d4a783ea6c6640979ed7b5017e3e0c9935 + languageName: node + linkType: hard + +"pump@npm:^2.0.0": + version: 2.0.1 + resolution: "pump@npm:2.0.1" + dependencies: + end-of-stream: ^1.1.0 + once: ^1.3.1 + checksum: e9f26a17be00810bff37ad0171edb35f58b242487b0444f92fb7d78bc7d61442fa9b9c5bd93a43fd8fd8ddd3cc75f1221f5e04c790f42907e5baab7cf5e2b931 + languageName: node + linkType: hard + "pump@npm:^3.0.0": - version: 3.0.3 - resolution: "pump@npm:3.0.3" + version: 3.0.0 + resolution: "pump@npm:3.0.0" dependencies: end-of-stream: ^1.1.0 once: ^1.3.1 - checksum: 52843fc933b838c0330f588388115a1b28ef2a5ffa7774709b142e35431e8ab0c2edec90de3fa34ebb72d59fef854f151eea7dfc211b6dcf586b384556bd2f39 + checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 + languageName: node + linkType: hard + +"pumpify@npm:^1.3.3": + version: 1.5.1 + resolution: "pumpify@npm:1.5.1" + dependencies: + duplexify: ^3.6.0 + inherits: ^2.0.3 + pump: ^2.0.0 + checksum: 26ca412ec8d665bd0d5e185c1b8f627728eff603440d75d22a58e421e3c66eaf86ec6fc6a6efc54808ecef65979279fa8e99b109a23ec1fa8d79f37e6978c9bd + languageName: node + linkType: hard + +"punycode@npm:^1.2.4, punycode@npm:^1.4.1": + version: 1.4.1 + resolution: "punycode@npm:1.4.1" + checksum: fa6e698cb53db45e4628559e557ddaf554103d2a96a1d62892c8f4032cd3bc8871796cae9eabc1bc700e2b6677611521ce5bb1d9a27700086039965d0cf34518 languageName: node linkType: hard -"punycode@npm:^2.1.0, punycode@npm:^2.1.1, punycode@npm:^2.3.1": +"punycode@npm:^2.1.0, punycode@npm:^2.1.1": version: 2.3.1 resolution: "punycode@npm:2.3.1" checksum: bb0a0ceedca4c3c57a9b981b90601579058903c62be23c5e8e843d2c2d4148a3ecf029d5133486fb0e1822b098ba8bba09e89d6b21742d02fa26bda6441a6fb2 @@ -17678,21 +16480,45 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.13.0": - version: 6.13.0 - resolution: "qs@npm:6.13.0" +"qs@npm:6.11.0": + version: 6.11.0 + resolution: "qs@npm:6.11.0" + dependencies: + side-channel: ^1.0.4 + checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297 + languageName: node + linkType: hard + +"qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.7.0": + version: 6.12.1 + resolution: "qs@npm:6.12.1" dependencies: side-channel: ^1.0.6 - checksum: e9404dc0fc2849245107108ce9ec2766cde3be1b271de0bf1021d049dc5b98d1a2901e67b431ac5509f865420a7ed80b7acb3980099fe1c118a1c5d2e1432ad8 + checksum: aa761d99e65b6936ba2dd2187f2d9976afbcda38deb3ff1b3fe331d09b0c578ed79ca2abdde1271164b5be619c521ec7db9b34c23f49a074e5921372d16242d5 languageName: node linkType: hard -"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.7.0": - version: 6.14.0 - resolution: "qs@npm:6.14.0" +"query-string@npm:^4.1.0": + version: 4.3.4 + resolution: "query-string@npm:4.3.4" dependencies: - side-channel: ^1.1.0 - checksum: 189b52ad4e9a0da1a16aff4c58b2a554a8dad9bd7e287c7da7446059b49ca2e33a49e570480e8be406b87fccebf134f51c373cbce36c8c83859efa0c9b71d635 + object-assign: ^4.1.0 + strict-uri-encode: ^1.0.0 + checksum: 3b2bae6a8454cf0edf11cf1aa4d1f920398bbdabc1c39222b9bb92147e746fcd97faf00e56f494728fb66b2961b495ba0fde699d5d3bd06b11472d664b36c6cf + languageName: node + linkType: hard + +"querystring-es3@npm:^0.2.0": + version: 0.2.1 + resolution: "querystring-es3@npm:0.2.1" + checksum: 691e8d6b8b157e7cd49ae8e83fcf86de39ab3ba948c25abaa94fba84c0986c641aa2f597770848c64abce290ed17a39c9df6df737dfa7e87c3b63acc7d225d61 + languageName: node + linkType: hard + +"querystring@npm:^0.2.0": + version: 0.2.1 + resolution: "querystring@npm:0.2.1" + checksum: 7b83b45d641e75fd39cd6625ddfd44e7618e741c61e95281b57bbae8fde0afcc12cf851924559e5cc1ef9baa3b1e06e22b164ea1397d65dd94b801f678d9c8ce languageName: node linkType: hard @@ -17710,13 +16536,6 @@ __metadata: languageName: node linkType: hard -"raf-schd@npm:^4.0.3": - version: 4.0.3 - resolution: "raf-schd@npm:4.0.3" - checksum: 45514041c5ad31fa96aef3bb3c572a843b92da2f2cd1cb4a47c9ad58e48761d3a4126e18daa32b2bfa0bc2551a42d8f324a0e40e536cb656969929602b4e8b58 - languageName: node - linkType: hard - "raf@npm:^3.4.1": version: 3.4.1 resolution: "raf@npm:3.4.1" @@ -17726,7 +16545,7 @@ __metadata: languageName: node linkType: hard -"randombytes@npm:^2.1.0": +"randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" dependencies: @@ -17735,6 +16554,16 @@ __metadata: languageName: node linkType: hard +"randomfill@npm:^1.0.3": + version: 1.0.4 + resolution: "randomfill@npm:1.0.4" + dependencies: + randombytes: ^2.0.5 + safe-buffer: ^5.1.0 + checksum: 33734bb578a868d29ee1b8555e21a36711db084065d94e019a6d03caa67debef8d6a1bfd06a2b597e32901ddc761ab483a85393f0d9a75838f1912461d4dbfc7 + languageName: node + linkType: hard + "range-parser@npm:^1.2.1, range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" @@ -17742,7 +16571,7 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.2, raw-body@npm:^2.3.3": +"raw-body@npm:2.5.2": version: 2.5.2 resolution: "raw-body@npm:2.5.2" dependencies: @@ -17754,123 +16583,61 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:^3.0.0": - version: 3.0.1 - resolution: "raw-body@npm:3.0.1" - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.7.0 - unpipe: 1.0.0 - checksum: e75e1db74337e01b78cc07f7e65692ed46aef2e0c4fb39cb25bb365a7ab04cbdb8b3541aabebe50b07a5bffec5def5674b587fd9e8fbde84c8838cbab1ad9836 - languageName: node - linkType: hard - -"rc@npm:^1.2.7": - version: 1.2.8 - resolution: "rc@npm:1.2.8" - dependencies: - deep-extend: ^0.6.0 - ini: ~1.3.0 - minimist: ^1.2.0 - strip-json-comments: ~2.0.1 - bin: - rc: ./cli.js - checksum: 2e26e052f8be2abd64e6d1dabfbd7be03f80ec18ccbc49562d31f617d0015fbdbcf0f9eed30346ea6ab789e0fdfe4337f033f8016efdbee0df5354751842080e - languageName: node - linkType: hard - -"react-app-polyfill@npm:^3.0.0": - version: 3.0.0 - resolution: "react-app-polyfill@npm:3.0.0" +"react-app-polyfill@npm:^2.0.0": + version: 2.0.0 + resolution: "react-app-polyfill@npm:2.0.0" dependencies: - core-js: ^3.19.2 + core-js: ^3.6.5 object-assign: ^4.1.1 promise: ^8.1.0 raf: ^3.4.1 - regenerator-runtime: ^0.13.9 - whatwg-fetch: ^3.6.2 - checksum: 1bb031080af15397d6eb9c69a0c2e93799991f7197a086e4409ba719398f1256b542a3d6c9a34673d516c684eef3e8226c99b335982593851f58f65f6e43571b - languageName: node - linkType: hard - -"react-archer@npm:^4.4.0": - version: 4.4.0 - resolution: "react-archer@npm:4.4.0" - dependencies: - react-fast-compare: ^2.0.4 - resize-observer-polyfill: 1.5.0 - peerDependencies: - "@types/react": ^16.8.8 || ^17 || ^18 - prop-types: ^15.6.2 - react: ^16.9.0 || ^17 || ^18 - checksum: 2f675499d9af5a06911332e432af24280b38715151078a3a75b6dd7790f6756c19647928e3f67cda3b21526c6dda2729bedb17e40d1f21835a1b4873c362c6c4 - languageName: node - linkType: hard - -"react-chartjs-2@npm:5.2.0": - version: 5.2.0 - resolution: "react-chartjs-2@npm:5.2.0" - peerDependencies: - chart.js: ^4.1.1 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: ace702185be1450e5888a8bcd8b5fc1995067e3b11d236764a67f5567a3d7c32ff16923b8d48d3d39bda6e45135da6c044c9b43fbe8e1978f95aca9d2c0ce348 - languageName: node - linkType: hard - -"react-dev-utils@npm:^12.0.1": - version: 12.0.1 - resolution: "react-dev-utils@npm:12.0.1" - dependencies: - "@babel/code-frame": ^7.16.0 - address: ^1.1.2 - browserslist: ^4.18.1 - chalk: ^4.1.2 - cross-spawn: ^7.0.3 - detect-port-alt: ^1.1.6 - escape-string-regexp: ^4.0.0 - filesize: ^8.0.6 - find-up: ^5.0.0 - fork-ts-checker-webpack-plugin: ^6.5.0 - global-modules: ^2.0.0 - globby: ^11.0.4 - gzip-size: ^6.0.0 - immer: ^9.0.7 - is-root: ^2.1.0 - loader-utils: ^3.2.0 - open: ^8.4.0 - pkg-up: ^3.1.0 - prompts: ^2.4.2 - react-error-overlay: ^6.0.11 - recursive-readdir: ^2.2.2 - shell-quote: ^1.7.3 - strip-ansi: ^6.0.1 - text-table: ^0.2.0 - checksum: 2c6917e47f03d9595044770b0f883a61c6b660fcaa97b8ba459a1d57c9cca9aa374cd51296b22d461ff5e432105dbe6f04732dab128e52729c79239e1c23ab56 + regenerator-runtime: ^0.13.7 + whatwg-fetch: ^3.4.1 + checksum: 99e52a6b2229c7ca730cfd44ac95640f955be71d144225bd6c24fa47922a742658a371d0a2f0876d732533f1055b7cd7e9d534c89c29f8ca889ecd1b8d15f065 languageName: node linkType: hard -"react-dom@npm:19.0.0": - version: 19.0.0 - resolution: "react-dom@npm:19.0.0" +"react-dev-utils@npm:^11.0.3": + version: 11.0.4 + resolution: "react-dev-utils@npm:11.0.4" dependencies: - scheduler: ^0.25.0 - peerDependencies: - react: ^19.0.0 - checksum: 009cc6e575263a0d1906f9dd4aa6532d2d3d0d71e4c2b7777c8fe4de585fa06b5b77cdc2e0fbaa2f3a4a5e5d3305c189ba152153f358ee7da4d9d9ba5d3a8975 + "@babel/code-frame": 7.10.4 + address: 1.1.2 + browserslist: 4.14.2 + chalk: 2.4.2 + cross-spawn: 7.0.3 + detect-port-alt: 1.1.6 + escape-string-regexp: 2.0.0 + filesize: 6.1.0 + find-up: 4.1.0 + fork-ts-checker-webpack-plugin: 4.1.6 + global-modules: 2.0.0 + globby: 11.0.1 + gzip-size: 5.1.1 + immer: 8.0.1 + is-root: 2.1.0 + loader-utils: 2.0.0 + open: ^7.0.2 + pkg-up: 3.1.0 + prompts: 2.4.0 + react-error-overlay: ^6.0.9 + recursive-readdir: 2.2.2 + shell-quote: 1.7.2 + strip-ansi: 6.0.0 + text-table: 0.2.0 + checksum: b41c95010a4fb60d4ea6309423520e6268757b68df34de7e9e8dbc72549236a1f5a698ff99ad72a034ac51b042aa79ee53994330ce4df05bf867e63c5464bb3f languageName: node linkType: hard -"react-draggable@npm:^4.4.6": - version: 4.5.0 - resolution: "react-draggable@npm:4.5.0" +"react-dom@npm:^18.2.0": + version: 18.2.0 + resolution: "react-dom@npm:18.2.0" dependencies: - clsx: ^2.1.1 - prop-types: ^15.8.1 + loose-envify: ^1.1.0 + scheduler: ^0.23.0 peerDependencies: - react: ">= 16.3.0" - react-dom: ">= 16.3.0" - checksum: a5563ed8142ab77e9e68af9b5a57484358462bae76368691362419d7fb4d9fba73300b5c5d1346db6551d88743c68746dc18bc035276db1539d0ad0aff6580cc + react: ^18.2.0 + checksum: 7d323310bea3a91be2965f9468d552f201b1c27891e45ddc2d6b8f717680c95a75ae0bc1e3f5cf41472446a2589a75aed4483aee8169287909fcd59ad149e8cc languageName: node linkType: hard @@ -17885,17 +16652,10 @@ __metadata: languageName: node linkType: hard -"react-error-overlay@npm:^6.0.11": - version: 6.1.0 - resolution: "react-error-overlay@npm:6.1.0" - checksum: 4f0785ea14390e333d040e7d7d6f8b915ad9bd4b8ae6eb28e1a5338f23a0325798d20deea7572c3c129bd1d32c432b01e7a4d40ca99710e2fa1f8157929e6cda - languageName: node - linkType: hard - -"react-fast-compare@npm:^2.0.4": - version: 2.0.4 - resolution: "react-fast-compare@npm:2.0.4" - checksum: 06046595f90a4e3e3a56f40a8078c00aa71bdb064ddb98343f577f546aa22e888831fd45f009c93b34707cc842b4c637737e956fd13d6f80607ee92fb9cf9a1c +"react-error-overlay@npm:^6.0.9": + version: 6.0.11 + resolution: "react-error-overlay@npm:6.0.11" + checksum: ce7b44c38fadba9cedd7c095cf39192e632daeccf1d0747292ed524f17dcb056d16bc197ddee5723f9dd888f0b9b19c3b486c430319e30504289b9296f2d2c42 languageName: node linkType: hard @@ -17906,13 +16666,26 @@ __metadata: languageName: node linkType: hard -"react-google-charts@npm:^5.2.1": - version: 5.2.1 - resolution: "react-google-charts@npm:5.2.1" +"react-google-charts@npm:^4.0.0": + version: 4.0.1 + resolution: "react-google-charts@npm:4.0.1" peerDependencies: react: ">=16.3.0" react-dom: ">=16.3.0" - checksum: 80a03fda3e9c828e9d22919fe8b2f9cdb40cb9c38b617d9de2afa1a288304ab652604149e818c9f5fe990ffc748290b5db74539c61c3720c7d85c8d7840482ce + checksum: 874a552b07cc67d6b830718dd5e71055c46fbd0c7a12bca14078c0744111d8fead833e36a16bd0b0ea5c26f6cff0eb84b4b6de62845c945b3c47c6cc75233f9d + languageName: node + linkType: hard + +"react-google-login@npm:^5.2.2": + version: 5.2.2 + resolution: "react-google-login@npm:5.2.2" + dependencies: + "@types/react": "*" + prop-types: ^15.6.0 + peerDependencies: + react: ^16 || ^17 + react-dom: ^16 || ^17 + checksum: 29199c7035c3c1070a82241dc4063628d693f35a1736d292e3db736e52da825e8a53f9287b0b12b08a50d676973ce1349a4d8243cd849ca25fed6a4284378880 languageName: node linkType: hard @@ -17930,22 +16703,12 @@ __metadata: languageName: node linkType: hard -"react-hook-form-persist@npm:^3.0.0": - version: 3.0.0 - resolution: "react-hook-form-persist@npm:3.0.0" - peerDependencies: - react: ">= 16.3" - react-hook-form: ">= 6" - checksum: de90d45cb8ac49c636df78da96284e5f915894a639b06b95c1ce1d7da7bbd04305a52411b90693007376417dac3fd9bd3ed114dedbbae32fb15c2a588e870260 - languageName: node - linkType: hard - "react-hook-form@npm:^7.34.0": - version: 7.62.0 - resolution: "react-hook-form@npm:7.62.0" + version: 7.51.3 + resolution: "react-hook-form@npm:7.51.3" peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^19 - checksum: 76f0574d0df632c22b37c2666e8aef8b4378dfa0bcc5ae5b20c410d3103abd17e0bcf6256f8a6d9d18cbd687f96edf3fce35bf41d06872ffb412c91664361b1a + react: ^16.8.0 || ^17 || ^18 + checksum: 4ac71033b66ae0b7b9d75a1bc2053a6747fb37f68c6895ee85a72cabb890168d82990c8ca7bddd271e80fdbf58f471d14d6a0e0714400d017590d4f56b3d241f languageName: node linkType: hard @@ -17956,69 +16719,41 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^17.0.1": +"react-is@npm:^17.0.0, react-is@npm:^17.0.1": version: 17.0.2 resolution: "react-is@npm:17.0.2" checksum: 9d6d111d8990dc98bc5402c1266a808b0459b5d54830bbea24c12d908b536df7883f268a7868cfaedde3dd9d4e0d574db456f84d2e6df9c4526f99bb4b5344d8 languageName: node linkType: hard -"react-is@npm:^18.0.0, react-is@npm:^18.3.1": - version: 18.3.1 - resolution: "react-is@npm:18.3.1" - checksum: e20fe84c86ff172fc8d898251b7cc2c43645d108bf96d0b8edf39b98f9a2cae97b40520ee7ed8ee0085ccc94736c4886294456033304151c3f94978cec03df21 - languageName: node - linkType: hard - -"react-is@npm:^19.0.0, react-is@npm:^19.1.1": - version: 19.1.1 - resolution: "react-is@npm:19.1.1" - checksum: e60ed01c27fe4d22b08f8a31f18831d144a801d08a909ca31fb1d02721b4f4cde0759148d6341f660a4d6ce54a78e22b8b39520b67e2e76254e583885868ab43 - languageName: node - linkType: hard - -"react-markdown@npm:^9.0.3": - version: 9.1.0 - resolution: "react-markdown@npm:9.1.0" - dependencies: - "@types/hast": ^3.0.0 - "@types/mdast": ^4.0.0 - devlop: ^1.0.0 - hast-util-to-jsx-runtime: ^2.0.0 - html-url-attributes: ^3.0.0 - mdast-util-to-hast: ^13.0.0 - remark-parse: ^11.0.0 - remark-rehype: ^11.0.0 - unified: ^11.0.0 - unist-util-visit: ^5.0.0 - vfile: ^6.0.0 - peerDependencies: - "@types/react": ">=18" - react: ">=18" - checksum: d78ca3b6bea23a3383d067ad8eb0aec3a22a4500663f32773be45ad38572b5f1b823184fafc85c1a35ff6290bddea42b003dc7bdfc02cf20a9e0163ecd3ea605 +"react-is@npm:^18.0.0, react-is@npm:^18.2.0": + version: 18.2.0 + resolution: "react-is@npm:18.2.0" + checksum: e72d0ba81b5922759e4aff17e0252bd29988f9642ed817f56b25a3e217e13eea8a7f2322af99a06edb779da12d5d636e9fda473d620df9a3da0df2a74141d53e languageName: node linkType: hard -"react-pdf@npm:^9.2.1": - version: 9.2.1 - resolution: "react-pdf@npm:9.2.1" +"react-markdown@npm:^6.0.0": + version: 6.0.3 + resolution: "react-markdown@npm:6.0.3" dependencies: - clsx: ^2.0.0 - dequal: ^2.0.3 - make-cancellable-promise: ^1.3.1 - make-event-props: ^1.6.0 - merge-refs: ^1.3.0 - pdfjs-dist: 4.8.69 - tiny-invariant: ^1.0.0 - warning: ^4.0.0 + "@types/hast": ^2.0.0 + "@types/unist": ^2.0.3 + comma-separated-tokens: ^1.0.0 + prop-types: ^15.7.2 + property-information: ^5.3.0 + react-is: ^17.0.0 + remark-parse: ^9.0.0 + remark-rehype: ^8.0.0 + space-separated-tokens: ^1.1.0 + style-to-object: ^0.3.0 + unified: ^9.0.0 + unist-util-visit: ^2.0.0 + vfile: ^4.0.0 peerDependencies: - "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 0d90c19e0cbc3a053479f161c18060a744f3b644d9decfac05b4186ba62a36924361f239bf4d85c713ea2e1b7b304fcc659b617148c6f261c1cc3b19ca862404 + "@types/react": ">=16" + react: ">=16" + checksum: 5176e6a314a397b4747570213ae6c092f76c5c3dc67c748731243a0d4108e002134a9061cea87df1bea00db46cc7d238e092bae1609de74983c844e8386c0554 languageName: node linkType: hard @@ -18058,36 +16793,17 @@ __metadata: languageName: node linkType: hard -"react-redux@npm:^9.1.2": - version: 9.2.0 - resolution: "react-redux@npm:9.2.0" - dependencies: - "@types/use-sync-external-store": ^0.0.6 - use-sync-external-store: ^1.4.0 - peerDependencies: - "@types/react": ^18.2.25 || ^19 - react: ^18.0 || ^19 - redux: ^5.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - redux: - optional: true - checksum: 96dfe2929561d7c98d4443722738e4595f08758bde27b7bc20cd98ba9b0dfe9b81b9fa17b6888be94a0c1d2d1305397ae493a8219698536d011a941589eb82bd - languageName: node - linkType: hard - -"react-refresh@npm:^0.11.0": - version: 0.11.0 - resolution: "react-refresh@npm:0.11.0" - checksum: 112178a05b1e0ffeaf5d9fb4e56b4410a34a73adeb04dbf13abdc50d9ac9df2ada83e81485156cca0b3fa296aa3612751b3d6cd13be4464642a43679b819cbc7 +"react-refresh@npm:^0.14.0": + version: 0.14.0 + resolution: "react-refresh@npm:0.14.0" + checksum: dc69fa8c993df512f42dd0f1b604978ae89bd747c0ed5ec595c0cc50d535fb2696619ccd98ae28775cc01d0a7c146a532f0f7fb81dc22e1977c242a4912312f4 languageName: node linkType: hard -"react-refresh@npm:^0.17.0": - version: 0.17.0 - resolution: "react-refresh@npm:0.17.0" - checksum: e9d23a70543edde879263976d7909cd30c6f698fa372a1240142cf7c8bf99e0396378b9c07c2d39c3a10261d7ba07dc49f990cd8f1ac7b88952e99040a0be5e9 +"react-refresh@npm:^0.8.3": + version: 0.8.3 + resolution: "react-refresh@npm:0.8.3" + checksum: 3cffe5a9cbac1c5d59bf74bf9fff43c987d87ef32098b9092ea94b6637377d86c08565b9374d9397f446b3fbcd95de986ec77220a16f979687cb39b7b89e2f91 languageName: node linkType: hard @@ -18127,58 +16843,69 @@ __metadata: languageName: node linkType: hard -"react-scripts@npm:^5.0.1": - version: 5.0.1 - resolution: "react-scripts@npm:5.0.1" - dependencies: - "@babel/core": ^7.16.0 - "@pmmmwh/react-refresh-webpack-plugin": ^0.5.3 - "@svgr/webpack": ^5.5.0 - babel-jest: ^27.4.2 - babel-loader: ^8.2.3 - babel-plugin-named-asset-import: ^0.3.8 - babel-preset-react-app: ^10.0.1 +"react-scripts@npm:^4.0.1": + version: 4.0.3 + resolution: "react-scripts@npm:4.0.3" + dependencies: + "@babel/core": 7.12.3 + "@pmmmwh/react-refresh-webpack-plugin": 0.4.3 + "@svgr/webpack": 5.5.0 + "@typescript-eslint/eslint-plugin": ^4.5.0 + "@typescript-eslint/parser": ^4.5.0 + babel-eslint: ^10.1.0 + babel-jest: ^26.6.0 + babel-loader: 8.1.0 + babel-plugin-named-asset-import: ^0.3.7 + babel-preset-react-app: ^10.0.0 bfj: ^7.0.2 - browserslist: ^4.18.1 - camelcase: ^6.2.1 - case-sensitive-paths-webpack-plugin: ^2.4.0 - css-loader: ^6.5.1 - css-minimizer-webpack-plugin: ^3.2.0 - dotenv: ^10.0.0 - dotenv-expand: ^5.1.0 - eslint: ^8.3.0 - eslint-config-react-app: ^7.0.1 - eslint-webpack-plugin: ^3.1.1 - file-loader: ^6.2.0 - fs-extra: ^10.0.0 - fsevents: ^2.3.2 - html-webpack-plugin: ^5.5.0 - identity-obj-proxy: ^3.0.0 - jest: ^27.4.3 - jest-resolve: ^27.4.2 - jest-watch-typeahead: ^1.0.0 - mini-css-extract-plugin: ^2.4.5 - postcss: ^8.4.4 - postcss-flexbugs-fixes: ^5.0.2 - postcss-loader: ^6.2.1 - postcss-normalize: ^10.0.1 - postcss-preset-env: ^7.0.1 - prompts: ^2.4.2 - react-app-polyfill: ^3.0.0 - react-dev-utils: ^12.0.1 - react-refresh: ^0.11.0 - resolve: ^1.20.0 - resolve-url-loader: ^4.0.0 - sass-loader: ^12.3.0 - semver: ^7.3.5 - source-map-loader: ^3.0.0 - style-loader: ^3.3.1 - tailwindcss: ^3.0.2 - terser-webpack-plugin: ^5.2.5 - webpack: ^5.64.4 - webpack-dev-server: ^4.6.0 - webpack-manifest-plugin: ^4.0.2 - workbox-webpack-plugin: ^6.4.1 + camelcase: ^6.1.0 + case-sensitive-paths-webpack-plugin: 2.3.0 + css-loader: 4.3.0 + dotenv: 8.2.0 + dotenv-expand: 5.1.0 + eslint: ^7.11.0 + eslint-config-react-app: ^6.0.0 + eslint-plugin-flowtype: ^5.2.0 + eslint-plugin-import: ^2.22.1 + eslint-plugin-jest: ^24.1.0 + eslint-plugin-jsx-a11y: ^6.3.1 + eslint-plugin-react: ^7.21.5 + eslint-plugin-react-hooks: ^4.2.0 + eslint-plugin-testing-library: ^3.9.2 + eslint-webpack-plugin: ^2.5.2 + file-loader: 6.1.1 + fs-extra: ^9.0.1 + fsevents: ^2.1.3 + html-webpack-plugin: 4.5.0 + identity-obj-proxy: 3.0.0 + jest: 26.6.0 + jest-circus: 26.6.0 + jest-resolve: 26.6.0 + jest-watch-typeahead: 0.6.1 + mini-css-extract-plugin: 0.11.3 + optimize-css-assets-webpack-plugin: 5.0.4 + pnp-webpack-plugin: 1.6.4 + postcss-flexbugs-fixes: 4.2.1 + postcss-loader: 3.0.0 + postcss-normalize: 8.0.1 + postcss-preset-env: 6.7.0 + postcss-safe-parser: 5.0.2 + prompts: 2.4.0 + react-app-polyfill: ^2.0.0 + react-dev-utils: ^11.0.3 + react-refresh: ^0.8.3 + resolve: 1.18.1 + resolve-url-loader: ^3.1.2 + sass-loader: ^10.0.5 + semver: 7.3.2 + style-loader: 1.3.0 + terser-webpack-plugin: 4.2.3 + ts-pnp: 1.2.0 + url-loader: 4.1.1 + webpack: 4.44.2 + webpack-dev-server: 3.11.1 + webpack-manifest-plugin: 2.2.0 + workbox-webpack-plugin: 5.1.4 peerDependencies: react: ">= 16" typescript: ^3.2.1 || ^4 @@ -18189,8 +16916,8 @@ __metadata: typescript: optional: true bin: - react-scripts: bin/react-scripts.js - checksum: 92afa2f245c7092ccc97d5609dc7a2130616262e34da7f15072d9442e2d2e1d4909a91022abd1faac1336eb17c5525a10d9bd43e1ae374c7ec941ca20addca68 + react-scripts: ./bin/react-scripts.js + checksum: a05a46ce3145b42ac8b57633d3b90b6689c24697c1449bccf219349996d718a3cd0796e4910f4ab6abb5b024982cafd62345e88c8e7b42a45efca3bef1a0eb87 languageName: node linkType: hard @@ -18203,20 +16930,6 @@ __metadata: languageName: node linkType: hard -"react-smooth@npm:^4.0.4": - version: 4.0.4 - resolution: "react-smooth@npm:4.0.4" - dependencies: - fast-equals: ^5.0.1 - prop-types: ^15.8.1 - react-transition-group: ^4.4.5 - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - checksum: 909305d40bae79a011ff21a10c4bc7ddadc87ac5ff093b4a5f827f730f093ec4e044c4330688d29b3ad2db83aab8997c3bb1bae550a9c66de74521b8ed52cc53 - languageName: node - linkType: hard - "react-transition-group@npm:^4.4.5": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5" @@ -18233,35 +16946,61 @@ __metadata: linkType: hard "react-use-measure@npm:^2.1.1": - version: 2.1.7 - resolution: "react-use-measure@npm:2.1.7" + version: 2.1.1 + resolution: "react-use-measure@npm:2.1.1" + dependencies: + debounce: ^1.2.1 peerDependencies: react: ">=16.13" react-dom: ">=16.13" - peerDependenciesMeta: - react-dom: - optional: true - checksum: 5f00c14cf50b0710cdbd27b63a005be20283099d2fa2723a97f3a1cf0b2daedddd67249520c21e49e95348f56428689f3229c343dcb9ed37da58f9c227d29bee + checksum: b8e8939229d463c3c505f7b617925c0228efae0cd6f651371f463846417b06c9170be57df51293a61027c41770f8a090fdb8a08717c4e36290ccb496e0318f1f + languageName: node + linkType: hard + +"react@npm:^18.2.0": + version: 18.2.0 + resolution: "react@npm:18.2.0" + dependencies: + loose-envify: ^1.1.0 + checksum: 88e38092da8839b830cda6feef2e8505dec8ace60579e46aa5490fc3dc9bba0bd50336507dc166f43e3afc1c42939c09fe33b25fae889d6f402721dcd78fca1b + languageName: node + linkType: hard + +"read-pkg-up@npm:^7.0.1": + version: 7.0.1 + resolution: "read-pkg-up@npm:7.0.1" + dependencies: + find-up: ^4.1.0 + read-pkg: ^5.2.0 + type-fest: ^0.8.1 + checksum: e4e93ce70e5905b490ca8f883eb9e48b5d3cebc6cd4527c25a0d8f3ae2903bd4121c5ab9c5a3e217ada0141098eeb661313c86fa008524b089b8ed0b7f165e44 languageName: node linkType: hard -"react@npm:19.0.0": - version: 19.0.0 - resolution: "react@npm:19.0.0" - checksum: 86de15d85b2465feb40297a90319c325cb07cf27191a361d47bcfe8c6126c973d660125aa67b8f4cbbe39f15a2f32efd0c814e98196d8e5b68c567ba40a399c6 +"read-pkg@npm:^4.0.1": + version: 4.0.1 + resolution: "read-pkg@npm:4.0.1" + dependencies: + normalize-package-data: ^2.3.2 + parse-json: ^4.0.0 + pify: ^3.0.0 + checksum: 56193535486c50a0a40039e4a92f68676362f5a7160628ca4d856c62509e125220f69c562a32940dcc51e3dcd38211af69756bbb5b8a1aed1d09be1bedd1e1a5 languageName: node linkType: hard -"read-cache@npm:^1.0.0": - version: 1.0.0 - resolution: "read-cache@npm:1.0.0" +"read-pkg@npm:^5.2.0": + version: 5.2.0 + resolution: "read-pkg@npm:5.2.0" dependencies: - pify: ^2.3.0 - checksum: cffc728b9ede1e0667399903f9ecaf3789888b041c46ca53382fa3a06303e5132774dc0a96d0c16aa702dbac1ea0833d5a868d414f5ab2af1e1438e19e6657c6 + "@types/normalize-package-data": ^2.4.0 + normalize-package-data: ^2.5.0 + parse-json: ^5.0.0 + type-fest: ^0.6.0 + checksum: eb696e60528b29aebe10e499ba93f44991908c57d70f2d26f369e46b8b9afc208ef11b4ba64f67630f31df8b6872129e0a8933c8c53b7b4daf0eace536901222 languageName: node linkType: hard -"readable-stream@npm:^2.0.1, readable-stream@npm:^2.2.2": +"readable-stream@npm:1 || 2, readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.1.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.6, readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -18276,7 +17015,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.0.2, readable-stream@npm:^3.0.6, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": +"readable-stream@npm:^3.0.2, readable-stream@npm:^3.0.6, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -18287,10 +17026,14 @@ __metadata: languageName: node linkType: hard -"readdirp@npm:^4.0.1": - version: 4.1.2 - resolution: "readdirp@npm:4.1.2" - checksum: 3242ee125422cb7c0e12d51452e993f507e6ed3d8c490bc8bf3366c5cdd09167562224e429b13e9cb2b98d4b8b2b11dc100d3c73883aa92d657ade5a21ded004 +"readdirp@npm:^2.2.1": + version: 2.2.1 + resolution: "readdirp@npm:2.2.1" + dependencies: + graceful-fs: ^4.1.11 + micromatch: ^3.1.10 + readable-stream: ^2.0.2 + checksum: 3879b20f1a871e0e004a14fbf1776e65ee0b746a62f5a416010808b37c272ac49b023c47042c7b1e281cba75a449696635bc64c397ed221ea81d853a8f2ed79a languageName: node linkType: hard @@ -18303,40 +17046,12 @@ __metadata: languageName: node linkType: hard -"recharts-scale@npm:^0.4.4": - version: 0.4.5 - resolution: "recharts-scale@npm:0.4.5" - dependencies: - decimal.js-light: ^2.4.1 - checksum: e970377190a610e684a32c7461c7684ac3603c2e0ac0020bbba1eea9d099b38138143a8e80bf769bb49c0b7cecf22a2f5c6854885efed2d56f4540d4aa7052bd - languageName: node - linkType: hard - -"recharts@npm:^2.15.3": - version: 2.15.4 - resolution: "recharts@npm:2.15.4" - dependencies: - clsx: ^2.0.0 - eventemitter3: ^4.0.1 - lodash: ^4.17.21 - react-is: ^18.3.1 - react-smooth: ^4.0.4 - recharts-scale: ^0.4.4 - tiny-invariant: ^1.3.1 - victory-vendor: ^36.6.8 - peerDependencies: - react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - checksum: 7d7d89da8875a7aa3e157d4caf6c8fdbaf22fcf111c70cd67d8259dca6b7f878287b6f2db5af9b2daf6a85046de06ca2dcf18cb7cd7bb5a6ddd3639690c5d888 - languageName: node - linkType: hard - -"recursive-readdir@npm:^2.2.2": - version: 2.2.3 - resolution: "recursive-readdir@npm:2.2.3" +"recursive-readdir@npm:2.2.2": + version: 2.2.2 + resolution: "recursive-readdir@npm:2.2.2" dependencies: - minimatch: ^3.0.5 - checksum: 88ec96e276237290607edc0872b4f9842837b95cfde0cdbb1e00ba9623dfdf3514d44cdd14496ab60a0c2dd180a6ef8a3f1c34599e6cf2273afac9b72a6fb2b5 + minimatch: 3.0.4 + checksum: a6b22994d76458443d4a27f5fd7147ac63ad31bba972666a291d511d4d819ee40ff71ba7524c14f6a565b8cfaf7f48b318f971804b913cf538d58f04e25d1fee languageName: node linkType: hard @@ -18350,35 +17065,27 @@ __metadata: languageName: node linkType: hard -"redux@npm:^5.0.1": - version: 5.0.1 - resolution: "redux@npm:5.0.1" - checksum: e74affa9009dd5d994878b9a1ce30d6569d986117175056edb003de2651c05b10fe7819d6fa94aea1a94de9a82f252f986547f007a2fbeb35c317a2e5f5ecf2c - languageName: node - linkType: hard - -"reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9": - version: 1.0.10 - resolution: "reflect.getprototypeof@npm:1.0.10" +"reflect.getprototypeof@npm:^1.0.4": + version: 1.0.6 + resolution: "reflect.getprototypeof@npm:1.0.6" dependencies: - call-bind: ^1.0.8 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.23.9 + es-abstract: ^1.23.1 es-errors: ^1.3.0 - es-object-atoms: ^1.0.0 - get-intrinsic: ^1.2.7 - get-proto: ^1.0.1 - which-builtin-type: ^1.2.1 - checksum: ccc5debeb66125e276ae73909cecb27e47c35d9bb79d9cc8d8d055f008c58010ab8cb401299786e505e4aab733a64cba9daf5f312a58e96a43df66adad221870 + get-intrinsic: ^1.2.4 + globalthis: ^1.0.3 + which-builtin-type: ^1.1.3 + checksum: 88e9e65a7eaa0bf8e9a8bbf8ac07571363bc333ba8b6769ed5e013e0042ed7c385e97fae9049510b3b5fe4b42472d8f32de9ce8ce84902bc4297d4bbe3777dba languageName: node linkType: hard -"regenerate-unicode-properties@npm:^10.2.2": - version: 10.2.2 - resolution: "regenerate-unicode-properties@npm:10.2.2" +"regenerate-unicode-properties@npm:^10.1.0": + version: 10.1.1 + resolution: "regenerate-unicode-properties@npm:10.1.1" dependencies: regenerate: ^1.4.2 - checksum: 7ae4c1c32460c4360e3118c45eec0621424908f430fdd6f162c9172067786bf2b1682fbc885a33b26bc85e76e06f4d3f398b52425e801b0bb0cbae147dafb0b2 + checksum: b80958ef40f125275824c2c47d5081dfaefebd80bff26c76761e9236767c748a4a95a69c053fe29d2df881177f2ca85df4a71fe70a82360388b31159ef19adcf languageName: node linkType: hard @@ -18389,31 +17096,62 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.13.9": +"regenerator-runtime@npm:^0.11.0": + version: 0.11.1 + resolution: "regenerator-runtime@npm:0.11.1" + checksum: 3c97bd2c7b2b3247e6f8e2147a002eb78c995323732dad5dc70fac8d8d0b758d0295e7015b90d3d444446ae77cbd24b9f9123ec3a77018e81d8999818301b4f4 + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.13.7": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4 languageName: node linkType: hard +"regenerator-runtime@npm:^0.14.0": + version: 0.14.1 + resolution: "regenerator-runtime@npm:0.14.1" + checksum: 9f57c93277b5585d3c83b0cf76be47b473ae8c6d9142a46ce8b0291a04bb2cf902059f0f8445dcabb3fb7378e5fe4bb4ea1e008876343d42e46d3b484534ce38 + languageName: node + linkType: hard + +"regenerator-transform@npm:^0.15.2": + version: 0.15.2 + resolution: "regenerator-transform@npm:0.15.2" + dependencies: + "@babel/runtime": ^7.8.4 + checksum: 20b6f9377d65954980fe044cfdd160de98df415b4bff38fbade67b3337efaf078308c4fed943067cd759827cc8cfeca9cb28ccda1f08333b85d6a2acbd022c27 + languageName: node + linkType: hard + +"regex-not@npm:^1.0.0, regex-not@npm:^1.0.2": + version: 1.0.2 + resolution: "regex-not@npm:1.0.2" + dependencies: + extend-shallow: ^3.0.2 + safe-regex: ^1.1.0 + checksum: 3081403de79559387a35ef9d033740e41818a559512668cef3d12da4e8a29ef34ee13c8ed1256b07e27ae392790172e8a15c8a06b72962fd4550476cde3d8f77 + languageName: node + linkType: hard + "regex-parser@npm:^2.2.11": - version: 2.3.1 - resolution: "regex-parser@npm:2.3.1" - checksum: 37d5549040782207b98a5c007b739f85bf43f70249cbf813954d3fab370b93f3c8029534c62ca7c56e7a61e24848118b1bae15668b80ab7e67b4bb98465d54cc + version: 2.3.0 + resolution: "regex-parser@npm:2.3.0" + checksum: bcd1eb7e9b0775b6f44928ceb0280ad5b6e4da91e1070d3e9a653fcf72d2d04873c44190fb569141b6897fe94e9514fee1f3ac7ba112ccd9c9b5ad6eabab6bbd languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": - version: 1.5.4 - resolution: "regexp.prototype.flags@npm:1.5.4" +"regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.2": + version: 1.5.2 + resolution: "regexp.prototype.flags@npm:1.5.2" dependencies: - call-bind: ^1.0.8 + call-bind: ^1.0.6 define-properties: ^1.2.1 es-errors: ^1.3.0 - get-proto: ^1.0.1 - gopd: ^1.2.0 - set-function-name: ^2.0.2 - checksum: 18cb667e56cb328d2dda569d7f04e3ea78f2683135b866d606538cf7b1d4271f7f749f09608c877527799e6cf350e531368f3c7a20ccd1bb41048a48926bdeeb + set-function-name: ^2.0.1 + checksum: d7f333667d5c564e2d7a97c56c3075d64c722c9bb51b2b4df6822b2e8096d623a5e63088fb4c83df919b6951ef8113841de8b47de7224872fa6838bc5d8a7d64 languageName: node linkType: hard @@ -18424,35 +17162,28 @@ __metadata: languageName: node linkType: hard -"regexpu-core@npm:^6.2.0": - version: 6.3.1 - resolution: "regexpu-core@npm:6.3.1" +"regexpu-core@npm:^5.3.1": + version: 5.3.2 + resolution: "regexpu-core@npm:5.3.2" dependencies: + "@babel/regjsgen": ^0.8.0 regenerate: ^1.4.2 - regenerate-unicode-properties: ^10.2.2 - regjsgen: ^0.8.0 - regjsparser: ^0.12.0 + regenerate-unicode-properties: ^10.1.0 + regjsparser: ^0.9.1 unicode-match-property-ecmascript: ^2.0.0 - unicode-match-property-value-ecmascript: ^2.2.1 - checksum: 601a8298bca4d074c239e3b989b3b5f7532e4c8bde4e6d45690d4ba01d4f331869df3899a260a0fd88ecdb8902082725845447b0e2a3e1b0a1364131970489cb - languageName: node - linkType: hard - -"regjsgen@npm:^0.8.0": - version: 0.8.0 - resolution: "regjsgen@npm:0.8.0" - checksum: a1d925ff14a4b2be774e45775ee6b33b256f89c42d480e6d85152d2133f18bd3d6af662161b226fa57466f7efec367eaf7ccd2a58c0ec2a1306667ba2ad07b0d + unicode-match-property-value-ecmascript: ^2.1.0 + checksum: 95bb97088419f5396e07769b7de96f995f58137ad75fac5811fb5fe53737766dfff35d66a0ee66babb1eb55386ef981feaef392f9df6d671f3c124812ba24da2 languageName: node linkType: hard -"regjsparser@npm:^0.12.0": - version: 0.12.0 - resolution: "regjsparser@npm:0.12.0" +"regjsparser@npm:^0.9.1": + version: 0.9.1 + resolution: "regjsparser@npm:0.9.1" dependencies: - jsesc: ~3.0.2 + jsesc: ~0.5.0 bin: regjsparser: bin/parser - checksum: 094b55b0ab3e1fd58f8ce5132a1d44dab08d91f7b0eea4132b0157b303ebb8ded20a9cbd893d25402d2aeddb23fac1f428ab4947b295d6fa51dd1c334a9e76f0 + checksum: 5e1b76afe8f1d03c3beaf9e0d935dd467589c3625f6d65fb8ffa14f224d783a0fed4bf49c2c1b8211043ef92b6117313419edf055a098ed8342e340586741afc languageName: node linkType: hard @@ -18463,28 +17194,21 @@ __metadata: languageName: node linkType: hard -"remark-parse@npm:^11.0.0": - version: 11.0.0 - resolution: "remark-parse@npm:11.0.0" +"remark-parse@npm:^9.0.0": + version: 9.0.0 + resolution: "remark-parse@npm:9.0.0" dependencies: - "@types/mdast": ^4.0.0 - mdast-util-from-markdown: ^2.0.0 - micromark-util-types: ^2.0.0 - unified: ^11.0.0 - checksum: d83d245290fa84bb04fb3e78111f09c74f7417e7c012a64dd8dc04fccc3699036d828fbd8eeec8944f774b6c30cc1d925c98f8c46495ebcee7c595496342ab7f + mdast-util-from-markdown: ^0.8.0 + checksum: 50104880549639b7dd7ae6f1e23c214915fe9c054f02f3328abdaee3f6de6d7282bf4357c3c5b106958fe75e644a3c248c2197755df34f9955e8e028fc74868f languageName: node linkType: hard -"remark-rehype@npm:^11.0.0": - version: 11.1.2 - resolution: "remark-rehype@npm:11.1.2" +"remark-rehype@npm:^8.0.0": + version: 8.1.0 + resolution: "remark-rehype@npm:8.1.0" dependencies: - "@types/hast": ^3.0.0 - "@types/mdast": ^4.0.0 - mdast-util-to-hast: ^13.0.0 - unified: ^11.0.0 - vfile: ^6.0.0 - checksum: 6eab55cb3464ec01d8e002cc9fe02ae57f48162899693fd53b5ba553ac8699dae7b55fce9df7131a5981313b19b495d6fbfa98a9d6bd243e7485591364d9b5b3 + mdast-util-to-hast: ^10.2.0 + checksum: e1152464cfa83c14b570b1cb85eb9b3667795b5bed2f6b16d1c6e96c369816b07945a3c04eb0e1fd57a19cc1837969527d0056d5b6d179f1290688db2a7e2c5f languageName: node linkType: hard @@ -18495,16 +17219,37 @@ __metadata: languageName: node linkType: hard -"renderkid@npm:^3.0.0": - version: 3.0.0 - resolution: "renderkid@npm:3.0.0" +"remove-trailing-separator@npm:^1.0.1": + version: 1.1.0 + resolution: "remove-trailing-separator@npm:1.1.0" + checksum: d3c20b5a2d987db13e1cca9385d56ecfa1641bae143b620835ac02a6b70ab88f68f117a0021838db826c57b31373d609d52e4f31aca75fc490c862732d595419 + languageName: node + linkType: hard + +"renderkid@npm:^2.0.4": + version: 2.0.7 + resolution: "renderkid@npm:2.0.7" dependencies: css-select: ^4.1.3 dom-converter: ^0.2.0 htmlparser2: ^6.1.0 lodash: ^4.17.21 - strip-ansi: ^6.0.1 - checksum: 77162b62d6f33ab81f337c39efce0439ff0d1f6d441e29c35183151f83041c7850774fb904da163d6c844264d440d10557714e6daa0b19e4561a5cd4ef305d41 + strip-ansi: ^3.0.1 + checksum: d3d7562531fb8104154d4aa6aa977707783616318014088378a6c5bbc36318ada9289543d380ede707e531b7f5b96229e87d1b8944f675e5ec3686e62692c7c7 + languageName: node + linkType: hard + +"repeat-element@npm:^1.1.2": + version: 1.1.4 + resolution: "repeat-element@npm:1.1.4" + checksum: 1edd0301b7edad71808baad226f0890ba709443f03a698224c9ee4f2494c317892dc5211b2ba8cbea7194a9ddbcac01e283bd66de0467ab24ee1fc1a3711d8a9 + languageName: node + linkType: hard + +"repeat-string@npm:^1.6.1": + version: 1.6.1 + resolution: "repeat-string@npm:1.6.1" + checksum: 1b809fc6db97decdc68f5b12c4d1a671c8e3f65ec4a40c238bc5200e44e85bcc52a54f78268ab9c29fcf5fe4f1343e805420056d1f30fa9a9ee4c2d93e3cc6c0 languageName: node linkType: hard @@ -18550,10 +17295,12 @@ __metadata: languageName: node linkType: hard -"resize-observer-polyfill@npm:1.5.0": - version: 1.5.0 - resolution: "resize-observer-polyfill@npm:1.5.0" - checksum: ecc6aab5d4f967f1b76cee0748c1967c8b6b5d8c4393764ca3b788dbd15c0f846326c4ebff9f4f39aba45fea8016cd42bb95e28e8fab1d14349e173790c58133 +"resolve-cwd@npm:^2.0.0": + version: 2.0.0 + resolution: "resolve-cwd@npm:2.0.0" + dependencies: + resolve-from: ^3.0.0 + checksum: e7c16880c460656e77f102d537a6dc82b3657d9173697cd6ea82ffce37df96f6c1fc79d0bb35fd73fff8871ac13f21b4396958b5f0a13e5b99c97d69f5e319fa languageName: node linkType: hard @@ -18566,6 +17313,13 @@ __metadata: languageName: node linkType: hard +"resolve-from@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-from@npm:3.0.0" + checksum: fff9819254d2d62b57f74e5c2ca9c0bdd425ca47287c4d801bc15f947533148d858229ded7793b0f59e61e49e782fffd6722048add12996e1bd4333c29669062 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -18587,44 +17341,51 @@ __metadata: languageName: node linkType: hard -"resolve-url-loader@npm:^4.0.0": - version: 4.0.0 - resolution: "resolve-url-loader@npm:4.0.0" - dependencies: - adjust-sourcemap-loader: ^4.0.0 - convert-source-map: ^1.7.0 - loader-utils: ^2.0.0 - postcss: ^7.0.35 - source-map: 0.6.1 - peerDependencies: +"resolve-url-loader@npm:^3.1.2": + version: 3.1.5 + resolution: "resolve-url-loader@npm:3.1.5" + dependencies: + adjust-sourcemap-loader: 3.0.0 + camelcase: 5.3.1 + compose-function: 3.0.3 + convert-source-map: 1.7.0 + es6-iterator: 2.0.3 + loader-utils: ^1.2.3 + postcss: 7.0.36 rework: 1.0.1 rework-visit: 1.0.0 - peerDependenciesMeta: - rework: - optional: true - rework-visit: - optional: true - checksum: 8e5bcf97867a5e128b6b86988d445b7fbd1214f7c5c0214332f835e8607438e153d9b3899799a03ddd03540254bb591e572feb330981a4478be934f6f045c925 + source-map: 0.6.1 + checksum: eb52911eff20723f07409cc12138d254fa0dd4a4f3b1ba11ee1b29912afb03f1272aaddb523658be1e3a946e0d1bf6f603d0e107753ab83d48ad2116cf04b7f6 languageName: node linkType: hard -"resolve.exports@npm:^1.1.0": - version: 1.1.1 - resolution: "resolve.exports@npm:1.1.1" - checksum: 485aa10082eb388a569d696e17ad7b16f4186efc97dd34eadd029d95b811f21ffee13b1b733198bb4584dbb3cb296aa6f141835221fb7613b9606b84f1386655 +"resolve-url@npm:^0.2.1": + version: 0.2.1 + resolution: "resolve-url@npm:0.2.1" + checksum: 7b7035b9ed6e7bc7d289e90aef1eab5a43834539695dac6416ca6e91f1a94132ae4796bbd173cdacfdc2ade90b5f38a3fb6186bebc1b221cd157777a23b9ad14 + languageName: node + linkType: hard + +"resolve@npm:1.18.1": + version: 1.18.1 + resolution: "resolve@npm:1.18.1" + dependencies: + is-core-module: ^2.0.0 + path-parse: ^1.0.6 + checksum: bab3686fa87576ac7e7f68481e25494f99b8413f3bc5048c5284eabe021f98917a50c625f8a1920a87ffc347b076c12a4a685d46d5fc98f337cf2dd3792014f4 languageName: node linkType: hard -"resolve@npm:^1.1.7, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.10, resolve@npm:^1.22.4, resolve@npm:^1.22.8": - version: 1.22.10 - resolution: "resolve@npm:1.22.10" +"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.18.1, resolve@npm:^1.19.0, resolve@npm:^1.22.4, resolve@npm:^1.3.2": + version: 1.22.8 + resolution: "resolve@npm:1.22.8" dependencies: - is-core-module: ^2.16.0 + is-core-module: ^2.13.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: ab7a32ff4046fcd7c6fdd525b24a7527847d03c3650c733b909b01b757f92eb23510afa9cc3e9bf3f26a3e073b48c88c706dfd4c1d2fb4a16a96b73b6328ddcf + checksum: f8a26958aa572c9b064562750b52131a37c29d072478ea32e129063e2da7f83e31f7f11e7087a18225a8561cfe8d2f0df9dbea7c9d331a897571c0a2527dbb4c languageName: node linkType: hard @@ -18641,16 +17402,26 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.10#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.22.8#~builtin": - version: 1.22.10 - resolution: "resolve@patch:resolve@npm%3A1.22.10#~builtin::version=1.22.10&hash=07638b" +"resolve@patch:resolve@1.18.1#~builtin": + version: 1.18.1 + resolution: "resolve@patch:resolve@npm%3A1.18.1#~builtin::version=1.18.1&hash=07638b" + dependencies: + is-core-module: ^2.0.0 + path-parse: ^1.0.6 + checksum: 7439c8f3d8fa00c9dc800ef3c8ed0bd8e8772823e6e4948b1a77487759e0fb905381808caae96398d135619af90654d8e74cac778e5b8c9d7138f2dd52bb2bba + languageName: node + linkType: hard + +"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.18.1#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.3.2#~builtin": + version: 1.22.8 + resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=07638b" dependencies: - is-core-module: ^2.16.0 + is-core-module: ^2.13.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 8aac1e4e4628bd00bf4b94b23de137dd3fe44097a8d528fd66db74484be929936e20c696e1a3edf4488f37e14180b73df6f600992baea3e089e8674291f16c9d + checksum: 5479b7d431cacd5185f8db64bfcb7286ae5e31eb299f4c4f404ad8aa6098b77599563ac4257cb2c37a42f59dfc06a1bec2bcf283bb448f319e37f0feb9a09847 languageName: node linkType: hard @@ -18667,6 +17438,23 @@ __metadata: languageName: node linkType: hard +"restore-cursor@npm:^3.1.0": + version: 3.1.0 + resolution: "restore-cursor@npm:3.1.0" + dependencies: + onetime: ^5.1.0 + signal-exit: ^3.0.2 + checksum: f877dd8741796b909f2a82454ec111afb84eb45890eb49ac947d87991379406b3b83ff9673a46012fca0d7844bb989f45cc5b788254cf1a39b6b5a9659de0630 + languageName: node + linkType: hard + +"ret@npm:~0.1.10": + version: 0.1.15 + resolution: "ret@npm:0.1.15" + checksum: d76a9159eb8c946586567bd934358dfc08a36367b3257f7a3d7255fdd7b56597235af23c6afa0d7f0254159e8051f93c918809962ebd6df24ca2a83dbe4d4151 + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -18681,17 +17469,41 @@ __metadata: languageName: node linkType: hard -"rettime@npm:^0.7.0": - version: 0.7.0 - resolution: "rettime@npm:0.7.0" - checksum: 1ad3984a4f8000adf56c623882170115d7453b3bbaed56429a40077b067fad98c1c5db9a58e63793add15a97006fa7c817516d985c3347df40b5d274dc087803 +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: c3076ebcc22a6bc252cb0b9c77561795256c22b757f40c0d8110b1300723f15ec0fc8685e8d4ea6d7666f36c79ccc793b1939c748bf36f18f542744a4e379fcc languageName: node linkType: hard -"reusify@npm:^1.0.4": - version: 1.1.0 - resolution: "reusify@npm:1.1.0" - checksum: 64cb3142ac5e9ad689aca289585cb41d22521f4571f73e9488af39f6b1bd62f0cbb3d65e2ecc768ec6494052523f473f1eb4b55c3e9014b3590c17fc6a03e22a +"rework-visit@npm:1.0.0": + version: 1.0.0 + resolution: "rework-visit@npm:1.0.0" + checksum: 969ca1f4e5bf4a1755c464a9b498da51eb3f28a798cf73da2cf0a3a3ab7b21a2f05c9d3bfa5fb81c8aaf5487dd31679efa67b8d0f418277ef5deb2a230b17c81 + languageName: node + linkType: hard + +"rework@npm:1.0.1": + version: 1.0.1 + resolution: "rework@npm:1.0.1" + dependencies: + convert-source-map: ^0.3.3 + css: ^2.0.0 + checksum: 13e5054d81ac84eee488fd4bacd20d08f35683bd8e296b4358e7f0a41b2d30a959313b7794f388f336705ad18d36af6ee7080e1b6c1313ecf33bc51d1bd95971 + languageName: node + linkType: hard + +"rgb-regex@npm:^1.0.1": + version: 1.0.1 + resolution: "rgb-regex@npm:1.0.1" + checksum: b270ce8bc14782d2d21d3184c1e6c65b465476d8f03e72b93ef57c95710a452b2fe280e1d516c88873aec06efd7f71373e673f114b9d99f3a4f9a0393eb00126 + languageName: node + linkType: hard + +"rgba-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "rgba-regex@npm:1.0.0" + checksum: 7f2cd271572700faea50753d82524cb2b98f17a5b9722965c7076f6cd674fe545f28145b7ef2cccabc9eca2475c793db16862cd5e7b3784a9f4b8d6496431057 languageName: node linkType: hard @@ -18706,134 +17518,102 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^6.0.1": - version: 6.0.1 - resolution: "rimraf@npm:6.0.1" +"rimraf@npm:^2.5.4, rimraf@npm:^2.6.3": + version: 2.7.1 + resolution: "rimraf@npm:2.7.1" dependencies: - glob: ^11.0.0 - package-json-from-dist: ^1.0.0 + glob: ^7.1.3 bin: - rimraf: dist/esm/bin.mjs - checksum: 8ba5b84131c1344e9417cb7e8c05d8368bb73cbe5dd4c1d5eb49fc0b558209781658d18c450460e30607d0b7865bb067482839a2f343b186b07ae87715837e66 + rimraf: ./bin.js + checksum: cdc7f6eacb17927f2a075117a823e1c5951792c6498ebcce81ca8203454a811d4cf8900314154d3259bb8f0b42ab17f67396a8694a54cae3283326e57ad250cd languageName: node linkType: hard -"rollup-plugin-terser@npm:^7.0.0": - version: 7.0.2 - resolution: "rollup-plugin-terser@npm:7.0.2" +"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": + version: 2.0.2 + resolution: "ripemd160@npm:2.0.2" dependencies: - "@babel/code-frame": ^7.10.4 - jest-worker: ^26.2.1 + hash-base: ^3.0.0 + inherits: ^2.0.1 + checksum: 006accc40578ee2beae382757c4ce2908a826b27e2b079efdcd2959ee544ddf210b7b5d7d5e80467807604244e7388427330f5c6d4cd61e6edaddc5773ccc393 + languageName: node + linkType: hard + +"rollup-plugin-babel@npm:^4.3.3": + version: 4.4.0 + resolution: "rollup-plugin-babel@npm:4.4.0" + dependencies: + "@babel/helper-module-imports": ^7.0.0 + rollup-pluginutils: ^2.8.1 + peerDependencies: + "@babel/core": 7 || ^7.0.0-rc.2 + rollup: ">=0.60.0 <3" + checksum: 5b8ed7c0a4192d7c74689074c910c1670eb07dfc875b1f4af5694a94c46bcb168ba85e2c9753030131efd6261ece7c252b9695953d0ea96d944977c6e79930d3 + languageName: node + linkType: hard + +"rollup-plugin-terser@npm:^5.3.1": + version: 5.3.1 + resolution: "rollup-plugin-terser@npm:5.3.1" + dependencies: + "@babel/code-frame": ^7.5.5 + jest-worker: ^24.9.0 + rollup-pluginutils: ^2.8.2 serialize-javascript: ^4.0.0 - terser: ^5.0.0 + terser: ^4.6.2 peerDependencies: - rollup: ^2.0.0 - checksum: af84bb7a7a894cd00852b6486528dfb8653cf94df4c126f95f389a346f401d054b08c46bee519a2ab6a22b33804d1d6ac6d8c90b1b2bf8fffb097eed73fc3c72 + rollup: ">=0.66.0 <3" + checksum: 50f9e8fa6737fa5e8aeca6a52b59ea3bc66faebe743bdfe9ce0484298cd1978082026721b182d79bcc88240429842dc58feae88d6c238b47cafc1684e0320a73 languageName: node linkType: hard -"rollup@npm:^2.43.1": - version: 2.79.2 - resolution: "rollup@npm:2.79.2" +"rollup-pluginutils@npm:^2.8.1, rollup-pluginutils@npm:^2.8.2": + version: 2.8.2 + resolution: "rollup-pluginutils@npm:2.8.2" dependencies: - fsevents: ~2.3.2 - dependenciesMeta: - fsevents: - optional: true + estree-walker: ^0.6.1 + checksum: 339fdf866d8f4ff6e408fa274c0525412f7edb01dc46b5ccda51f575b7e0d20ad72965773376fb5db95a77a7fcfcab97bf841ec08dbadf5d6b08af02b7a2cf5e + languageName: node + linkType: hard + +"rollup@npm:^1.31.1": + version: 1.32.1 + resolution: "rollup@npm:1.32.1" + dependencies: + "@types/estree": "*" + "@types/node": "*" + acorn: ^7.1.0 bin: rollup: dist/bin/rollup - checksum: df7aa4c8b95245dede157b06ab71e1921de6080757d30e9bf31f8fb142064d12dda865e2bafbab4349588f43425b2965a290c9a5da1c048246a70fc21734ebd7 - languageName: node - linkType: hard - -"rollup@npm:^4.20.0, rollup@npm:^4.23.0, rollup@npm:^4.43.0": - version: 4.50.1 - resolution: "rollup@npm:4.50.1" - dependencies: - "@rollup/rollup-android-arm-eabi": 4.50.1 - "@rollup/rollup-android-arm64": 4.50.1 - "@rollup/rollup-darwin-arm64": 4.50.1 - "@rollup/rollup-darwin-x64": 4.50.1 - "@rollup/rollup-freebsd-arm64": 4.50.1 - "@rollup/rollup-freebsd-x64": 4.50.1 - "@rollup/rollup-linux-arm-gnueabihf": 4.50.1 - "@rollup/rollup-linux-arm-musleabihf": 4.50.1 - "@rollup/rollup-linux-arm64-gnu": 4.50.1 - "@rollup/rollup-linux-arm64-musl": 4.50.1 - "@rollup/rollup-linux-loongarch64-gnu": 4.50.1 - "@rollup/rollup-linux-ppc64-gnu": 4.50.1 - "@rollup/rollup-linux-riscv64-gnu": 4.50.1 - "@rollup/rollup-linux-riscv64-musl": 4.50.1 - "@rollup/rollup-linux-s390x-gnu": 4.50.1 - "@rollup/rollup-linux-x64-gnu": 4.50.1 - "@rollup/rollup-linux-x64-musl": 4.50.1 - "@rollup/rollup-openharmony-arm64": 4.50.1 - "@rollup/rollup-win32-arm64-msvc": 4.50.1 - "@rollup/rollup-win32-ia32-msvc": 4.50.1 - "@rollup/rollup-win32-x64-msvc": 4.50.1 - "@types/estree": 1.0.8 + checksum: 3a02731c20c71321fae647c9c9cab0febee0580c6af029fdcd5dd6f424b8c85119d92c8554c6837327fd323c2458e92d955bbebc90ca6bed87cc626695e7c31f + languageName: node + linkType: hard + +"rollup@npm:^3.27.1": + version: 3.29.4 + resolution: "rollup@npm:3.29.4" + dependencies: fsevents: ~2.3.2 dependenciesMeta: - "@rollup/rollup-android-arm-eabi": - optional: true - "@rollup/rollup-android-arm64": - optional: true - "@rollup/rollup-darwin-arm64": - optional: true - "@rollup/rollup-darwin-x64": - optional: true - "@rollup/rollup-freebsd-arm64": - optional: true - "@rollup/rollup-freebsd-x64": - optional: true - "@rollup/rollup-linux-arm-gnueabihf": - optional: true - "@rollup/rollup-linux-arm-musleabihf": - optional: true - "@rollup/rollup-linux-arm64-gnu": - optional: true - "@rollup/rollup-linux-arm64-musl": - optional: true - "@rollup/rollup-linux-loongarch64-gnu": - optional: true - "@rollup/rollup-linux-ppc64-gnu": - optional: true - "@rollup/rollup-linux-riscv64-gnu": - optional: true - "@rollup/rollup-linux-riscv64-musl": - optional: true - "@rollup/rollup-linux-s390x-gnu": - optional: true - "@rollup/rollup-linux-x64-gnu": - optional: true - "@rollup/rollup-linux-x64-musl": - optional: true - "@rollup/rollup-openharmony-arm64": - optional: true - "@rollup/rollup-win32-arm64-msvc": - optional: true - "@rollup/rollup-win32-ia32-msvc": - optional: true - "@rollup/rollup-win32-x64-msvc": - optional: true fsevents: optional: true bin: rollup: dist/bin/rollup - checksum: 3d825ac7fa5c099b09738cb7b6288b27c242d54dfb07c8140f05dea8c33373f70968ed1b50b8b230ed694ac3404eb13739f6dbfb810fa51278200ed91893d301 + checksum: 8bb20a39c8d91130825159c3823eccf4dc2295c9a0a5c4ed851a5bf2167dbf24d9a29f23461a54c955e5506395e6cc188eafc8ab0e20399d7489fb33793b184e languageName: node linkType: hard -"router@npm:^2.2.0": - version: 2.2.0 - resolution: "router@npm:2.2.0" - dependencies: - debug: ^4.4.0 - depd: ^2.0.0 - is-promise: ^4.0.0 - parseurl: ^1.3.3 - path-to-regexp: ^8.0.0 - checksum: 4c3bec8011ed10bb07d1ee860bc715f245fff0fdff991d8319741d2932d89c3fe0a56766b4fa78e95444bc323fd2538e09c8e43bfbd442c2a7fab67456df7fa5 +"rsvp@npm:^4.8.4": + version: 4.8.5 + resolution: "rsvp@npm:4.8.5" + checksum: 2d8ef30d8febdf05bdf856ccca38001ae3647e41835ca196bc1225333f79b94ae44def733121ca549ccc36209c9b689f6586905e2a043873262609744da8efc1 + languageName: node + linkType: hard + +"run-async@npm:^2.4.0": + version: 2.4.1 + resolution: "run-async@npm:2.4.1" + checksum: a2c88aa15df176f091a2878eb840e68d0bdee319d8d97bbb89112223259cebecb94bc0defd735662b83c2f7a30bed8cddb7d1674eb48ae7322dc602b22d03797 languageName: node linkType: hard @@ -18846,60 +17626,76 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:7.8.2": - version: 7.8.2 - resolution: "rxjs@npm:7.8.2" +"run-queue@npm:^1.0.0, run-queue@npm:^1.0.3": + version: 1.0.3 + resolution: "run-queue@npm:1.0.3" dependencies: - tslib: ^2.1.0 - checksum: 2f233d7c832a6c255dabe0759014d7d9b1c9f1cb2f2f0d59690fd11c883c9826ea35a51740c06ab45b6ade0d9087bde9192f165cba20b6730d344b831ef80744 + aproba: ^1.1.1 + checksum: c4541e18b5e056af60f398f2f1b3d89aae5c093d1524bf817c5ee68bcfa4851ad9976f457a9aea135b1d0d72ee9a91c386e3d136bcd95b699c367cd09c70be53 languageName: node linkType: hard -"safe-array-concat@npm:^1.1.2, safe-array-concat@npm:^1.1.3": - version: 1.1.3 - resolution: "safe-array-concat@npm:1.1.3" +"rxjs@npm:^6.5.2": + version: 6.6.7 + resolution: "rxjs@npm:6.6.7" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.2 - get-intrinsic: ^1.2.6 - has-symbols: ^1.1.0 - isarray: ^2.0.5 - checksum: 00f6a68140e67e813f3ad5e73e6dedcf3e42a9fa01f04d44b0d3f7b1f4b257af876832a9bfc82ac76f307e8a6cc652e3cf95876048a26cbec451847cf6ae3707 + tslib: ^1.9.0 + checksum: bc334edef1bb8bbf56590b0b25734ba0deaf8825b703256a93714308ea36dff8a11d25533671adf8e104e5e8f256aa6fdfe39b2e248cdbd7a5f90c260acbbd1b languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 +"rxjs@npm:^7.5.5": + version: 7.8.1 + resolution: "rxjs@npm:7.8.1" + dependencies: + tslib: ^2.1.0 + checksum: de4b53db1063e618ec2eca0f7965d9137cabe98cf6be9272efe6c86b47c17b987383df8574861bcced18ebd590764125a901d5506082be84a8b8e364bf05f119 + languageName: node + linkType: hard + +"safe-array-concat@npm:^1.1.2": + version: 1.1.2 + resolution: "safe-array-concat@npm:1.1.2" + dependencies: + call-bind: ^1.0.7 + get-intrinsic: ^1.2.4 + has-symbols: ^1.0.3 + isarray: ^2.0.5 + checksum: a3b259694754ddfb73ae0663829e396977b99ff21cbe8607f35a469655656da8e271753497e59da8a7575baa94d2e684bea3e10ddd74ba046c0c9b4418ffa0c4 languageName: node linkType: hard -"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": +"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c languageName: node linkType: hard -"safe-push-apply@npm:^1.0.0": - version: 1.0.0 - resolution: "safe-push-apply@npm:1.0.0" +"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 + languageName: node + linkType: hard + +"safe-regex-test@npm:^1.0.3": + version: 1.0.3 + resolution: "safe-regex-test@npm:1.0.3" dependencies: + call-bind: ^1.0.6 es-errors: ^1.3.0 - isarray: ^2.0.5 - checksum: 8c11cbee6dc8ff5cc0f3d95eef7052e43494591384015902e4292aef4ae9e539908288520ed97179cee17d6ffb450fe5f05a46ce7a1749685f7524fd568ab5db + is-regex: ^1.1.4 + checksum: 6c7d392ff1ae7a3ae85273450ed02d1d131f1d2c76e177d6b03eb88e6df8fa062639070e7d311802c1615f351f18dc58f9454501c58e28d5ffd9b8f502ba6489 languageName: node linkType: hard -"safe-regex-test@npm:^1.0.3, safe-regex-test@npm:^1.1.0": +"safe-regex@npm:^1.1.0": version: 1.1.0 - resolution: "safe-regex-test@npm:1.1.0" + resolution: "safe-regex@npm:1.1.0" dependencies: - call-bound: ^1.0.2 - es-errors: ^1.3.0 - is-regex: ^1.2.1 - checksum: 3c809abeb81977c9ed6c869c83aca6873ea0f3ab0f806b8edbba5582d51713f8a6e9757d24d2b4b088f563801475ea946c8e77e7713e8c65cdd02305b6caedab + ret: ~0.1.10 + checksum: 9a8bba57c87a841f7997b3b951e8e403b1128c1a4fd1182f40cc1a20e2d490593d7c2a21030fadfea320c8e859219019e136f678c6689ed5960b391b822f01d5 languageName: node linkType: hard @@ -18910,25 +17706,46 @@ __metadata: languageName: node linkType: hard -"sanitize.css@npm:*": - version: 13.0.0 - resolution: "sanitize.css@npm:13.0.0" - checksum: a99ca77c4d135800a4a93c3555e5aa4a2eb040a833df716dbe9132e1f2086fbf9acdb8021a579f40dcf77166d2d50f3358b4b6121a247d26fed5a0e6f5af3bb7 +"sane@npm:^4.0.3": + version: 4.1.0 + resolution: "sane@npm:4.1.0" + dependencies: + "@cnakazawa/watch": ^1.0.3 + anymatch: ^2.0.0 + capture-exit: ^2.0.0 + exec-sh: ^0.3.2 + execa: ^1.0.0 + fb-watchman: ^2.0.0 + micromatch: ^3.1.4 + minimist: ^1.1.1 + walker: ~1.0.5 + bin: + sane: ./src/cli.js + checksum: 97716502d456c0d38670a902a4ea943d196dcdf998d1e40532d8f3e24e25d7eddfd4c3579025a1eee8eac09a48dfd05fba61a2156c56704e7feaa450eb249f7c + languageName: node + linkType: hard + +"sanitize.css@npm:^10.0.0": + version: 10.0.0 + resolution: "sanitize.css@npm:10.0.0" + checksum: 99932e53e864b83562a421f57383c9747ab03c51872437eb56170639cd6c634a945517e25d1b7005d10c8dc863f71c61c573e3452474d4ef25bcf5f7344e4ce3 languageName: node linkType: hard -"sass-loader@npm:^12.3.0": - version: 12.6.0 - resolution: "sass-loader@npm:12.6.0" +"sass-loader@npm:^10.0.5": + version: 10.5.2 + resolution: "sass-loader@npm:10.5.2" dependencies: klona: ^2.0.4 + loader-utils: ^2.0.0 neo-async: ^2.6.2 + schema-utils: ^3.0.0 + semver: ^7.3.2 peerDependencies: fibers: ">= 3.1.0" - node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + 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 + webpack: ^4.36.0 || ^5.0.0 peerDependenciesMeta: fibers: optional: true @@ -18936,26 +17753,20 @@ __metadata: optional: true sass: optional: true - sass-embedded: - optional: true - checksum: 5d73a428588150f704016aa27397941bb9246cecd2ee083b573e95d969fc080ac6a16f2fe1cc64aca08f6e70da6f3c586ee68f0efc9f527fecc360e5f1c299ec + checksum: 416909a9d685aafeb4342d91575439b293f4e1d6fdf7f8f970e4b3158af38e3e7379b87c0a82d7b7b32165b1f54bcd7eca3c132ad143405a5105ea4ba79cdac2 languageName: node linkType: hard "sass@npm:^1.54.0": - version: 1.92.1 - resolution: "sass@npm:1.92.1" + version: 1.75.0 + resolution: "sass@npm:1.75.0" dependencies: - "@parcel/watcher": ^2.4.1 - chokidar: ^4.0.0 - immutable: ^5.0.2 + chokidar: ">=3.0.0 <4.0.0" + immutable: ^4.0.0 source-map-js: ">=0.6.2 <2.0.0" - dependenciesMeta: - "@parcel/watcher": - optional: true bin: sass: sass.js - checksum: ec0d4da639874f0f849b766f51f3db1fdff703840e7066ca3dd097999179630707b357744d83dde54289c02bba2f1ef8b34bba460cf4f703874b7922a86e32df + checksum: bfb9f5ddb6a2e1fe0c1ba6191cdb17afa7b40c1eb892c7152f6a29ff2b06dc7a510bdb648f8cca0179dcb3965920ebeb8894f0710b0b450a99db563831345033 languageName: node linkType: hard @@ -18975,25 +17786,27 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.25.0": - version: 0.25.0 - resolution: "scheduler@npm:0.25.0" - checksum: b7bb9fddbf743e521e9aaa5198a03ae823f5e104ebee0cb9ec625392bb7da0baa1c28ab29cee4b1e407a94e76acc6eee91eeb749614f91f853efda2613531566 +"scheduler@npm:^0.23.0": + version: 0.23.0 + resolution: "scheduler@npm:0.23.0" + dependencies: + loose-envify: ^1.1.0 + checksum: d79192eeaa12abef860c195ea45d37cbf2bbf5f66e3c4dcd16f54a7da53b17788a70d109ee3d3dde1a0fd50e6a8fc171f4300356c5aee4fc0171de526bf35f8a languageName: node linkType: hard -"schema-utils@npm:2.7.0": - version: 2.7.0 - resolution: "schema-utils@npm:2.7.0" +"schema-utils@npm:^1.0.0": + version: 1.0.0 + resolution: "schema-utils@npm:1.0.0" dependencies: - "@types/json-schema": ^7.0.4 - ajv: ^6.12.2 - ajv-keywords: ^3.4.1 - checksum: 8889325b0ee1ae6a8f5d6aaa855c71e136ebbb7fd731b01a9d3ec8225dcb245f644c47c50104db4c741983b528cdff8558570021257d4d397ec6aaecd9172a8e + ajv: ^6.1.0 + ajv-errors: ^1.0.0 + ajv-keywords: ^3.1.0 + checksum: e8273b4f6eff9ddf4a4f4c11daf7b96b900237bf8859c86fa1e9b4fab416b72d7ea92468f8db89c18a3499a1070206e1c8a750c83b42d5325fc659cbb55eee88 languageName: node linkType: hard -"schema-utils@npm:^2.6.5": +"schema-utils@npm:^2.6.5, schema-utils@npm:^2.7.0, schema-utils@npm:^2.7.1": version: 2.7.1 resolution: "schema-utils@npm:2.7.1" dependencies: @@ -19004,7 +17817,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.0.0": +"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1": version: 3.3.0 resolution: "schema-utils@npm:3.3.0" dependencies: @@ -19015,18 +17828,6 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.2": - version: 4.3.2 - resolution: "schema-utils@npm:4.3.2" - dependencies: - "@types/json-schema": ^7.0.9 - ajv: ^8.9.0 - ajv-formats: ^2.1.1 - ajv-keywords: ^5.1.0 - checksum: d798b341ffa1371f8471629e8861af3aa99e8e15b89da2c0db28c5a80a02ee8c6ffc7daefbe28a2b8c1bc8e3f3e02d028775145d7ab3d9d1a413a9651a835466 - languageName: node - linkType: hard - "select-hose@npm:^2.0.0": version: 2.0.0 resolution: "select-hose@npm:2.0.0" @@ -19034,22 +17835,41 @@ __metadata: languageName: node linkType: hard -"selfsigned@npm:^2.1.1": - version: 2.4.1 - resolution: "selfsigned@npm:2.4.1" +"selfsigned@npm:^1.10.8": + version: 1.10.14 + resolution: "selfsigned@npm:1.10.14" dependencies: - "@types/node-forge": ^1.3.0 - node-forge: ^1 - checksum: 38b91c56f1d7949c0b77f9bbe4545b19518475cae15e7d7f0043f87b1626710b011ce89879a88969651f650a19d213bb15b7d5b4c2877df9eeeff7ba8f8b9bfa + node-forge: ^0.10.0 + checksum: 616d131b18516ba2876398f0230987511d50a13816e0709b9f0d20246a524a2e83dfb27ea46ce2bfe331519583a156afa67bc3ece8bf0f9804aec06e2e8c7a21 languageName: node linkType: hard -"semver@npm:^5.6.0, semver@npm:^5.7.1": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.1": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: - semver: bin/semver - checksum: fb4ab5e0dd1c22ce0c937ea390b4a822147a9c53dbd2a9a0132f12fe382902beef4fbf12cf51bb955248d8d15874ce8cd89532569756384f994309825f10b686 + semver: bin/semver + checksum: fb4ab5e0dd1c22ce0c937ea390b4a822147a9c53dbd2a9a0132f12fe382902beef4fbf12cf51bb955248d8d15874ce8cd89532569756384f994309825f10b686 + languageName: node + linkType: hard + +"semver@npm:7.3.2": + version: 7.3.2 + resolution: "semver@npm:7.3.2" + bin: + semver: bin/semver.js + checksum: 692f4900dadb43919614b0df9af23fe05743051cda0d1735b5e4d76f93c9e43a266fae73cfc928f5d1489f022c5c0e65dfd2900fcf5b1839c4e9a239729afa7b + languageName: node + linkType: hard + +"semver@npm:7.x, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3": + version: 7.6.0 + resolution: "semver@npm:7.6.0" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 7427f05b70786c696640edc29fdd4bc33b2acf3bbe1740b955029044f80575fc664e1a512e4113c3af21e767154a94b4aa214bf6cd6e42a1f6dba5914e0b208c languageName: node linkType: hard @@ -19062,15 +17882,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": - version: 7.7.2 - resolution: "semver@npm:7.7.2" - bin: - semver: bin/semver.js - checksum: dd94ba8f1cbc903d8eeb4dd8bf19f46b3deb14262b6717d0de3c804b594058ae785ef2e4b46c5c3b58733c99c83339068203002f9e37cfe44f7e2cc5e3d2f621 - languageName: node - linkType: hard - "semver@npm:~7.0.0": version: 7.0.0 resolution: "semver@npm:7.0.0" @@ -19080,9 +17891,9 @@ __metadata: languageName: node linkType: hard -"send@npm:0.19.0": - version: 0.19.0 - resolution: "send@npm:0.19.0" +"send@npm:0.18.0": + version: 0.18.0 + resolution: "send@npm:0.18.0" dependencies: debug: 2.6.9 depd: 2.0.0 @@ -19097,26 +17908,7 @@ __metadata: on-finished: 2.4.1 range-parser: ~1.2.1 statuses: 2.0.1 - checksum: 5ae11bd900c1c2575525e2aa622e856804e2f96a09281ec1e39610d089f53aa69e13fd8db84b52f001d0318cf4bb0b3b904ad532fc4c0014eb90d32db0cff55f - languageName: node - linkType: hard - -"send@npm:^1.1.0, send@npm:^1.2.0": - version: 1.2.0 - resolution: "send@npm:1.2.0" - dependencies: - debug: ^4.3.5 - encodeurl: ^2.0.0 - escape-html: ^1.0.3 - etag: ^1.8.1 - fresh: ^2.0.0 - http-errors: ^2.0.0 - mime-types: ^3.0.1 - ms: ^2.1.3 - on-finished: ^2.4.1 - range-parser: ^1.2.1 - statuses: ^2.0.1 - checksum: 7557ee6c1c257a1c53b402b4fba8ed88c95800b08abe085fc79e0824869274f213491be2efb2df3de228c70e4d40ce2019e5f77b58c42adb97149135420c3f34 + checksum: 74fc07ebb58566b87b078ec63e5a3e41ecd987e4272ba67b7467e86c6ad51bc6b0b0154133b6d8b08a2ddda360464f71382f7ef864700f34844a76c8027817a8 languageName: node linkType: hard @@ -19140,12 +17932,12 @@ __metadata: languageName: node linkType: hard -"serialize-javascript@npm:^6.0.0, serialize-javascript@npm:^6.0.2": - version: 6.0.2 - resolution: "serialize-javascript@npm:6.0.2" +"serialize-javascript@npm:^5.0.1": + version: 5.0.1 + resolution: "serialize-javascript@npm:5.0.1" dependencies: randombytes: ^2.1.0 - checksum: c4839c6206c1d143c0f80763997a361310305751171dd95e4b57efee69b8f6edd8960a0b7fbfc45042aadff98b206d55428aee0dc276efe54f100899c7fa8ab7 + checksum: bb45a427690c3d2711e28499de0fbf25036af1e23c63c6a9237ed0aa572fd0941fcdefe50a2dccf26d9df8c8b86ae38659e19d8ba7afd3fbc1f1c7539a2a48d2 languageName: node linkType: hard @@ -19164,27 +17956,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.16.2": - version: 1.16.2 - resolution: "serve-static@npm:1.16.2" +"serve-static@npm:1.15.0": + version: 1.15.0 + resolution: "serve-static@npm:1.15.0" dependencies: - encodeurl: ~2.0.0 + encodeurl: ~1.0.2 escape-html: ~1.0.3 parseurl: ~1.3.3 - send: 0.19.0 - checksum: dffc52feb4cc5c68e66d0c7f3c1824d4e989f71050aefc9bd5f822a42c54c9b814f595fc5f2b717f4c7cc05396145f3e90422af31186a93f76cf15f707019759 - languageName: node - linkType: hard - -"serve-static@npm:^2.2.0": - version: 2.2.0 - resolution: "serve-static@npm:2.2.0" - dependencies: - encodeurl: ^2.0.0 - escape-html: ^1.0.3 - parseurl: ^1.3.3 - send: ^1.2.0 - checksum: 74f39e88f0444aa6732aae3b9597739c47552adecdc83fa32aa42555e76f1daad480d791af73894655c27a2d378275a461e691cead33fb35d8b976f1e2d24665 + send: 0.18.0 + checksum: af57fc13be40d90a12562e98c0b7855cf6e8bd4c107fe9a45c212bf023058d54a1871b1c89511c3958f70626fff47faeb795f5d83f8cf88514dbaeb2b724464d languageName: node linkType: hard @@ -19195,7 +17975,14 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.2.2": +"set-cookie-parser@npm:^2.4.6": + version: 2.6.0 + resolution: "set-cookie-parser@npm:2.6.0" + checksum: bf11ebc594c53d84588f1b4c04f1b8ce14e0498b1c011b3d76b5c6d5aac481bbc3f7c5260ec4ce99bdc1d9aed19f9fc315e73166a36ca74d0f12349a73f6bdc9 + languageName: node + linkType: hard + +"set-function-length@npm:^1.2.1": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" dependencies: @@ -19209,7 +17996,7 @@ __metadata: languageName: node linkType: hard -"set-function-name@npm:^2.0.2": +"set-function-name@npm:^2.0.1, set-function-name@npm:^2.0.2": version: 2.0.2 resolution: "set-function-name@npm:2.0.2" dependencies: @@ -19221,14 +18008,22 @@ __metadata: languageName: node linkType: hard -"set-proto@npm:^1.0.0": - version: 1.0.0 - resolution: "set-proto@npm:1.0.0" +"set-value@npm:^2.0.0, set-value@npm:^2.0.1": + version: 2.0.1 + resolution: "set-value@npm:2.0.1" dependencies: - dunder-proto: ^1.0.1 - es-errors: ^1.3.0 - es-object-atoms: ^1.0.0 - checksum: ec27cbbe334598547e99024403e96da32aca3e530583e4dba7f5db1c43cbc4affa9adfbd77c7b2c210b9b8b2e7b2e600bad2a6c44fd62e804d8233f96bbb62f4 + extend-shallow: ^2.0.1 + is-extendable: ^0.1.1 + is-plain-object: ^2.0.3 + split-string: ^3.0.1 + checksum: 09a4bc72c94641aeae950eb60dc2755943b863780fcc32e441eda964b64df5e3f50603d5ebdd33394ede722528bd55ed43aae26e9df469b4d32e2292b427b601 + languageName: node + linkType: hard + +"setimmediate@npm:^1.0.4": + version: 1.0.5 + resolution: "setimmediate@npm:1.0.5" + checksum: c9a6f2c5b51a2dabdc0247db9c46460152ffc62ee139f3157440bd48e7c59425093f42719ac1d7931f054f153e2d26cf37dfeb8da17a794a58198a2705e527fd languageName: node linkType: hard @@ -19246,6 +18041,18 @@ __metadata: languageName: node linkType: hard +"sha.js@npm:^2.4.0, sha.js@npm:^2.4.8": + version: 2.4.11 + resolution: "sha.js@npm:2.4.11" + dependencies: + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + bin: + sha.js: ./bin.js + checksum: ebd3f59d4b799000699097dadb831c8e3da3eb579144fd7eb7a19484cbcbb7aca3c68ba2bb362242eb09e33217de3b4ea56e4678184c334323eca24a58e3ad07 + languageName: node + linkType: hard + "shared@1.0.0, shared@workspace:src/shared": version: 0.0.0-use.local resolution: "shared@workspace:src/shared" @@ -19256,6 +18063,15 @@ __metadata: languageName: unknown linkType: soft +"shebang-command@npm:^1.2.0": + version: 1.2.0 + resolution: "shebang-command@npm:1.2.0" + dependencies: + shebang-regex: ^1.0.0 + checksum: 9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -19265,6 +18081,13 @@ __metadata: languageName: node linkType: hard +"shebang-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "shebang-regex@npm:1.0.0" + checksum: 404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 + languageName: node + linkType: hard + "shebang-regex@npm:^3.0.0": version: 3.0.0 resolution: "shebang-regex@npm:3.0.0" @@ -19272,58 +18095,29 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:1.8.3, shell-quote@npm:^1.7.3, shell-quote@npm:^1.8.3": - version: 1.8.3 - resolution: "shell-quote@npm:1.8.3" - checksum: 550dd84e677f8915eb013d43689c80bb114860649ec5298eb978f40b8f3d4bc4ccb072b82c094eb3548dc587144bb3965a8676f0d685c1cf4c40b5dc27166242 - languageName: node - linkType: hard - -"side-channel-list@npm:^1.0.0": - version: 1.0.0 - resolution: "side-channel-list@npm:1.0.0" - dependencies: - es-errors: ^1.3.0 - object-inspect: ^1.13.3 - checksum: 603b928997abd21c5a5f02ae6b9cc36b72e3176ad6827fab0417ead74580cc4fb4d5c7d0a8a2ff4ead34d0f9e35701ed7a41853dac8a6d1a664fcce1a044f86f - languageName: node - linkType: hard - -"side-channel-map@npm:^1.0.1": - version: 1.0.1 - resolution: "side-channel-map@npm:1.0.1" - dependencies: - call-bound: ^1.0.2 - es-errors: ^1.3.0 - get-intrinsic: ^1.2.5 - object-inspect: ^1.13.3 - checksum: 42501371cdf71f4ccbbc9c9e2eb00aaaab80a4c1c429d5e8da713fd4d39ef3b8d4a4b37ed4f275798a65260a551a7131fd87fe67e922dba4ac18586d6aab8b06 +"shell-quote@npm:1.7.2": + version: 1.7.2 + resolution: "shell-quote@npm:1.7.2" + checksum: efad426fb25d8a54d06363f1f45774aa9e195f62f14fa696d542b44bfe418ab41206448b63af18d726c62e099e66d9a3f4f44858b9ea2ce4b794b41b802672d1 languageName: node linkType: hard -"side-channel-weakmap@npm:^1.0.2": - version: 1.0.2 - resolution: "side-channel-weakmap@npm:1.0.2" - dependencies: - call-bound: ^1.0.2 - es-errors: ^1.3.0 - get-intrinsic: ^1.2.5 - object-inspect: ^1.13.3 - side-channel-map: ^1.0.1 - checksum: a815c89bc78c5723c714ea1a77c938377ea710af20d4fb886d362b0d1f8ac73a17816a5f6640f354017d7e292a43da9c5e876c22145bac00b76cfb3468001736 +"shellwords@npm:^0.1.1": + version: 0.1.1 + resolution: "shellwords@npm:0.1.1" + checksum: 8d73a5e9861f5e5f1068e2cfc39bc0002400fe58558ab5e5fa75630d2c3adf44ca1fac81957609c8320d5533e093802fcafc72904bf1a32b95de3c19a0b1c0d4 languageName: node linkType: hard -"side-channel@npm:^1.0.6, side-channel@npm:^1.1.0": - version: 1.1.0 - resolution: "side-channel@npm:1.1.0" +"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" dependencies: + call-bind: ^1.0.7 es-errors: ^1.3.0 - object-inspect: ^1.13.3 - side-channel-list: ^1.0.0 - side-channel-map: ^1.0.1 - side-channel-weakmap: ^1.0.2 - checksum: bf73d6d6682034603eb8e99c63b50155017ed78a522d27c2acec0388a792c3ede3238b878b953a08157093b85d05797217d270b7666ba1f111345fbe933380ff + get-intrinsic: ^1.2.4 + object-inspect: ^1.13.1 + checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97 languageName: node linkType: hard @@ -19334,35 +18128,26 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 languageName: node linkType: hard -"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": +"signal-exit@npm:^4.0.1": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" checksum: 64c757b498cb8629ffa5f75485340594d2f8189e9b08700e69199069c8e3070fb3e255f7ab873c05dc0b3cec412aea7402e10a5990cb6a050bd33ba062a6c549 languageName: node linkType: hard -"simple-concat@npm:^1.0.0": - version: 1.0.1 - resolution: "simple-concat@npm:1.0.1" - checksum: 4d211042cc3d73a718c21ac6c4e7d7a0363e184be6a5ad25c8a1502e49df6d0a0253979e3d50dbdd3f60ef6c6c58d756b5d66ac1e05cda9cacd2e9fc59e3876a - languageName: node - linkType: hard - -"simple-get@npm:^4.0.0": - version: 4.0.1 - resolution: "simple-get@npm:4.0.1" +"simple-swizzle@npm:^0.2.2": + version: 0.2.2 + resolution: "simple-swizzle@npm:0.2.2" dependencies: - decompress-response: ^6.0.0 - once: ^1.3.1 - simple-concat: ^1.0.0 - checksum: e4132fd27cf7af230d853fa45c1b8ce900cb430dd0a3c6d3829649fe4f2b26574c803698076c4006450efb0fad2ba8c5455fbb5755d4b0a5ec42d4f12b31d27e + is-arrayish: ^0.3.1 + checksum: a7f3f2ab5c76c4472d5c578df892e857323e452d9f392e1b5cf74b74db66e6294a1e1b8b390b519fa1b96b5b613f2a37db6cffef52c3f1f8f3c5ea64eb2d54c0 languageName: node linkType: hard @@ -19389,13 +18174,6 @@ __metadata: languageName: node linkType: hard -"slash@npm:^4.0.0": - version: 4.0.0 - resolution: "slash@npm:4.0.0" - checksum: da8e4af73712253acd21b7853b7e0dbba776b786e82b010a5bfc8b5051a1db38ed8aba8e1e8f400dd2c9f373be91eb1c42b66e91abb407ff42b10feece5e1d2d - languageName: node - linkType: hard - "slice-ansi@npm:^4.0.0": version: 4.0.0 resolution: "slice-ansi@npm:4.0.0" @@ -19424,7 +18202,56 @@ __metadata: languageName: node linkType: hard -"sockjs@npm:^0.3.24": +"snapdragon-node@npm:^2.0.1": + version: 2.1.1 + resolution: "snapdragon-node@npm:2.1.1" + dependencies: + define-property: ^1.0.0 + isobject: ^3.0.0 + snapdragon-util: ^3.0.1 + checksum: 9bb57d759f9e2a27935dbab0e4a790137adebace832b393e350a8bf5db461ee9206bb642d4fe47568ee0b44080479c8b4a9ad0ebe3712422d77edf9992a672fd + languageName: node + linkType: hard + +"snapdragon-util@npm:^3.0.1": + version: 3.0.1 + resolution: "snapdragon-util@npm:3.0.1" + dependencies: + kind-of: ^3.2.0 + checksum: 684997dbe37ec995c03fd3f412fba2b711fc34cb4010452b7eb668be72e8811a86a12938b511e8b19baf853b325178c56d8b78d655305e5cfb0bb8b21677e7b7 + languageName: node + linkType: hard + +"snapdragon@npm:^0.8.1": + version: 0.8.2 + resolution: "snapdragon@npm:0.8.2" + dependencies: + base: ^0.11.1 + debug: ^2.2.0 + define-property: ^0.2.5 + extend-shallow: ^2.0.1 + map-cache: ^0.2.2 + source-map: ^0.5.6 + source-map-resolve: ^0.5.0 + use: ^3.1.0 + checksum: a197f242a8f48b11036563065b2487e9b7068f50a20dd81d9161eca6af422174fc158b8beeadbe59ce5ef172aa5718143312b3aebaae551c124b7824387c8312 + languageName: node + linkType: hard + +"sockjs-client@npm:^1.5.0": + version: 1.6.1 + resolution: "sockjs-client@npm:1.6.1" + dependencies: + debug: ^3.2.7 + eventsource: ^2.0.2 + faye-websocket: ^0.11.4 + inherits: ^2.0.4 + url-parse: ^1.5.10 + checksum: c7623bbc9891f427c1670145550a1c9c2d5379719e174a791606ba4f12c7d92e4cfb9acec6c17f91fda45d910b23c308a1f9fbcad4916ce5db4e982b24079fc7 + languageName: node + linkType: hard + +"sockjs@npm:^0.3.21": version: 0.3.24 resolution: "sockjs@npm:0.3.24" dependencies: @@ -19436,54 +18263,63 @@ __metadata: linkType: hard "socks-proxy-agent@npm:^8.0.3": - version: 8.0.5 - resolution: "socks-proxy-agent@npm:8.0.5" + version: 8.0.3 + resolution: "socks-proxy-agent@npm:8.0.3" dependencies: - agent-base: ^7.1.2 + agent-base: ^7.1.1 debug: ^4.3.4 - socks: ^2.8.3 - checksum: b4fbcdb7ad2d6eec445926e255a1fb95c975db0020543fbac8dfa6c47aecc6b3b619b7fb9c60a3f82c9b2969912a5e7e174a056ae4d98cb5322f3524d6036e1d + socks: ^2.7.1 + checksum: 8fab38821c327c190c28f1658087bc520eb065d55bc07b4a0fdf8d1e0e7ad5d115abbb22a95f94f944723ea969dd771ad6416b1e3cde9060c4c71f705c8b85c5 languageName: node linkType: hard -"socks@npm:^2.8.3": - version: 2.8.7 - resolution: "socks@npm:2.8.7" +"socks@npm:^2.7.1": + version: 2.8.3 + resolution: "socks@npm:2.8.3" dependencies: - ip-address: ^10.0.1 + ip-address: ^9.0.5 smart-buffer: ^4.2.0 - checksum: 4bbe2c88cf0eeaf49f94b7f11564a99b2571bde6fd1e714ff95b38f89e1f97858c19e0ab0e6d39eb7f6a984fa67366825895383ed563fe59962a1d57a1d55318 + checksum: 7a6b7f6eedf7482b9e4597d9a20e09505824208006ea8f2c49b71657427f3c137ca2ae662089baa73e1971c62322d535d9d0cf1c9235cf6f55e315c18203eadd + languageName: node + linkType: hard + +"sort-keys@npm:^1.0.0": + version: 1.1.2 + resolution: "sort-keys@npm:1.1.2" + dependencies: + is-plain-obj: ^1.0.0 + checksum: 5963fd191a2a185a5ec86f06e47721e8e04713eda43bb04ae60d2a8afb21241553dd5bc9d863ed2bd7c3d541b609b0c8d0e58836b1a3eb6764c09c094bcc8b00 languageName: node linkType: hard -"source-list-map@npm:^2.0.0, source-list-map@npm:^2.0.1": +"source-list-map@npm:^2.0.0": version: 2.0.1 resolution: "source-list-map@npm:2.0.1" checksum: 806efc6f75e7cd31e4815e7a3aaf75a45c704871ea4075cb2eb49882c6fca28998f44fc5ac91adb6de03b2882ee6fb02f951fdc85e6a22b338c32bfe19557938 languageName: node linkType: hard -"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.1": - version: 1.2.1 - resolution: "source-map-js@npm:1.2.1" - checksum: 4eb0cd997cdf228bc253bcaff9340afeb706176e64868ecd20efbe6efea931465f43955612346d6b7318789e5265bdc419bc7669c1cebe3db0eb255f57efa76b +"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.2.0": + version: 1.2.0 + resolution: "source-map-js@npm:1.2.0" + checksum: 791a43306d9223792e84293b00458bf102a8946e7188f3db0e4e22d8d530b5f80a4ce468eb5ec0bf585443ad55ebbd630bf379c98db0b1f317fd902500217f97 languageName: node linkType: hard -"source-map-loader@npm:^3.0.0": - version: 3.0.2 - resolution: "source-map-loader@npm:3.0.2" +"source-map-resolve@npm:^0.5.0, source-map-resolve@npm:^0.5.2": + version: 0.5.3 + resolution: "source-map-resolve@npm:0.5.3" dependencies: - abab: ^2.0.5 - iconv-lite: ^0.6.3 - source-map-js: ^1.0.1 - peerDependencies: - webpack: ^5.0.0 - checksum: d5a4e2ab190c93ae5cba68c247fbaa9fd560333c91060602b634c399a8a4b3205b8c07714c3bcdb0a11c6cc5476c06256bd8e824e71fbbb7981e8fad5cba4a00 + atob: ^2.1.2 + decode-uri-component: ^0.2.0 + resolve-url: ^0.2.1 + source-map-url: ^0.4.0 + urix: ^0.1.0 + checksum: c73fa44ac00783f025f6ad9e038ab1a2e007cd6a6b86f47fe717c3d0765b4a08d264f6966f3bd7cd9dbcd69e4832783d5472e43247775b2a550d6f2155d24bae languageName: node linkType: hard -"source-map-support@npm:^0.5.17, source-map-support@npm:^0.5.6, source-map-support@npm:~0.5.20": +"source-map-support@npm:^0.5.17, source-map-support@npm:^0.5.6, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -19493,6 +18329,13 @@ __metadata: languageName: node linkType: hard +"source-map-url@npm:^0.4.0": + version: 0.4.1 + resolution: "source-map-url@npm:0.4.1" + checksum: 64c5c2c77aff815a6e61a4120c309ae4cac01298d9bcbb3deb1b46a4dd4c46d4a1eaeda79ec9f684766ae80e8dc86367b89326ce9dd2b89947bd9291fc1ac08c + languageName: node + linkType: hard + "source-map@npm:0.6.1, source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" @@ -19500,7 +18343,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.7": +"source-map@npm:^0.5.0, source-map@npm:^0.5.6, source-map@npm:^0.5.7": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 5dc2043b93d2f194142c7f38f74a24670cd7a0063acdaf4bf01d2964b402257ae843c2a8fa822ad5b71013b5fcafa55af7421383da919752f22ff488bc553f4d @@ -19508,18 +18351,9 @@ __metadata: linkType: hard "source-map@npm:^0.7.3": - version: 0.7.6 - resolution: "source-map@npm:0.7.6" - checksum: 932f4a2390aa7100e91357d88cc272de984ad29139ac09eedfde8cc78d46da35f389065d0c5343c5d71d054a6ebd4939a8c0f2c98d5df64fe97bb8a730596c2d - languageName: node - linkType: hard - -"source-map@npm:^0.8.0-beta.0": - version: 0.8.0-beta.0 - resolution: "source-map@npm:0.8.0-beta.0" - dependencies: - whatwg-url: ^7.0.0 - checksum: e94169be6461ab0ac0913313ad1719a14c60d402bd22b0ad96f4a6cffd79130d91ab5df0a5336a326b04d2df131c1409f563c9dc0d21a6ca6239a44b6c8dbd92 + version: 0.7.4 + resolution: "source-map@npm:0.7.4" + checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5 languageName: node linkType: hard @@ -19530,10 +18364,51 @@ __metadata: languageName: node linkType: hard -"space-separated-tokens@npm:^2.0.0": - version: 2.0.2 - resolution: "space-separated-tokens@npm:2.0.2" - checksum: 202e97d7ca1ba0758a0aa4fe226ff98142073bcceeff2da3aad037968878552c3bbce3b3231970025375bbba5aee00c5b8206eda408da837ab2dc9c0f26be990 +"space-separated-tokens@npm:^1.1.0": + version: 1.1.5 + resolution: "space-separated-tokens@npm:1.1.5" + checksum: 8ef68f1cfa8ccad316b7f8d0df0919d0f1f6d32101e8faeee34ea3a923ce8509c1ad562f57388585ee4951e92d27afa211ed0a077d3d5995b5ba9180331be708 + languageName: node + linkType: hard + +"spawn-command@npm:^0.0.2-1": + version: 0.0.2 + resolution: "spawn-command@npm:0.0.2" + checksum: e35c5d28177b4d461d33c88cc11f6f3a5079e2b132c11e1746453bbb7a0c0b8a634f07541a2a234fa4758239d88203b758def509161b651e81958894c0b4b64b + languageName: node + linkType: hard + +"spdx-correct@npm:^3.0.0": + version: 3.2.0 + resolution: "spdx-correct@npm:3.2.0" + dependencies: + spdx-expression-parse: ^3.0.0 + spdx-license-ids: ^3.0.0 + checksum: e9ae98d22f69c88e7aff5b8778dc01c361ef635580e82d29e5c60a6533cc8f4d820803e67d7432581af0cc4fb49973125076ee3b90df191d153e223c004193b2 + languageName: node + linkType: hard + +"spdx-exceptions@npm:^2.1.0": + version: 2.5.0 + resolution: "spdx-exceptions@npm:2.5.0" + checksum: bb127d6e2532de65b912f7c99fc66097cdea7d64c10d3ec9b5e96524dbbd7d20e01cba818a6ddb2ae75e62bb0c63d5e277a7e555a85cbc8ab40044984fa4ae15 + languageName: node + linkType: hard + +"spdx-expression-parse@npm:^3.0.0": + version: 3.0.1 + resolution: "spdx-expression-parse@npm:3.0.1" + dependencies: + spdx-exceptions: ^2.1.0 + spdx-license-ids: ^3.0.0 + checksum: a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde + languageName: node + linkType: hard + +"spdx-license-ids@npm:^3.0.0": + version: 3.0.17 + resolution: "spdx-license-ids@npm:3.0.17" + checksum: 0aba5d16292ff604dd20982200e23b4d425f6ba364765039bdbde2f6c956b9909fce1ad040a897916a5f87388e85e001f90cb64bf706b6e319f3908cfc445a59 languageName: node linkType: hard @@ -19564,6 +18439,22 @@ __metadata: languageName: node linkType: hard +"split-string@npm:^3.0.1, split-string@npm:^3.0.2": + version: 3.1.0 + resolution: "split-string@npm:3.1.0" + dependencies: + extend-shallow: ^3.0.0 + checksum: ae5af5c91bdc3633628821bde92fdf9492fa0e8a63cf6a0376ed6afde93c701422a1610916f59be61972717070119e848d10dfbbd5024b7729d6a71972d2a84c + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -19571,12 +18462,30 @@ __metadata: languageName: node linkType: hard -"ssri@npm:^12.0.0": - version: 12.0.0 - resolution: "ssri@npm:12.0.0" +"ssri@npm:^10.0.0": + version: 10.0.5 + resolution: "ssri@npm:10.0.5" dependencies: minipass: ^7.0.3 - checksum: ef4b6b0ae47b4a69896f5f1c4375f953b9435388c053c36d27998bc3d73e046969ccde61ab659e679142971a0b08e50478a1228f62edb994105b280f17900c98 + checksum: 0a31b65f21872dea1ed3f7c200d7bc1c1b91c15e419deca14f282508ba917cbb342c08a6814c7f68ca4ca4116dd1a85da2bbf39227480e50125a1ceffeecb750 + languageName: node + linkType: hard + +"ssri@npm:^6.0.1": + version: 6.0.2 + resolution: "ssri@npm:6.0.2" + dependencies: + figgy-pudding: ^3.5.1 + checksum: 7c2e5d442f6252559c8987b7114bcf389fe5614bf65de09ba3e6f9a57b9b65b2967de348fcc3acccff9c069adb168140dd2c5fc2f6f4a779e604a27ef1f7d551 + languageName: node + linkType: hard + +"ssri@npm:^8.0.1": + version: 8.0.1 + resolution: "ssri@npm:8.0.1" + dependencies: + minipass: ^3.1.1 + checksum: bc447f5af814fa9713aa201ec2522208ae0f4d8f3bda7a1f445a797c7b929a02720436ff7c478fb5edc4045adb02b1b88d2341b436a80798734e2494f1067b36 languageName: node linkType: hard @@ -19587,7 +18496,7 @@ __metadata: languageName: node linkType: hard -"stack-utils@npm:^2.0.3": +"stack-utils@npm:^2.0.2, stack-utils@npm:^2.0.3": version: 2.0.6 resolution: "stack-utils@npm:2.0.6" dependencies: @@ -19619,7 +18528,17 @@ __metadata: languageName: node linkType: hard -"statuses@npm:2.0.1": +"static-extend@npm:^0.1.1": + version: 0.1.2 + resolution: "static-extend@npm:0.1.2" + dependencies: + define-property: ^0.2.5 + object-copy: ^0.1.0 + checksum: 8657485b831f79e388a437260baf22784540417a9b29e11572c87735df24c22b84eda42107403a64b30861b2faf13df9f7fc5525d51f9d1d2303aba5cbf4e12c + languageName: node + linkType: hard + +"statuses@npm:2.0.1, statuses@npm:^2.0.0": version: 2.0.1 resolution: "statuses@npm:2.0.1" checksum: 18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb @@ -19633,27 +18552,59 @@ __metadata: languageName: node linkType: hard -"statuses@npm:^2.0.1": +"std-env@npm:^3.3.3": + version: 3.7.0 + resolution: "std-env@npm:3.7.0" + checksum: 4f489d13ff2ab838c9acd4ed6b786b51aa52ecacdfeaefe9275fcb220ff2ac80c6e95674723508fd29850a694569563a8caaaea738eb82ca16429b3a0b50e510 + languageName: node + linkType: hard + +"stop-iteration-iterator@npm:^1.0.0": + version: 1.0.0 + resolution: "stop-iteration-iterator@npm:1.0.0" + dependencies: + internal-slot: ^1.0.4 + checksum: d04173690b2efa40e24ab70e5e51a3ff31d56d699550cfad084104ab3381390daccb36652b25755e420245f3b0737de66c1879eaa2a8d4fc0a78f9bf892fcb42 + languageName: node + linkType: hard + +"stream-browserify@npm:^2.0.1": version: 2.0.2 - resolution: "statuses@npm:2.0.2" - checksum: 6927feb50c2a75b2a4caab2c565491f7a93ad3d8dbad7b1398d52359e9243a20e2ebe35e33726dee945125ef7a515e9097d8a1b910ba2bbd818265a2f6c39879 + resolution: "stream-browserify@npm:2.0.2" + dependencies: + inherits: ~2.0.1 + readable-stream: ^2.0.2 + checksum: 8de7bcab5582e9a931ae1a4768be7efe8fa4b0b95fd368d16d8cf3e494b897d6b0a7238626de5d71686e53bddf417fd59d106cfa3af0ec055f61a8d1f8fc77b3 languageName: node linkType: hard -"std-env@npm:^3.8.0, std-env@npm:^3.9.0": - version: 3.9.0 - resolution: "std-env@npm:3.9.0" - checksum: d40126e4a650f6e5456711e6c297420352a376ef99a9599e8224d2d8f2ff2b91a954f3264fcef888d94fce5c9ae14992c5569761c95556fc87248ce4602ed212 +"stream-each@npm:^1.1.0": + version: 1.2.3 + resolution: "stream-each@npm:1.2.3" + dependencies: + end-of-stream: ^1.1.0 + stream-shift: ^1.0.0 + checksum: f243de78e9fcc60757994efc4e8ecae9f01a4b2c6a505d786b11fcaa68b1a75ca54afc1669eac9e08f19ff0230792fc40d0f3e3e2935d76971b4903af18b76ab languageName: node linkType: hard -"stop-iteration-iterator@npm:^1.1.0": - version: 1.1.0 - resolution: "stop-iteration-iterator@npm:1.1.0" +"stream-http@npm:^2.7.2": + version: 2.8.3 + resolution: "stream-http@npm:2.8.3" dependencies: - es-errors: ^1.3.0 - internal-slot: ^1.1.0 - checksum: be944489d8829fb3bdec1a1cc4a2142c6b6eb317305eeace1ece978d286d6997778afa1ae8cb3bd70e2b274b9aa8c69f93febb1e15b94b1359b11058f9d3c3a1 + builtin-status-codes: ^3.0.0 + inherits: ^2.0.1 + readable-stream: ^2.3.6 + to-arraybuffer: ^1.0.0 + xtend: ^4.0.0 + checksum: f57dfaa21a015f72e6ce6b199cf1762074cfe8acf0047bba8f005593754f1743ad0a91788f95308d9f3829ad55742399ad27b4624432f2752a08e62ef4346e05 + languageName: node + linkType: hard + +"stream-shift@npm:^1.0.0": + version: 1.0.3 + resolution: "stream-shift@npm:1.0.3" + checksum: a24c0a3f66a8f9024bd1d579a533a53be283b4475d4e6b4b3211b964031447bdf6532dd1f3c2b0ad66752554391b7c62bd7ca4559193381f766534e723d50242 languageName: node linkType: hard @@ -19664,17 +18615,19 @@ __metadata: languageName: node linkType: hard -"strict-event-emitter@npm:^0.5.1": - version: 0.5.1 - resolution: "strict-event-emitter@npm:0.5.1" - checksum: 350480431bc1c28fdb601ef4976c2f8155fc364b4740f9692dd03e5bdd48aafc99a5e021fe655fbd986d0b803e9f3fc5c4b018b35cb838c4690d60f2a26f1cf3 +"strict-event-emitter@npm:^0.2.0, strict-event-emitter@npm:^0.2.4": + version: 0.2.8 + resolution: "strict-event-emitter@npm:0.2.8" + dependencies: + events: ^3.3.0 + checksum: 6ac06fe72a6ee6ae64d20f1dd42838ea67342f1b5f32b03b3050d73ee6ecee44b4d5c4ed2965a7154b47991e215f373d4e789e2b2be2769cd80e356126c2ca53 languageName: node linkType: hard -"string-hash@npm:^1.1.3": - version: 1.1.3 - resolution: "string-hash@npm:1.1.3" - checksum: 104b8667a5e0dc71bfcd29fee09cb88c6102e27bfb07c55f95535d90587d016731d52299380052e514266f4028a7a5172e0d9ac58e2f8f5001be61dc77c0754d +"strict-uri-encode@npm:^1.0.0": + version: 1.1.0 + resolution: "strict-uri-encode@npm:1.1.0" + checksum: 9466d371f7b36768d43f7803f26137657559e4c8b0161fb9e320efb8edba3ae22f8e99d4b0d91da023b05a13f62ec5412c3f4f764b5788fac11d1fea93720bb3 languageName: node linkType: hard @@ -19688,16 +18641,6 @@ __metadata: languageName: node linkType: hard -"string-length@npm:^5.0.1": - version: 5.0.1 - resolution: "string-length@npm:5.0.1" - dependencies: - char-regex: ^2.0.0 - strip-ansi: ^7.0.1 - checksum: 71f73b8c8a743e01dcd001bcf1b197db78d5e5e53b12bd898cddaf0961be09f947dfd8c429783db3694b55b05cb5a51de6406c5085ff1aaa10c4771440c8396d - languageName: node - linkType: hard - "string-natural-compare@npm:^3.0.1": version: 3.0.1 resolution: "string-natural-compare@npm:3.0.1" @@ -19716,6 +18659,17 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^3.0.0, string-width@npm:^3.1.0": + version: 3.1.0 + resolution: "string-width@npm:3.1.0" + dependencies: + emoji-regex: ^7.0.1 + is-fullwidth-code-point: ^2.0.0 + strip-ansi: ^5.1.0 + checksum: 57f7ca73d201682816d573dc68bd4bb8e1dff8dc9fcf10470fdfc3474135c97175fec12ea6a159e67339b41e86963112355b64529489af6e7e70f94a7caf08b2 + languageName: node + linkType: hard + "string-width@npm:^5.0.1, string-width@npm:^5.1.2": version: 5.1.2 resolution: "string-width@npm:5.1.2" @@ -19727,72 +18681,46 @@ __metadata: languageName: node linkType: hard -"string.prototype.includes@npm:^2.0.1": - version: 2.0.1 - resolution: "string.prototype.includes@npm:2.0.1" +"string.prototype.matchall@npm:^4.0.10": + version: 4.0.11 + resolution: "string.prototype.matchall@npm:4.0.11" dependencies: call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.23.3 - checksum: ed4b7058b092f30d41c4df1e3e805eeea92479d2c7a886aa30f42ae32fde8924a10cc99cccc99c29b8e18c48216608a0fe6bf887f8b4aadf9559096a758f313a - languageName: node - linkType: hard - -"string.prototype.matchall@npm:^4.0.12, string.prototype.matchall@npm:^4.0.6": - version: 4.0.12 - resolution: "string.prototype.matchall@npm:4.0.12" - dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.3 - define-properties: ^1.2.1 - es-abstract: ^1.23.6 + es-abstract: ^1.23.2 es-errors: ^1.3.0 es-object-atoms: ^1.0.0 - get-intrinsic: ^1.2.6 - gopd: ^1.2.0 - has-symbols: ^1.1.0 - internal-slot: ^1.1.0 - regexp.prototype.flags: ^1.5.3 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-symbols: ^1.0.3 + internal-slot: ^1.0.7 + regexp.prototype.flags: ^1.5.2 set-function-name: ^2.0.2 - side-channel: ^1.1.0 - checksum: 98a09d6af91bfc6ee25556f3d7cd6646d02f5f08bda55d45528ed273d266d55a71af7291fe3fc76854deffb9168cc1a917d0b07a7d5a178c7e9537c99e6d2b57 - languageName: node - linkType: hard - -"string.prototype.repeat@npm:^1.0.0": - version: 1.0.0 - resolution: "string.prototype.repeat@npm:1.0.0" - dependencies: - define-properties: ^1.1.3 - es-abstract: ^1.17.5 - checksum: 95dfc514ed7f328d80a066dabbfbbb1615c3e51490351085409db2eb7cbfed7ea29fdadaf277647fbf9f4a1e10e6dd9e95e78c0fd2c4e6bb6723ea6e59401004 + side-channel: ^1.0.6 + checksum: 6ac6566ed065c0c8489c91156078ca077db8ff64d683fda97ae652d00c52dfa5f39aaab0a710d8243031a857fd2c7c511e38b45524796764d25472d10d7075ae languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.10": - version: 1.2.10 - resolution: "string.prototype.trim@npm:1.2.10" +"string.prototype.trim@npm:^1.2.9": + version: 1.2.9 + resolution: "string.prototype.trim@npm:1.2.9" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.2 - define-data-property: ^1.1.4 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.23.5 + es-abstract: ^1.23.0 es-object-atoms: ^1.0.0 - has-property-descriptors: ^1.0.2 - checksum: 87659cd8561237b6c69f5376328fda934693aedde17bb7a2c57008e9d9ff992d0c253a391c7d8d50114e0e49ff7daf86a362f7961cf92f7564cd01342ca2e385 + checksum: ea2df6ec1e914c9d4e2dc856fa08228e8b1be59b59e50b17578c94a66a176888f417264bb763d4aac638ad3b3dad56e7a03d9317086a178078d131aa293ba193 languageName: node linkType: hard -"string.prototype.trimend@npm:^1.0.9": - version: 1.0.9 - resolution: "string.prototype.trimend@npm:1.0.9" +"string.prototype.trimend@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimend@npm:1.0.8" dependencies: - call-bind: ^1.0.8 - call-bound: ^1.0.2 + call-bind: ^1.0.7 define-properties: ^1.2.1 es-object-atoms: ^1.0.0 - checksum: cb86f639f41d791a43627784be2175daa9ca3259c7cb83e7a207a729909b74f2ea0ec5d85de5761e6835e5f443e9420c6ff3f63a845378e4a61dd793177bc287 + checksum: cc3bd2de08d8968a28787deba9a3cb3f17ca5f9f770c91e7e8fa3e7d47f079bad70fadce16f05dda9f261788be2c6e84a942f618c3bed31e42abc5c1084f8dfd languageName: node linkType: hard @@ -19807,7 +18735,7 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:^1.1.1": +"string_decoder@npm:^1.0.0, string_decoder@npm:^1.1.1": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" dependencies: @@ -19825,42 +18753,59 @@ __metadata: languageName: node linkType: hard -"stringify-entities@npm:^4.0.0": - version: 4.0.4 - resolution: "stringify-entities@npm:4.0.4" +"stringify-object@npm:^3.3.0": + version: 3.3.0 + resolution: "stringify-object@npm:3.3.0" dependencies: - character-entities-html4: ^2.0.0 - character-entities-legacy: ^3.0.0 - checksum: ac1344ef211eacf6cf0a0a8feaf96f9c36083835b406560d2c6ff5a87406a41b13f2f0b4c570a3b391f465121c4fd6822b863ffb197e8c0601a64097862cc5b5 + get-own-enumerable-property-symbols: ^3.0.0 + is-obj: ^1.0.1 + is-regexp: ^1.0.0 + checksum: 6827a3f35975cfa8572e8cd3ed4f7b262def260af18655c6fde549334acdac49ddba69f3c861ea5a6e9c5a4990fe4ae870b9c0e6c31019430504c94a83b7a154 languageName: node linkType: hard -"stringify-object@npm:^3.3.0": - version: 3.3.0 - resolution: "stringify-object@npm:3.3.0" +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: ^5.0.1 + checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c + languageName: node + linkType: hard + +"strip-ansi@npm:6.0.0": + version: 6.0.0 + resolution: "strip-ansi@npm:6.0.0" + dependencies: + ansi-regex: ^5.0.0 + checksum: 04c3239ede44c4d195b0e66c0ad58b932f08bec7d05290416d361ff908ad282ecdaf5d9731e322c84f151d427436bde01f05b7422c3ec26dd927586736b0e5d0 + languageName: node + linkType: hard + +"strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1": + version: 3.0.1 + resolution: "strip-ansi@npm:3.0.1" dependencies: - get-own-enumerable-property-symbols: ^3.0.0 - is-obj: ^1.0.1 - is-regexp: ^1.0.0 - checksum: 6827a3f35975cfa8572e8cd3ed4f7b262def260af18655c6fde549334acdac49ddba69f3c861ea5a6e9c5a4990fe4ae870b9c0e6c31019430504c94a83b7a154 + ansi-regex: ^2.0.0 + checksum: 9b974de611ce5075c70629c00fa98c46144043db92ae17748fb780f706f7a789e9989fd10597b7c2053ae8d1513fd707816a91f1879b2f71e6ac0b6a863db465 languageName: node linkType: hard -"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": - version: 6.0.1 - resolution: "strip-ansi@npm:6.0.1" +"strip-ansi@npm:^5.0.0, strip-ansi@npm:^5.1.0, strip-ansi@npm:^5.2.0": + version: 5.2.0 + resolution: "strip-ansi@npm:5.2.0" dependencies: - ansi-regex: ^5.0.1 - checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c + ansi-regex: ^4.1.0 + checksum: bdb5f76ade97062bd88e7723aa019adbfacdcba42223b19ccb528ffb9fb0b89a5be442c663c4a3fb25268eaa3f6ea19c7c3fbae830bd1562d55adccae1fcec46 languageName: node linkType: hard "strip-ansi@npm:^7.0.1": - version: 7.1.2 - resolution: "strip-ansi@npm:7.1.2" + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" dependencies: ansi-regex: ^6.0.1 - checksum: db0e3f9654e519c8a33c50fc9304d07df5649388e7da06d3aabf66d29e5ad65d5e6315d8519d409c15b32fa82c1df7e11ed6f8cd50b0e4404463f0c9d77c8d0b + checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d languageName: node linkType: hard @@ -19878,10 +18823,20 @@ __metadata: languageName: node linkType: hard -"strip-comments@npm:^2.0.1": - version: 2.0.1 - resolution: "strip-comments@npm:2.0.1" - checksum: 36cd122e1c27b5be69df87e1687770a62fe183bdee9f3ff5cf85d30bbc98280afc012581f2fd50c7ad077c90f656f272560c9d2e520d28604b8b7ea3bc87d6f9 +"strip-comments@npm:^1.0.2": + version: 1.0.2 + resolution: "strip-comments@npm:1.0.2" + dependencies: + babel-extract-comments: ^1.0.0 + babel-plugin-transform-object-rest-spread: ^6.26.0 + checksum: 19e6f659a617566aef011b29ef9ce50da0db24556073d9c8065c73072f89bf1238d1fcaaa485933fee038a50a09bb04493097f66e622cdfc3a114f5e9e99ee24 + languageName: node + linkType: hard + +"strip-eof@npm:^1.0.0": + version: 1.0.0 + resolution: "strip-eof@npm:1.0.0" + checksum: 40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 languageName: node linkType: hard @@ -19908,65 +18863,44 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:~2.0.1": - version: 2.0.1 - resolution: "strip-json-comments@npm:2.0.1" - checksum: 1074ccb63270d32ca28edfb0a281c96b94dc679077828135141f27d52a5a398ef5e78bcf22809d23cadc2b81dfbe345eb5fd8699b385c8b1128907dec4a7d1e1 - languageName: node - linkType: hard - -"strip-literal@npm:^3.0.0": - version: 3.0.0 - resolution: "strip-literal@npm:3.0.0" +"strip-literal@npm:^1.0.1": + version: 1.3.0 + resolution: "strip-literal@npm:1.3.0" dependencies: - js-tokens: ^9.0.1 - checksum: f697a31c4ad82ad259e0c57e715cde4585084af2260e38b3c916f34f0d462cec2af294a8b8cf062cc6f40d940ece7b79b0ec8316beabb2ed13c6e13e95ca70f0 - languageName: node - linkType: hard - -"strnum@npm:^2.1.0": - version: 2.1.1 - resolution: "strnum@npm:2.1.1" - checksum: 566139b218ef13bdde2a69c744852ac41ea167588f624d46c3b3bebb5d1d1775c55bca4702a0ad2a6a66eb4b3b7de4cbbc83e8d40c5835feabebf6f9cc468993 - languageName: node - linkType: hard - -"style-loader@npm:^3.3.1": - version: 3.3.4 - resolution: "style-loader@npm:3.3.4" - peerDependencies: - webpack: ^5.0.0 - checksum: caac3f2fe2c3c89e49b7a2a9329e1cfa515ecf5f36b9c4885f9b218019fda207a9029939b2c35821dec177a264a007e7c391ccdd3ff7401881ce6287b9c8f38b + acorn: ^8.10.0 + checksum: f5fa7e289df8ebe82e90091fd393974faf8871be087ca50114327506519323cf15f2f8fee6ebe68b5e58bfc795269cae8bdc7cb5a83e27b02b3fe953f37b0a89 languageName: node linkType: hard -"style-to-js@npm:^1.0.0": - version: 1.1.17 - resolution: "style-to-js@npm:1.1.17" +"style-loader@npm:1.3.0": + version: 1.3.0 + resolution: "style-loader@npm:1.3.0" dependencies: - style-to-object: 1.0.9 - checksum: cdf92a0a42383fcc535972b7ec73395b53e370e5eaa345faf4d360f7918789cd73a20a79eef6d764b6441ff2e532a42ad5830ab87fec60a9dfc177fa438a6876 + loader-utils: ^2.0.0 + schema-utils: ^2.7.0 + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + checksum: 1be9e8705307f5b8eb89e80f3703fa27296dccec349d790eace7aabe212f08c7c8f3ea6b6cb97bc53e82fbebfb9aa0689259671a8315f4655e24a850781e062a languageName: node linkType: hard -"style-to-object@npm:1.0.9": - version: 1.0.9 - resolution: "style-to-object@npm:1.0.9" +"style-to-object@npm:^0.3.0": + version: 0.3.0 + resolution: "style-to-object@npm:0.3.0" dependencies: - inline-style-parser: 0.2.4 - checksum: a89e229161a56c53e28d1b91dcdc902f482f577db8b13741d3f056df7df0fbff4ecb44e06e32960f11c3a477b26f056e889a223bef6bc72b162935c5e4828145 + inline-style-parser: 0.1.1 + checksum: 4d7084015207f2a606dfc10c29cb5ba569f2fe8005551df7396110dd694d6ff650f2debafa95bd5d147dfb4ca50f57868e2a7f91bf5d11ef734fe7ccbd7abf59 languageName: node linkType: hard -"stylehacks@npm:^5.1.1": - version: 5.1.1 - resolution: "stylehacks@npm:5.1.1" +"stylehacks@npm:^4.0.0": + version: 4.0.3 + resolution: "stylehacks@npm:4.0.3" dependencies: - browserslist: ^4.21.4 - postcss-selector-parser: ^6.0.4 - peerDependencies: - postcss: ^8.2.15 - checksum: 11175366ef52de65bf06cefba0ddc9db286dc3a1451fd2989e74c6ea47091a02329a4bf6ce10b1a36950056927b6bbbe47c5ab3a1f4c7032df932d010fbde5a2 + browserslist: ^4.0.0 + postcss: ^7.0.0 + postcss-selector-parser: ^3.0.0 + checksum: 8acf28ea609bee6d7ba40121bcf53af8d899c1ec04f2c08de9349b8292b84b8aa7f82e14c623ae6956decf5b7a7eeea5472ab8e48de7bdcdb6d76640444f6753 languageName: node linkType: hard @@ -19977,24 +18911,6 @@ __metadata: languageName: node linkType: hard -"sucrase@npm:^3.35.0": - version: 3.35.0 - resolution: "sucrase@npm:3.35.0" - 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 - checksum: 9fc5792a9ab8a14dcf9c47dcb704431d35c1cdff1d17d55d382a31c2e8e3063870ad32ce120a80915498486246d612e30cda44f1624d9d9a10423e1a43487ad1 - languageName: node - linkType: hard - "superagent@npm:^8.1.2": version: 8.1.2 resolution: "superagent@npm:8.1.2" @@ -20023,16 +18939,23 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:8.1.1, supports-color@npm:^8.0.0": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" +"supports-color@npm:^2.0.0": + version: 2.0.0 + resolution: "supports-color@npm:2.0.0" + checksum: 602538c5812b9006404370b5a4b885d3e2a1f6567d314f8b4a41974ffe7d08e525bf92ae0f9c7030e3b4c78e4e34ace55d6a67a74f1571bc205959f5972f88f0 + languageName: node + linkType: hard + +"supports-color@npm:^3.2.3": + version: 3.2.3 + resolution: "supports-color@npm:3.2.3" dependencies: - has-flag: ^4.0.0 - checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 + has-flag: ^1.0.0 + checksum: 56afc05fa87d00100d90148c4d0a6e20a0af0d56dca5c54d4d40b2553ee737dab0ca4e8b53c4471afc035227b5b44dfa4824747a7f01ad733173536f7da6fbbb languageName: node linkType: hard -"supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": +"supports-color@npm:^5.3.0, supports-color@npm:^5.4.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" dependencies: @@ -20041,6 +18964,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^6.1.0": + version: 6.1.0 + resolution: "supports-color@npm:6.1.0" + dependencies: + has-flag: ^3.0.0 + checksum: 74358f9535c83ee113fbaac354b11e808060f6e7d8722082ee43af3578469134e89d00026dce2a6b93ce4e5b89d0e9a10f638b2b9f64c7838c2fb2883a47b3d5 + languageName: node + linkType: hard + "supports-color@npm:^7.0.0, supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -20050,6 +18982,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^8.0.0": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: ^4.0.0 + checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 + languageName: node + linkType: hard + "supports-hyperlinks@npm:^2.0.0": version: 2.3.0 resolution: "supports-hyperlinks@npm:2.3.0" @@ -20074,7 +19015,7 @@ __metadata: languageName: node linkType: hard -"svgo@npm:^1.2.2": +"svgo@npm:^1.0.0, svgo@npm:^1.2.2": version: 1.3.2 resolution: "svgo@npm:1.3.2" dependencies: @@ -20097,23 +19038,6 @@ __metadata: languageName: node linkType: hard -"svgo@npm:^2.7.0": - version: 2.8.0 - resolution: "svgo@npm:2.8.0" - dependencies: - "@trysound/sax": 0.2.0 - commander: ^7.2.0 - css-select: ^4.1.3 - css-tree: ^1.1.3 - csso: ^4.2.0 - picocolors: ^1.0.0 - stable: ^0.1.8 - bin: - svgo: bin/svgo - checksum: b92f71a8541468ffd0b81b8cdb36b1e242eea320bf3c1a9b2c8809945853e9d8c80c19744267eb91cabf06ae9d5fff3592d677df85a31be4ed59ff78534fa420 - languageName: node - linkType: hard - "symbol-tree@npm:^3.2.4": version: 3.2.4 resolution: "symbol-tree@npm:3.2.4" @@ -20121,130 +19045,55 @@ __metadata: languageName: node linkType: hard -"synckit@npm:^0.11.7": - version: 0.11.11 - resolution: "synckit@npm:0.11.11" - dependencies: - "@pkgr/core": ^0.2.9 - checksum: bc896d4320525501495654766e6b0aa394e522476ea0547af603bdd9fd7e9b65dcd6e3a237bc7eb3ab7e196376712f228bf1bf6ed1e1809f4b32dc9baf7ad413 - languageName: node - linkType: hard - "table@npm:^6.0.9": - version: 6.9.0 - resolution: "table@npm:6.9.0" + version: 6.8.2 + resolution: "table@npm:6.8.2" dependencies: ajv: ^8.0.1 lodash.truncate: ^4.4.2 slice-ansi: ^4.0.0 string-width: ^4.2.3 strip-ansi: ^6.0.1 - checksum: f54a7d1c11cda8c676e1e9aff5e723646905ed4579cca14b3ce12d2b12eac3e18f5dbe2549fe0b79697164858e18961145db4dd0660bbeb0fb4032af0aaf32b4 - languageName: node - linkType: hard - -"tailwindcss@npm:^3.0.2": - version: 3.4.17 - resolution: "tailwindcss@npm:3.4.17" - 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: ^3.1.3 - 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 - checksum: bda962f30e9a2f0567e2ee936ec863d5178958078e577ced13da60b3af779062a53a7e95f2f32b5c558f12a7477dea3ce071441a7362c6d7bf50bc9e166728a4 + checksum: 61188652f53a980d1759ca460ca8dea5c5322aece3210457e7084882f053c2b6a870041295e08a82cb1d676e31b056406845d94b0abf3c79a4b104777bec413b languageName: node linkType: hard -"tapable@npm:^1.0.0": +"tapable@npm:^1.0.0, tapable@npm:^1.1.3": version: 1.1.3 resolution: "tapable@npm:1.1.3" checksum: 53ff4e7c3900051c38cc4faab428ebfd7e6ad0841af5a7ac6d5f3045c5b50e88497bfa8295b4b3fbcadd94993c9e358868b78b9fb249a76cb8b018ac8dccafd7 languageName: node linkType: hard -"tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": - version: 2.2.3 - resolution: "tapable@npm:2.2.3" - checksum: 0bef252c4f12d3371353c4b16b38ea4fc7153598ab7f7770a4235277ed4d631925a27f42bf03caa754817e9ab017e3179fd2323a0a28409846d225e23f3bf722 - languageName: node - linkType: hard - -"tar-fs@npm:^2.0.0": - version: 2.1.3 - resolution: "tar-fs@npm:2.1.3" - dependencies: - chownr: ^1.1.1 - mkdirp-classic: ^0.5.2 - pump: ^3.0.0 - tar-stream: ^2.1.4 - checksum: 8dd66c20779c1fe535df5cf2ab5132705c12aba3ab95283f225a798329c5aaa8bbe92144c8e21bc9404f46a0d3ce59fc4997f5c42bafc55b6a225d4ad15aa966 - languageName: node - linkType: hard - -"tar-stream@npm:^2.1.4": - version: 2.2.0 - resolution: "tar-stream@npm:2.2.0" - dependencies: - bl: ^4.0.3 - end-of-stream: ^1.4.1 - fs-constants: ^1.0.0 - inherits: ^2.0.3 - readable-stream: ^3.1.1 - checksum: 699831a8b97666ef50021c767f84924cfee21c142c2eb0e79c63254e140e6408d6d55a065a2992548e72b06de39237ef2b802b99e3ece93ca3904a37622a66f3 - languageName: node - linkType: hard - -"tar@npm:^7.4.3": - version: 7.4.3 - resolution: "tar@npm:7.4.3" +"tar@npm:^6.0.2, tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.1 + resolution: "tar@npm:6.2.1" 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 - checksum: 8485350c0688331c94493031f417df069b778aadb25598abdad51862e007c39d1dd5310702c7be4a6784731a174799d8885d2fde0484269aea205b724d7b2ffa + 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 + checksum: f1322768c9741a25356c11373bce918483f40fa9a25c69c59410c8a1247632487edef5fe76c5f12ac51a6356d2f1829e96d2bc34098668a2fc34d76050ac2b6c languageName: node linkType: hard -"temp-dir@npm:^2.0.0": - version: 2.0.0 - resolution: "temp-dir@npm:2.0.0" - checksum: cc4f0404bf8d6ae1a166e0e64f3f409b423f4d1274d8c02814a59a5529f07db6cd070a749664141b992b2c1af337fa9bb451a460a43bb9bcddc49f235d3115aa +"temp-dir@npm:^1.0.0": + version: 1.0.0 + resolution: "temp-dir@npm:1.0.0" + checksum: cb2b58ddfb12efa83e939091386ad73b425c9a8487ea0095fe4653192a40d49184a771a1beba99045fbd011e389fd563122d79f54f82be86a55620667e08a6b2 languageName: node linkType: hard -"tempy@npm:^0.6.0": - version: 0.6.0 - resolution: "tempy@npm:0.6.0" +"tempy@npm:^0.3.0": + version: 0.3.0 + resolution: "tempy@npm:0.3.0" dependencies: - is-stream: ^2.0.0 - temp-dir: ^2.0.0 - type-fest: ^0.16.0 - unique-string: ^2.0.0 - checksum: dd09c8b6615e4b785ea878e9a18b17ac0bfe5dccf5a0e205ebd274bb356356aff3f5c90a6c917077d51c75efb7648b113a78b0492e2ffc81a7c9912eb872ac52 + temp-dir: ^1.0.0 + type-fest: ^0.3.1 + unique-string: ^1.0.0 + checksum: f81ef72a7ee6d512439af8d8891e4fc6595309451910d7ac9d760f1242a1f87272b2b97c830c8f74aaa93a3aa550483bb16db17e6345601f64d614d240edc322 languageName: node linkType: hard @@ -20258,39 +19107,68 @@ __metadata: languageName: node linkType: hard -"terser-webpack-plugin@npm:^5.2.5, terser-webpack-plugin@npm:^5.3.11": - version: 5.3.14 - resolution: "terser-webpack-plugin@npm:5.3.14" +"terser-webpack-plugin@npm:4.2.3": + version: 4.2.3 + resolution: "terser-webpack-plugin@npm:4.2.3" dependencies: - "@jridgewell/trace-mapping": ^0.3.25 - jest-worker: ^27.4.5 - schema-utils: ^4.3.0 - serialize-javascript: ^6.0.2 - terser: ^5.31.1 + cacache: ^15.0.5 + find-cache-dir: ^3.3.1 + jest-worker: ^26.5.0 + p-limit: ^3.0.2 + schema-utils: ^3.0.0 + serialize-javascript: ^5.0.1 + source-map: ^0.6.1 + terser: ^5.3.4 + webpack-sources: ^1.4.3 peerDependencies: - webpack: ^5.1.0 - peerDependenciesMeta: - "@swc/core": - optional: true - esbuild: - optional: true - uglify-js: - optional: true - checksum: 13a1e67f1675a473b18d25cb0ce65c3f0a19b5e9a93213a99ea61dc4ca996ea93aa17a221965b526f5788d242836a8249ad00538fbb322e25cb69076eb55feab + webpack: ^4.0.0 || ^5.0.0 + checksum: ec1b3a85e2645c57e359d5e4831f3e1d78eca2a0c94b156db70eb846ae35b5e6e98ad8784b12e153fc273e57445ce69d017075bbe9fc42868a258ef121f11537 + languageName: node + linkType: hard + +"terser-webpack-plugin@npm:^1.4.3": + version: 1.4.5 + resolution: "terser-webpack-plugin@npm:1.4.5" + dependencies: + cacache: ^12.0.2 + find-cache-dir: ^2.1.0 + is-wsl: ^1.1.0 + schema-utils: ^1.0.0 + serialize-javascript: ^4.0.0 + source-map: ^0.6.1 + terser: ^4.1.2 + webpack-sources: ^1.4.0 + worker-farm: ^1.7.0 + peerDependencies: + webpack: ^4.0.0 + checksum: 02aada80927d3c8105d69cb00384d307b73aed67d180db5d20023a8d649149f3803ad50f9cd2ef9eb2622005de87e677198ecc5088f51422bfac5d4d57472d0e + languageName: node + linkType: hard + +"terser@npm:^4.1.2, terser@npm:^4.6.2, terser@npm:^4.6.3": + version: 4.8.1 + resolution: "terser@npm:4.8.1" + dependencies: + commander: ^2.20.0 + source-map: ~0.6.1 + source-map-support: ~0.5.12 + bin: + terser: bin/terser + checksum: b342819bf7e82283059aaa3f22bb74deb1862d07573ba5a8947882190ad525fd9b44a15074986be083fd379c58b9a879457a330b66dcdb77b485c44267f9a55a languageName: node linkType: hard -"terser@npm:^5.0.0, terser@npm:^5.10.0, terser@npm:^5.31.1": - version: 5.44.0 - resolution: "terser@npm:5.44.0" +"terser@npm:^5.3.4": + version: 5.30.4 + resolution: "terser@npm:5.30.4" dependencies: "@jridgewell/source-map": ^0.3.3 - acorn: ^8.15.0 + acorn: ^8.8.2 commander: ^2.20.0 source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: 4e1868d9662ea280dad7b49cfe61b7693187be2b529b31b1f86782db00833c03ba05f2b82fc513d928e937260f2a5fbf42a93724e86eaf55f069288f934ccdb3 + checksum: 4e33a98d451a1175c83f668cb1dd34e1b4573890ba3081e0389e71e6552ca501ebfda5b15cddeab33585f7b4c13f2e7ad9ba9613655b9e36bc919fde48ba2dcd languageName: node linkType: hard @@ -20305,35 +19183,34 @@ __metadata: languageName: node linkType: hard -"text-table@npm:^0.2.0": +"text-table@npm:0.2.0, text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a languageName: node linkType: hard -"thenify-all@npm:^1.0.0": - version: 1.6.0 - resolution: "thenify-all@npm:1.6.0" - dependencies: - thenify: ">= 3.1.0 < 4" - checksum: dba7cc8a23a154cdcb6acb7f51d61511c37a6b077ec5ab5da6e8b874272015937788402fd271fdfc5f187f8cb0948e38d0a42dcc89d554d731652ab458f5343e +"throat@npm:^5.0.0": + version: 5.0.0 + resolution: "throat@npm:5.0.0" + checksum: 031ff7f4431618036c1dedd99c8aa82f5c33077320a8358ed829e84b320783781d1869fe58e8f76e948306803de966f5f7573766a437562c9f5c033297ad2fe2 languageName: node linkType: hard -"thenify@npm:>= 3.1.0 < 4": - version: 3.3.1 - resolution: "thenify@npm:3.3.1" +"through2@npm:^2.0.0": + version: 2.0.5 + resolution: "through2@npm:2.0.5" dependencies: - any-promise: ^1.0.0 - checksum: 84e1b804bfec49f3531215f17b4a6e50fd4397b5f7c1bccc427b9c656e1ecfb13ea79d899930184f78bc2f57285c54d9a50a590c8868f4f0cef5c1d9f898b05e + readable-stream: ~2.3.6 + xtend: ~4.0.1 + checksum: beb0f338aa2931e5660ec7bf3ad949e6d2e068c31f4737b9525e5201b824ac40cac6a337224856b56bd1ddd866334bbfb92a9f57cd6f66bc3f18d3d86fc0fe50 languageName: node linkType: hard -"throat@npm:^6.0.1": - version: 6.0.2 - resolution: "throat@npm:6.0.2" - checksum: 463093768d4884772020bb18b0f33d3fec8a2b4173f7da3958dfbe88ff0f1e686ffadf0f87333bf6f6db7306b1450efc7855df69c78bf0bfa61f6d84a3361fe8 +"through@npm:^2.3.6": + version: 2.3.8 + resolution: "through@npm:2.3.8" + checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd languageName: node linkType: hard @@ -20344,14 +19221,23 @@ __metadata: languageName: node linkType: hard -"tiny-case@npm:^1.0.3": - version: 1.0.3 - resolution: "tiny-case@npm:1.0.3" - checksum: 3f7a30c39d5b0e1bc097b0b271bec14eb5b836093db034f35a0de26c14422380b50dc12bfd37498cf35b192f5df06f28a710712c87ead68872a9e37ad6f6049d +"timers-browserify@npm:^2.0.4": + version: 2.0.12 + resolution: "timers-browserify@npm:2.0.12" + dependencies: + setimmediate: ^1.0.4 + checksum: ec37ae299066bef6c464dcac29c7adafba1999e7227a9bdc4e105a459bee0f0b27234a46bfd7ab4041da79619e06a58433472867a913d01c26f8a203f87cee70 + languageName: node + linkType: hard + +"timsort@npm:^0.3.0": + version: 0.3.0 + resolution: "timsort@npm:0.3.0" + checksum: 1a66cb897dacabd7dd7c91b7e2301498ca9e224de2edb9e42d19f5b17c4b6dc62a8d4cbc64f28be82aaf1541cb5a78ab49aa818f42a2989ebe049a64af731e2a languageName: node linkType: hard -"tiny-invariant@npm:^1.0.0, tiny-invariant@npm:^1.0.2, tiny-invariant@npm:^1.0.6, tiny-invariant@npm:^1.3.1": +"tiny-invariant@npm:^1.0.2": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 5e185c8cc2266967984ce3b352a4e57cb89dad5a8abb0dea21468a6ecaa67cd5bb47a3b7a85d08041008644af4f667fb8b6575ba38ba5fb00b3b5068306e59fe @@ -20365,87 +19251,73 @@ __metadata: languageName: node linkType: hard -"tinybench@npm:^2.9.0": - version: 2.9.0 - resolution: "tinybench@npm:2.9.0" - checksum: 1ab00d7dfe0d1f127cbf00822bacd9024f7a50a3ecd1f354a8168e0b7d2b53a639a24414e707c27879d1adc0f5153141d51d76ebd7b4d37fe245e742e5d91fe8 - languageName: node - linkType: hard - -"tinyexec@npm:^0.3.1, tinyexec@npm:^0.3.2": - version: 0.3.2 - resolution: "tinyexec@npm:0.3.2" - checksum: bd491923020610bdeadb0d8cf5d70e7cbad5a3201620fd01048c9bf3b31ffaa75c33254e1540e13b993ce4e8187852b0b5a93057bb598e7a57afa2ca2048a35c - languageName: node - linkType: hard - -"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": - version: 0.2.15 - resolution: "tinyglobby@npm:0.2.15" - dependencies: - fdir: ^6.5.0 - picomatch: ^4.0.3 - checksum: 0e33b8babff966c6ab86e9b825a350a6a98a63700fa0bb7ae6cf36a7770a508892383adc272f7f9d17aaf46a9d622b455e775b9949a3f951eaaf5dfb26331d44 +"tinybench@npm:^2.5.0": + version: 2.8.0 + resolution: "tinybench@npm:2.8.0" + checksum: 024a307c6a71f6e2903e110952457ee3dfa606093b45d7f49efcfd01d452650e099474080677ff650b0fd76b49074425ac68ff2a70561699a78515a278bf0862 languageName: node linkType: hard -"tinypool@npm:^1.0.1, tinypool@npm:^1.1.1": - version: 1.1.1 - resolution: "tinypool@npm:1.1.1" - checksum: 0258abe108df8be395a2cbdc8b4390c94908850250530f7bea83a129fa33d49a8c93246f76bf81cd458534abd81322f4d4cb3a40690254f8d9044ff449f328a8 +"tinypool@npm:^0.5.0": + version: 0.5.0 + resolution: "tinypool@npm:0.5.0" + checksum: 4e0dfd8f28666d541c1d92304222edc4613f05d74fe2243c8520d466a2cc6596011a7072c1c41a7de7522351b82fda07e8038198e8f43673d8d69401c5903f8c languageName: node linkType: hard -"tinyrainbow@npm:^1.2.0": - version: 1.2.0 - resolution: "tinyrainbow@npm:1.2.0" - checksum: d1e2cb5400032c0092be00e4a3da5450bea8b4fad58bfb5d3c58ca37ff5c5e252f7fcfb9af247914854af79c46014add9d1042fe044358c305a129ed55c8be35 +"tinyspy@npm:^2.1.1": + version: 2.2.1 + resolution: "tinyspy@npm:2.2.1" + checksum: 170d6232e87f9044f537b50b406a38fbfd6f79a261cd12b92879947bd340939a833a678632ce4f5c4a6feab4477e9c21cd43faac3b90b68b77dd0536c4149736 languageName: node linkType: hard -"tinyrainbow@npm:^2.0.0": - version: 2.0.0 - resolution: "tinyrainbow@npm:2.0.0" - checksum: 26360631d97e43955a07cfb70fe40a154ce4e2bcd14fa3d37ce8e2ed8f4fa9e5ba00783e4906bbfefe6dcabef5d3510f5bee207cb693bee4e4e7553f5454bef1 +"tmp@npm:^0.0.33": + version: 0.0.33 + resolution: "tmp@npm:0.0.33" + dependencies: + os-tmpdir: ~1.0.2 + checksum: 902d7aceb74453ea02abbf58c203f4a8fc1cead89b60b31e354f74ed5b3fb09ea817f94fb310f884a5d16987dd9fa5a735412a7c2dd088dd3d415aa819ae3a28 languageName: node linkType: hard -"tinyspy@npm:^3.0.2": - version: 3.0.2 - resolution: "tinyspy@npm:3.0.2" - checksum: 5db671b2ff5cd309de650c8c4761ca945459d7204afb1776db9a04fb4efa28a75f08517a8620c01ee32a577748802231ad92f7d5b194dc003ee7f987a2a06337 +"tmpl@npm:1.0.5": + version: 1.0.5 + resolution: "tmpl@npm:1.0.5" + checksum: cd922d9b853c00fe414c5a774817be65b058d54a2d01ebb415840960406c669a0fc632f66df885e24cb022ec812739199ccbdb8d1164c3e513f85bfca5ab2873 languageName: node linkType: hard -"tinyspy@npm:^4.0.3": - version: 4.0.3 - resolution: "tinyspy@npm:4.0.3" - checksum: cd5e52d09e2a67946d3a96e6cd68377e1281eb6aaddc9d38129bcec8971a55337ab438ac672857b983f5c620a9f978e784679054322155329d483d00d9291ba9 +"to-arraybuffer@npm:^1.0.0": + version: 1.0.1 + resolution: "to-arraybuffer@npm:1.0.1" + checksum: 31433c10b388722729f5da04c6b2a06f40dc84f797bb802a5a171ced1e599454099c6c5bc5118f4b9105e7d049d3ad9d0f71182b77650e4fdb04539695489941 languageName: node linkType: hard -"tldts-core@npm:^7.0.14": - version: 7.0.14 - resolution: "tldts-core@npm:7.0.14" - checksum: bc13d721605fb66dab2baaf3ae665a8a48722f5b86e2b8a9b299cdbdc34c2a3b7167a08566afe52eed3064a3a0fc08680c456aa170fa9a50d85b9421f787c6db +"to-fast-properties@npm:^2.0.0": + version: 2.0.0 + resolution: "to-fast-properties@npm:2.0.0" + checksum: be2de62fe58ead94e3e592680052683b1ec986c72d589e7b21e5697f8744cdbf48c266fa72f6c15932894c10187b5f54573a3bcf7da0bfd964d5caf23d436168 languageName: node linkType: hard -"tldts@npm:^7.0.5": - version: 7.0.14 - resolution: "tldts@npm:7.0.14" +"to-object-path@npm:^0.3.0": + version: 0.3.0 + resolution: "to-object-path@npm:0.3.0" dependencies: - tldts-core: ^7.0.14 - bin: - tldts: bin/cli.js - checksum: dfd07fe27f2d4bfb7219391dcf666e60ca5041c17e037a7eee3171d4a809e003f71abd73295ab846586c1b589f4aa727439038810e19ef86a8e74ac780deb421 + kind-of: ^3.0.2 + checksum: 9425effee5b43e61d720940fa2b889623f77473d459c2ce3d4a580a4405df4403eec7be6b857455908070566352f9e2417304641ed158dda6f6a365fe3e66d70 languageName: node linkType: hard -"tmpl@npm:1.0.5": - version: 1.0.5 - resolution: "tmpl@npm:1.0.5" - checksum: cd922d9b853c00fe414c5a774817be65b058d54a2d01ebb415840960406c669a0fc632f66df885e24cb022ec812739199ccbdb8d1164c3e513f85bfca5ab2873 +"to-regex-range@npm:^2.1.0": + version: 2.1.1 + resolution: "to-regex-range@npm:2.1.1" + dependencies: + is-number: ^3.0.0 + repeat-string: ^1.6.1 + checksum: 46093cc14be2da905cc931e442d280b2e544e2bfdb9a24b3cf821be8d342f804785e5736c108d5be026021a05d7b38144980a61917eee3c88de0a5e710e10320 languageName: node linkType: hard @@ -20458,6 +19330,18 @@ __metadata: languageName: node linkType: hard +"to-regex@npm:^3.0.1, to-regex@npm:^3.0.2": + version: 3.0.2 + resolution: "to-regex@npm:3.0.2" + dependencies: + define-property: ^2.0.2 + extend-shallow: ^3.0.2 + regex-not: ^1.0.2 + safe-regex: ^1.1.0 + checksum: 4ed4a619059b64e204aad84e4e5f3ea82d97410988bcece7cf6cbfdbf193d11bff48cf53842d88b8bb00b1bfc0d048f61f20f0709e6f393fd8fe0122662d9db4 + languageName: node + linkType: hard + "toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" @@ -20473,41 +19357,25 @@ __metadata: linkType: hard "touch@npm:^3.1.0": - version: 3.1.1 - resolution: "touch@npm:3.1.1" + version: 3.1.0 + resolution: "touch@npm:3.1.0" + dependencies: + nopt: ~1.0.10 bin: - nodetouch: bin/nodetouch.js - checksum: fb8c54207500eb760b6b9d77b9c5626cc027c9ad44431eed4268845f00f8c6bbfc95ce7e9da8e487f020aa921982a8bc5d8e909d0606e82686bd0a08a8e0539b + nodetouch: ./bin/nodetouch.js + checksum: e0be589cb5b0e6dbfce6e7e077d4a0d5f0aba558ef769c6d9c33f635e00d73d5be49da6f8631db302ee073919d82b5b7f56da2987feb28765c95a7673af68647 languageName: node linkType: hard "tough-cookie@npm:^4.0.0": - version: 4.1.4 - resolution: "tough-cookie@npm:4.1.4" + version: 4.1.3 + resolution: "tough-cookie@npm:4.1.3" dependencies: psl: ^1.1.33 punycode: ^2.1.1 universalify: ^0.2.0 url-parse: ^1.5.3 - checksum: 5815059f014c31179a303c673f753f7899a6fce94ac93712c88ea5f3c26e0c042b5f0c7a599a00f8e0feeca4615dba75c3dffc54f3c1a489978aa8205e09307c - languageName: node - linkType: hard - -"tough-cookie@npm:^6.0.0": - version: 6.0.0 - resolution: "tough-cookie@npm:6.0.0" - dependencies: - tldts: ^7.0.5 - checksum: 66d32ee40e1c6c61be5388e1c124674871dae0a684c30853f1628a4da2c5ad4199a825d1b0a7ba424dadfba7b5a9b37e8c761eafbf48f1b9f75a4629e73b14bc - languageName: node - linkType: hard - -"tr46@npm:^1.0.1": - version: 1.0.1 - resolution: "tr46@npm:1.0.1" - dependencies: - punycode: ^2.1.0 - checksum: 96d4ed46bc161db75dbf9247a236ea0bfcaf5758baae6749e92afab0bc5a09cb59af21788ede7e55080f2bf02dce3e4a8f2a484cc45164e29f4b5e68f7cbcc1a + checksum: c9226afff36492a52118432611af083d1d8493a53ff41ec4ea48e5b583aec744b989e4280bcf476c910ec1525a89a4a0f1cae81c08b18fb2ec3a9b3a72b91dcc languageName: node linkType: hard @@ -20527,7 +19395,7 @@ __metadata: languageName: node linkType: hard -"tree-kill@npm:1.2.2": +"tree-kill@npm:^1.2.2": version: 1.2.2 resolution: "tree-kill@npm:1.2.2" bin: @@ -20536,17 +19404,10 @@ __metadata: languageName: node linkType: hard -"trim-lines@npm:^3.0.0": - version: 3.0.1 - resolution: "trim-lines@npm:3.0.1" - checksum: e241da104682a0e0d807222cc1496b92e716af4db7a002f4aeff33ae6a0024fef93165d49eab11aa07c71e1347c42d46563f91dfaa4d3fb945aa535cdead53ed - languageName: node - linkType: hard - -"trough@npm:^2.0.0": - version: 2.2.0 - resolution: "trough@npm:2.2.0" - checksum: 6097df63169aca1f9b08c263b1b501a9b878387f46e161dde93f6d0bba7febba93c95f876a293c5ea370f6cb03bcb687b2488c8955c3cfb66c2c0161ea8c00f6 +"trough@npm:^1.0.0": + version: 1.0.5 + resolution: "trough@npm:1.0.5" + checksum: d6c8564903ed00e5258bab92134b020724dbbe83148dc72e4bf6306c03ed8843efa1bcc773fa62410dd89161ecb067432dd5916501793508a9506cacbc408e25 languageName: node linkType: hard @@ -20557,19 +19418,26 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^2.0.0": - version: 2.1.0 - resolution: "ts-api-utils@npm:2.1.0" +"ts-jest@npm:^26.2.0": + version: 26.5.6 + resolution: "ts-jest@npm:26.5.6" + dependencies: + bs-logger: 0.x + buffer-from: 1.x + fast-json-stable-stringify: 2.x + jest-util: ^26.1.0 + json5: 2.x + lodash: 4.x + make-error: 1.x + mkdirp: 1.x + semver: 7.x + yargs-parser: 20.x peerDependencies: - typescript: ">=4.8.4" - checksum: 5b1ef89105654d93d67582308bd8dfe4bbf6874fccbcaa729b08fbb00a940fd4c691ca6d0d2b18c3c70878d9a7e503421b7cc473dbc3d0d54258b86401d4b15d - languageName: node - linkType: hard - -"ts-interface-checker@npm:^0.1.9": - version: 0.1.13 - resolution: "ts-interface-checker@npm:0.1.13" - checksum: 20c29189c2dd6067a8775e07823ddf8d59a33e2ffc47a1bd59a5cb28bb0121a2969a816d5e77eda2ed85b18171aa5d1c4005a6b88ae8499ec7cc49f78571cb5e + jest: ">=26 <27" + typescript: ">=3.8 <5.0" + bin: + ts-jest: cli.js + checksum: 6f65ad4fe67ab3f0fd4c7f9954acbee863af05b2b3f88dd0f490bbcdc58002960fac908b2cb9f009ec14da6fe13cb00a39e291260d6e555abe72448d1c0a017f languageName: node linkType: hard @@ -20631,6 +19499,16 @@ __metadata: languageName: node linkType: hard +"ts-pnp@npm:1.2.0, ts-pnp@npm:^1.1.6": + version: 1.2.0 + resolution: "ts-pnp@npm:1.2.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: c2a698b85d521298fe6f2435fbf2d3dc5834b423ea25abd321805ead3f399dbeedce7ca09492d7eb005b9d2c009c6b9587055bc3ab273dc6b9e40eefd7edb5b2 + languageName: node + linkType: hard + "tsconfig-paths@npm:^3.15.0": version: 3.15.0 resolution: "tsconfig-paths@npm:3.15.0" @@ -20643,28 +19521,21 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.11.1, tslib@npm:^1.8.1": +"tslib@npm:^1.11.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.6.2": - version: 2.8.1 - resolution: "tslib@npm:2.8.1" - checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a - languageName: node - linkType: hard - -"tsscmp@npm:^1.0.6": - version: 1.0.6 - resolution: "tsscmp@npm:1.0.6" - checksum: 1512384def36bccc9125cabbd4c3b0e68608d7ee08127ceaa0b84a71797263f1a01c7f82fa69be8a3bd3c1396e2965d2f7b52d581d3a5eeaf3967fbc52e3b3bf +"tslib@npm:^2.0.3, tslib@npm:^2.1.0": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad languageName: node linkType: hard -"tsutils@npm:^3.21.0": +"tsutils@npm:^3.17.1, tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" dependencies: @@ -20675,12 +19546,10 @@ __metadata: languageName: node linkType: hard -"tunnel-agent@npm:^0.6.0": - version: 0.6.0 - resolution: "tunnel-agent@npm:0.6.0" - dependencies: - safe-buffer: ^5.0.1 - checksum: 05f6510358f8afc62a057b8b692f05d70c1782b70db86d6a1e0d5e28a32389e52fa6e7707b6c5ecccacc031462e4bc35af85ecfe4bbc341767917b7cf6965711 +"tty-browserify@npm:0.0.0": + version: 0.0.0 + resolution: "tty-browserify@npm:0.0.0" + checksum: a06f746acc419cb2527ba19b6f3bd97b4a208c03823bfb37b2982629d2effe30ebd17eaed0d7e2fc741f3c4f2a0c43455bd5fb4194354b378e78cfb7ca687f59 languageName: node linkType: hard @@ -20702,20 +19571,13 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8": +"type-detect@npm:4.0.8, type-detect@npm:^4.0.0, type-detect@npm:^4.0.8": version: 4.0.8 resolution: "type-detect@npm:4.0.8" checksum: 62b5628bff67c0eb0b66afa371bd73e230399a8d2ad30d852716efcc4656a7516904570cd8631a49a3ce57c10225adf5d0cbdcb47f6b0255fe6557c453925a15 languageName: node linkType: hard -"type-fest@npm:^0.16.0": - version: 0.16.0 - resolution: "type-fest@npm:0.16.0" - checksum: 1a4102c06dc109db00418c753062e206cab65befd469d000ece4452ee649bf2a9cf57686d96fb42326bc9d918d9a194d4452897b486dcc41989e5c99e4e87094 - languageName: node - linkType: hard - "type-fest@npm:^0.20.2": version: 0.20.2 resolution: "type-fest@npm:0.20.2" @@ -20730,17 +19592,31 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^2.19.0": - version: 2.19.0 - resolution: "type-fest@npm:2.19.0" - checksum: a4ef07ece297c9fba78fc1bd6d85dff4472fe043ede98bd4710d2615d15776902b595abf62bd78339ed6278f021235fb28a96361f8be86ed754f778973a0d278 +"type-fest@npm:^0.3.1": + version: 0.3.1 + resolution: "type-fest@npm:0.3.1" + checksum: 347ff46c2285616635cb59f722e7f396bee81b8988b6fc1f1536b725077f2abf6ccfa22ab7a78e9b6ce7debea0e6614bbf5946cbec6674ec1bde12113af3a65c + languageName: node + linkType: hard + +"type-fest@npm:^0.6.0": + version: 0.6.0 + resolution: "type-fest@npm:0.6.0" + checksum: b2188e6e4b21557f6e92960ec496d28a51d68658018cba8b597bd3ef757721d1db309f120ae987abeeda874511d14b776157ff809f23c6d1ce8f83b9b2b7d60f languageName: node linkType: hard -"type-fest@npm:^4.26.1": - version: 4.41.0 - resolution: "type-fest@npm:4.41.0" - checksum: 7055c0e3eb188425d07403f1d5dc175ca4c4f093556f26871fe22041bc93d137d54bef5851afa320638ca1379106c594f5aa153caa654ac1a7f22c71588a4e80 +"type-fest@npm:^0.8.1": + version: 0.8.1 + resolution: "type-fest@npm:0.8.1" + checksum: d61c4b2eba24009033ae4500d7d818a94fd6d1b481a8111612ee141400d5f1db46f199c014766b9fa9b31a6a7374d96fc748c6d688a78a3ce5a33123839becb7 + languageName: node + linkType: hard + +"type-fest@npm:^1.2.2": + version: 1.4.0 + resolution: "type-fest@npm:1.4.0" + checksum: b011c3388665b097ae6a109a437a04d6f61d81b7357f74cbcb02246f2f5bd72b888ae33631b99871388122ba0a87f4ff1c94078e7119ff22c70e52c0ff828201 languageName: node linkType: hard @@ -20753,89 +19629,83 @@ __metadata: checksum: 2c8e47675d55f8b4e404bcf529abdf5036c537a04c2b20177bcf78c9e3c1da69da3942b1346e6edb09e823228c0ee656ef0e033765ec39a70d496ef601a0c657 languageName: node linkType: hard - -"type-is@npm:^2.0.0, type-is@npm:^2.0.1": - version: 2.0.1 - resolution: "type-is@npm:2.0.1" - dependencies: - content-type: ^1.0.5 - media-typer: ^1.1.0 - mime-types: ^3.0.0 - checksum: 0266e7c782238128292e8c45e60037174d48c6366bb2d45e6bd6422b611c193f83409a8341518b6b5f33f8e4d5a959f38658cacfea77f0a3505b9f7ac1ddec8f + +"type@npm:^2.7.2": + version: 2.7.2 + resolution: "type@npm:2.7.2" + checksum: 0f42379a8adb67fe529add238a3e3d16699d95b42d01adfe7b9a7c5da297f5c1ba93de39265ba30ffeb37dfd0afb3fb66ae09f58d6515da442219c086219f6f4 languageName: node linkType: hard -"typed-array-buffer@npm:^1.0.3": - version: 1.0.3 - resolution: "typed-array-buffer@npm:1.0.3" +"typed-array-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-buffer@npm:1.0.2" dependencies: - call-bound: ^1.0.3 + call-bind: ^1.0.7 es-errors: ^1.3.0 - is-typed-array: ^1.1.14 - checksum: 3fb91f0735fb413b2bbaaca9fabe7b8fc14a3fa5a5a7546bab8a57e755be0e3788d893195ad9c2b842620592de0e68d4c077d4c2c41f04ec25b8b5bb82fa9a80 + is-typed-array: ^1.1.13 + checksum: 02ffc185d29c6df07968272b15d5319a1610817916ec8d4cd670ded5d1efe72901541ff2202fcc622730d8a549c76e198a2f74e312eabbfb712ed907d45cbb0b languageName: node linkType: hard -"typed-array-byte-length@npm:^1.0.3": - version: 1.0.3 - resolution: "typed-array-byte-length@npm:1.0.3" +"typed-array-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "typed-array-byte-length@npm:1.0.1" dependencies: - call-bind: ^1.0.8 + call-bind: ^1.0.7 for-each: ^0.3.3 - gopd: ^1.2.0 - has-proto: ^1.2.0 - is-typed-array: ^1.1.14 - checksum: cda9352178ebeab073ad6499b03e938ebc30c4efaea63a26839d89c4b1da9d2640b0d937fc2bd1f049eb0a38def6fbe8a061b601292ae62fe079a410ce56e3a6 + gopd: ^1.0.1 + has-proto: ^1.0.3 + is-typed-array: ^1.1.13 + checksum: f65e5ecd1cf76b1a2d0d6f631f3ea3cdb5e08da106c6703ffe687d583e49954d570cc80434816d3746e18be889ffe53c58bf3e538081ea4077c26a41055b216d languageName: node linkType: hard -"typed-array-byte-offset@npm:^1.0.4": - version: 1.0.4 - resolution: "typed-array-byte-offset@npm:1.0.4" +"typed-array-byte-offset@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-byte-offset@npm:1.0.2" dependencies: available-typed-arrays: ^1.0.7 - call-bind: ^1.0.8 + call-bind: ^1.0.7 for-each: ^0.3.3 - gopd: ^1.2.0 - has-proto: ^1.2.0 - is-typed-array: ^1.1.15 - reflect.getprototypeof: ^1.0.9 - checksum: 670b7e6bb1d3c2cf6160f27f9f529e60c3f6f9611c67e47ca70ca5cfa24ad95415694c49d1dbfeda016d3372cab7dfc9e38c7b3e1bb8d692cae13a63d3c144d7 + gopd: ^1.0.1 + has-proto: ^1.0.3 + is-typed-array: ^1.1.13 + checksum: c8645c8794a621a0adcc142e0e2c57b1823bbfa4d590ad2c76b266aa3823895cf7afb9a893bf6685e18454ab1b0241e1a8d885a2d1340948efa4b56add4b5f67 languageName: node linkType: hard -"typed-array-length@npm:^1.0.7": - version: 1.0.7 - resolution: "typed-array-length@npm:1.0.7" +"typed-array-length@npm:^1.0.6": + version: 1.0.6 + resolution: "typed-array-length@npm:1.0.6" dependencies: call-bind: ^1.0.7 for-each: ^0.3.3 gopd: ^1.0.1 + has-proto: ^1.0.3 is-typed-array: ^1.1.13 possible-typed-array-names: ^1.0.0 - reflect.getprototypeof: ^1.0.6 - checksum: deb1a4ffdb27cd930b02c7030cb3e8e0993084c643208e52696e18ea6dd3953dfc37b939df06ff78170423d353dc8b10d5bae5796f3711c1b3abe52872b3774c + checksum: f0315e5b8f0168c29d390ff410ad13e4d511c78e6006df4a104576844812ee447fcc32daab1f3a76c9ef4f64eff808e134528b5b2439de335586b392e9750e5c languageName: node linkType: hard -"typed-scss-modules@npm:^8.1.1": - version: 8.1.1 - resolution: "typed-scss-modules@npm:8.1.1" +"typed-scss-modules@npm:^6.5.0": + version: 6.6.0 + resolution: "typed-scss-modules@npm:6.6.0" dependencies: - bundle-require: ^4.0.4 + bundle-require: ^3.0.4 chalk: 4.1.2 change-case: ^4.1.2 chokidar: ^3.5.3 - esbuild: ^0.17.0 + css-modules-loader-core: ^1.1.0 + esbuild: ^0.14.21 glob: ^7.2.0 joycon: ^3.1.1 - postcss: ^8.4.27 - postcss-modules: ^6.0.0 reserved-words: ^0.1.2 slash: ^3.0.0 yargs: ^17.3.1 peerDependencies: - node-sass: ^7.0.3 || ^8.0.0 + node-sass: ^4.12.0 sass: ^1.49.7 peerDependenciesMeta: node-sass: @@ -20844,7 +19714,7 @@ __metadata: optional: true bin: typed-scss-modules: dist/lib/cli.js - checksum: a5fb33bbe16722e58d192b744c7915c5e35610f9e3c9faa4f4193c7f36d2d9c6381e2069323b0201d56231ed1de253d34519cb56fae620944b928cff2ea30af6 + checksum: aa039f1c26cb3a3fa5a445f25bf7f3f9754bcc55a9701b7d55fb380ac767eeb60ca2c17f1d983ad8cec4c9e92779e9f8bd57f2859a991ec8f31d6c3acd56856b languageName: node linkType: hard @@ -20864,16 +19734,6 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.7.3": - version: 5.7.3 - resolution: "typescript@npm:5.7.3" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 6c38b1e989918e576f0307e6ee013522ea480dfce5f3ca85c9b2d8adb1edeffd37f4f30cd68de0c38a44563d12ba922bdb7e36aa2dac9c51de5d561e6e9a2e9c - languageName: node - linkType: hard - "typescript@npm:^4.1.5": version: 4.9.5 resolution: "typescript@npm:4.9.5" @@ -20884,26 +19744,6 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.7.3": - version: 5.9.2 - resolution: "typescript@npm:5.9.2" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: f619cf6773cfe31409279711afd68cdf0859780006c50bc2a7a0c3227f85dea89a3b97248846326f3a17dad72ea90ec27cf61a8387772c680b2252fd02d8497b - languageName: node - linkType: hard - -"typescript@patch:typescript@5.7.3#~builtin": - version: 5.7.3 - resolution: "typescript@patch:typescript@npm%3A5.7.3#~builtin::version=5.7.3&hash=7ad353" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 633cd749d6cd7bc842c6b6245847173bba99742a60776fae3c0fbcc0d1733cd51a733995e5f4dadd8afb0e64e57d3c7dbbeae953a072ee303940eca69e22f311 - languageName: node - linkType: hard - "typescript@patch:typescript@^4.1.5#~builtin": version: 4.9.5 resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=7ad353" @@ -20914,25 +19754,22 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@^5.7.3#~builtin": - version: 5.9.2 - resolution: "typescript@patch:typescript@npm%3A5.9.2#~builtin::version=5.9.2&hash=7ad353" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: e42a701947325500008334622321a6ad073f842f5e7d5e7b588a6346b31fdf51d56082b9ce5cef24312ecd3e48d6c0d4d44da7555f65e2feec18cf62ec540385 +"ufo@npm:^1.3.2": + version: 1.5.3 + resolution: "ufo@npm:1.5.3" + checksum: 2f54fa543b2e689cc4ab341fe2194937afe37c5ee43cd782e6ecc184e36859e84d4197a43ae4cd6e9a56f793ca7c5b950dfff3f16fadaeef9b6b88b05c88c8ef languageName: node linkType: hard -"unbox-primitive@npm:^1.1.0": - version: 1.1.0 - resolution: "unbox-primitive@npm:1.1.0" +"unbox-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "unbox-primitive@npm:1.0.2" dependencies: - call-bound: ^1.0.3 + call-bind: ^1.0.2 has-bigints: ^1.0.2 - has-symbols: ^1.1.0 - which-boxed-primitive: ^1.1.1 - checksum: 729f13b84a5bfa3fead1d8139cee5c38514e63a8d6a437819a473e241ba87eeb593646568621c7fc7f133db300ef18d65d1a5a60dc9c7beb9000364d93c581df + has-symbols: ^1.0.3 + which-boxed-primitive: ^1.0.2 + checksum: b7a1cf5862b5e4b5deb091672ffa579aa274f648410009c81cca63fed3b62b610c4f3b773f912ce545bb4e31edc3138975b5bc777fc6e4817dca51affb6380e9 languageName: node linkType: hard @@ -20950,24 +19787,17 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.21.0": - version: 6.21.0 - resolution: "undici-types@npm:6.21.0" - checksum: 46331c7d6016bf85b3e8f20c159d62f5ae471aba1eb3dc52fff35a0259d58dcc7d592d4cc4f00c5f9243fa738a11cfa48bd20203040d4a9e6bc25e807fab7ab3 - languageName: node - linkType: hard - -"undici-types@npm:~7.10.0": - version: 7.10.0 - resolution: "undici-types@npm:7.10.0" - checksum: 6917fcd8c80963919fe918952f9243a6749af0e3f759a39f8d2c2486144a66c86ae4125aebbce700b636cb1dcd45e85eb8c49c60d60738a97b63f0e89ef9b053 +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: 3192ef6f3fd5df652f2dc1cd782b49d6ff14dc98e5dced492aa8a8c65425227da5da6aafe22523c67f035a272c599bb89cfe803c1db6311e44bed3042fc25487 languageName: node linkType: hard "unicode-canonical-property-names-ecmascript@npm:^2.0.0": - version: 2.0.1 - resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1" - checksum: 3c3dabdb1d22aef4904399f9e810d0b71c0b12b3815169d96fac97e56d5642840c6071cf709adcace2252bc6bb80242396c2ec74b37224eb015c5f7aca40bad7 + version: 2.0.0 + resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.0" + checksum: 39be078afd014c14dcd957a7a46a60061bc37c4508ba146517f85f60361acf4c7539552645ece25de840e17e293baa5556268d091ca6762747fdd0c705001a45 languageName: node linkType: hard @@ -20981,10 +19811,10 @@ __metadata: languageName: node linkType: hard -"unicode-match-property-value-ecmascript@npm:^2.2.1": - version: 2.2.1 - resolution: "unicode-match-property-value-ecmascript@npm:2.2.1" - checksum: e6c73e07bb4dc4aa399797a14b170e84a30ed290bcf97cc4305cf67dde8744119721ce17cef03f4f9d4ff48654bfa26eadc7fe1e8dd4b71b8f3b2e9a9742f013 +"unicode-match-property-value-ecmascript@npm:^2.1.0": + version: 2.1.0 + resolution: "unicode-match-property-value-ecmascript@npm:2.1.0" + checksum: 8d6f5f586b9ce1ed0e84a37df6b42fdba1317a05b5df0c249962bd5da89528771e2d149837cad11aa26bcb84c35355cb9f58a10c3d41fa3b899181ece6c85220 languageName: node linkType: hard @@ -20995,93 +19825,153 @@ __metadata: languageName: node linkType: hard -"unified@npm:^11.0.0": - version: 11.0.5 - resolution: "unified@npm:11.0.5" +"unified@npm:^9.0.0": + version: 9.2.2 + resolution: "unified@npm:9.2.2" dependencies: - "@types/unist": ^3.0.0 - bail: ^2.0.0 - devlop: ^1.0.0 + bail: ^1.0.0 extend: ^3.0.0 - is-plain-obj: ^4.0.0 - trough: ^2.0.0 - vfile: ^6.0.0 - checksum: b3bf7fd6f568cc261e074dae21188483b0f2a8ab858d62e6e85b75b96cc655f59532906ae3c64d56a9b257408722d71f1d4135292b3d7ee02907c8b592fb3cf0 + is-buffer: ^2.0.0 + is-plain-obj: ^2.0.0 + trough: ^1.0.0 + vfile: ^4.0.0 + checksum: 7c24461be7de4145939739ce50d18227c5fbdf9b3bc5a29dabb1ce26dd3e8bd4a1c385865f6f825f3b49230953ee8b591f23beab3bb3643e3e9dc37aa8a089d5 languageName: node linkType: hard -"unique-filename@npm:^4.0.0": - version: 4.0.0 - resolution: "unique-filename@npm:4.0.0" +"union-value@npm:^1.0.0": + version: 1.0.1 + resolution: "union-value@npm:1.0.1" dependencies: - unique-slug: ^5.0.0 - checksum: 6a62094fcac286b9ec39edbd1f8f64ff92383baa430af303dfed1ffda5e47a08a6b316408554abfddd9730c78b6106bef4ca4d02c1231a735ddd56ced77573df + arr-union: ^3.1.0 + get-value: ^2.0.6 + is-extendable: ^0.1.1 + set-value: ^2.0.1 + checksum: a3464097d3f27f6aa90cf103ed9387541bccfc006517559381a10e0dffa62f465a9d9a09c9b9c3d26d0f4cbe61d4d010e2fbd710fd4bf1267a768ba8a774b0ba languageName: node linkType: hard -"unique-slug@npm:^5.0.0": - version: 5.0.0 - resolution: "unique-slug@npm:5.0.0" - dependencies: - imurmurhash: ^0.1.4 - checksum: 222d0322bc7bbf6e45c08967863212398313ef73423f4125e075f893a02405a5ffdbaaf150f7dd1e99f8861348a486dd079186d27c5f2c60e465b7dcbb1d3e5b +"uniq@npm:^1.0.1": + version: 1.0.1 + resolution: "uniq@npm:1.0.1" + checksum: 8206535f83745ea83f9da7035f3b983fd6ed5e35b8ed7745441944e4065b616bc67cf0d0a23a86b40ee0074426f0607f0a138f9b78e124eb6a7a6a6966055709 languageName: node linkType: hard -"unique-string@npm:^2.0.0": +"uniqs@npm:^2.0.0": version: 2.0.0 - resolution: "unique-string@npm:2.0.0" + resolution: "uniqs@npm:2.0.0" + checksum: 5ace63e0521fd1ae2c161b3fa167cf6846fc45a71c00496729e0146402c3ae467c6f025a68fbd6766300a9bfbac9f240f2f0198164283bef48012b39db83f81f + languageName: node + linkType: hard + +"unique-filename@npm:^1.1.1": + version: 1.1.1 + resolution: "unique-filename@npm:1.1.1" dependencies: - crypto-random-string: ^2.0.0 - checksum: ef68f639136bcfe040cf7e3cd7a8dff076a665288122855148a6f7134092e6ed33bf83a7f3a9185e46c98dddc445a0da6ac25612afa1a7c38b8b654d6c02498e + unique-slug: ^2.0.0 + checksum: cf4998c9228cc7647ba7814e255dec51be43673903897b1786eff2ac2d670f54d4d733357eb08dea969aa5e6875d0e1bd391d668fbdb5a179744e7c7551a6f80 languageName: node linkType: hard -"unist-util-is@npm:^6.0.0": - version: 6.0.0 - resolution: "unist-util-is@npm:6.0.0" +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" dependencies: - "@types/unist": ^3.0.0 - checksum: f630a925126594af9993b091cf807b86811371e465b5049a6283e08537d3e6ba0f7e248e1e7dab52cfe33f9002606acef093441137181b327f6fe504884b20e2 + unique-slug: ^4.0.0 + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df languageName: node linkType: hard -"unist-util-position@npm:^5.0.0": - version: 5.0.0 - resolution: "unist-util-position@npm:5.0.0" +"unique-slug@npm:^2.0.0": + version: 2.0.2 + resolution: "unique-slug@npm:2.0.2" dependencies: - "@types/unist": ^3.0.0 - checksum: f89b27989b19f07878de9579cd8db2aa0194c8360db69e2c99bd2124a480d79c08f04b73a64daf01a8fb3af7cba65ff4b45a0b978ca243226084ad5f5d441dde + imurmurhash: ^0.1.4 + checksum: 5b6876a645da08d505dedb970d1571f6cebdf87044cb6b740c8dbb24f0d6e1dc8bdbf46825fd09f994d7cf50760e6f6e063cfa197d51c5902c00a861702eb75a languageName: node linkType: hard -"unist-util-stringify-position@npm:^4.0.0": +"unique-slug@npm:^4.0.0": version: 4.0.0 - resolution: "unist-util-stringify-position@npm:4.0.0" + resolution: "unique-slug@npm:4.0.0" dependencies: - "@types/unist": ^3.0.0 - checksum: e2e7aee4b92ddb64d314b4ac89eef7a46e4c829cbd3ee4aee516d100772b490eb6b4974f653ba0717a0071ca6ea0770bf22b0a2ea62c65fcba1d071285e96324 + imurmurhash: ^0.1.4 + checksum: 0884b58365af59f89739e6f71e3feacb5b1b41f2df2d842d0757933620e6de08eff347d27e9d499b43c40476cbaf7988638d3acb2ffbcb9d35fd035591adfd15 languageName: node linkType: hard -"unist-util-visit-parents@npm:^6.0.0": - version: 6.0.1 - resolution: "unist-util-visit-parents@npm:6.0.1" +"unique-string@npm:^1.0.0": + version: 1.0.0 + resolution: "unique-string@npm:1.0.0" dependencies: - "@types/unist": ^3.0.0 - unist-util-is: ^6.0.0 - checksum: 08927647c579f63b91aafcbec9966dc4a7d0af1e5e26fc69f4e3e6a01215084835a2321b06f3cbe7bf7914a852830fc1439f0fc3d7153d8804ac3ef851ddfa20 + crypto-random-string: ^1.0.0 + checksum: 588f16bd4ec99b5130f237793d1a5694156adde20460366726573238e41e93b739b87987e863792aeb2392b26f8afb292490ace119c82ed12c46816c9c859f5f languageName: node linkType: hard -"unist-util-visit@npm:^5.0.0": - version: 5.0.0 - resolution: "unist-util-visit@npm:5.0.0" +"unist-builder@npm:^2.0.0": + version: 2.0.3 + resolution: "unist-builder@npm:2.0.3" + checksum: e946fdf77dbfc320feaece137ce4959ae2da6614abd1623bd39512dc741a9d5f313eb2ba79f8887d941365dccddec7fef4e953827475e392bf49b45336f597f6 + languageName: node + linkType: hard + +"unist-util-generated@npm:^1.0.0": + version: 1.1.6 + resolution: "unist-util-generated@npm:1.1.6" + checksum: 86239ff88a08800d52198f2f0e15911f05bab2dad17cef95550f7c2728f15ebb0344694fcc3101d05762d88adaf86cb85aa7a3300fedabd0b6d7d00b41cdcb7f + languageName: node + linkType: hard + +"unist-util-is@npm:^4.0.0": + version: 4.1.0 + resolution: "unist-util-is@npm:4.1.0" + checksum: 726484cd2adc9be75a939aeedd48720f88294899c2e4a3143da413ae593f2b28037570730d5cf5fd910ff41f3bc1501e3d636b6814c478d71126581ef695f7ea + languageName: node + linkType: hard + +"unist-util-position@npm:^3.0.0": + version: 3.1.0 + resolution: "unist-util-position@npm:3.1.0" + checksum: 10b3952e32a1ffabbecad41c3946237f7059f5bb6436796da05531a285f50b97e4f37cfc2f7164676d041063f40fe1ad92fbb8ca38d3ae8747328ebe738d738f + languageName: node + linkType: hard + +"unist-util-stringify-position@npm:^2.0.0": + version: 2.0.3 + resolution: "unist-util-stringify-position@npm:2.0.3" + dependencies: + "@types/unist": ^2.0.2 + checksum: f755cadc959f9074fe999578a1a242761296705a7fe87f333a37c00044de74ab4b184b3812989a57d4cd12211f0b14ad397b327c3a594c7af84361b1c25a7f09 + languageName: node + linkType: hard + +"unist-util-visit-parents@npm:^3.0.0": + version: 3.1.1 + resolution: "unist-util-visit-parents@npm:3.1.1" + dependencies: + "@types/unist": ^2.0.0 + unist-util-is: ^4.0.0 + checksum: 1170e397dff88fab01e76d5154981666eb0291019d2462cff7a2961a3e76d3533b42eaa16b5b7e2d41ad42a5ea7d112301458283d255993e660511387bf67bc3 + languageName: node + linkType: hard + +"unist-util-visit@npm:^2.0.0": + version: 2.0.3 + resolution: "unist-util-visit@npm:2.0.3" dependencies: - "@types/unist": ^3.0.0 - unist-util-is: ^6.0.0 - unist-util-visit-parents: ^6.0.0 - checksum: 9ec42e618e7e5d0202f3c191cd30791b51641285732767ee2e6bcd035931032e3c1b29093f4d7fd0c79175bbc1f26f24f26ee49770d32be76f8730a652a857e6 + "@types/unist": ^2.0.0 + unist-util-is: ^4.0.0 + unist-util-visit-parents: ^3.0.0 + checksum: 1fe19d500e212128f96d8c3cfa3312846e586b797748a1fd195fe6479f06bc90a6f6904deb08eefc00dd58e83a1c8a32fb8677252d2273ad7a5e624525b69b8f + languageName: node + linkType: hard + +"universalify@npm:^0.1.0": + version: 0.1.2 + resolution: "universalify@npm:0.1.2" + checksum: 40cdc60f6e61070fe658ca36016a8f4ec216b29bf04a55dce14e3710cc84c7448538ef4dad3728d0bfe29975ccd7bfb5f414c45e7b78883567fb31b246f02dff languageName: node linkType: hard @@ -21123,24 +20013,34 @@ __metadata: languageName: node linkType: hard -"upath@npm:^1.2.0": +"unset-value@npm:^1.0.0": + version: 1.0.0 + resolution: "unset-value@npm:1.0.0" + dependencies: + has-value: ^0.3.1 + isobject: ^3.0.0 + checksum: 5990ecf660672be2781fc9fb322543c4aa592b68ed9a3312fa4df0e9ba709d42e823af090fc8f95775b4cd2c9a5169f7388f0cec39238b6d0d55a69fc2ab6b29 + languageName: node + linkType: hard + +"upath@npm:^1.1.1, upath@npm:^1.1.2, upath@npm:^1.2.0": version: 1.2.0 resolution: "upath@npm:1.2.0" checksum: 4c05c094797cb733193a0784774dbea5b1889d502fc9f0572164177e185e4a59ba7099bf0b0adf945b232e2ac60363f9bf18aac9b2206fb99cbef971a8455445 languageName: node linkType: hard -"update-browserslist-db@npm:^1.1.3": - version: 1.1.3 - resolution: "update-browserslist-db@npm:1.1.3" +"update-browserslist-db@npm:^1.0.13": + version: 1.0.13 + resolution: "update-browserslist-db@npm:1.0.13" dependencies: - escalade: ^3.2.0 - picocolors: ^1.1.1 + escalade: ^3.1.1 + picocolors: ^1.0.0 peerDependencies: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 7b6d8d08c34af25ee435bccac542bedcb9e57c710f3c42421615631a80aa6dd28b0a81c9d2afbef53799d482fb41453f714b8a7a0a8003e3b4ec8fb1abb819af + checksum: 1e47d80182ab6e4ad35396ad8b61008ae2a1330221175d0abd37689658bdb61af9b705bfc41057fd16682474d79944fb2d86767c5ed5ae34b6276b9bed353322 languageName: node linkType: hard @@ -21171,7 +20071,31 @@ __metadata: languageName: node linkType: hard -"url-parse@npm:^1.5.3": +"urix@npm:^0.1.0": + version: 0.1.0 + resolution: "urix@npm:0.1.0" + checksum: 4c076ecfbf3411e888547fe844e52378ab5ada2d2f27625139011eada79925e77f7fbf0e4016d45e6a9e9adb6b7e64981bd49b22700c7c401c5fc15f423303b3 + languageName: node + linkType: hard + +"url-loader@npm:4.1.1": + version: 4.1.1 + resolution: "url-loader@npm:4.1.1" + dependencies: + loader-utils: ^2.0.0 + mime-types: ^2.1.27 + schema-utils: ^3.0.0 + peerDependencies: + file-loader: "*" + webpack: ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + file-loader: + optional: true + checksum: c1122a992c6cff70a7e56dfc2b7474534d48eb40b2cc75467cde0c6972e7597faf8e43acb4f45f93c2473645dfd803bcbc20960b57544dd1e4c96e77f72ba6fd + languageName: node + linkType: hard + +"url-parse@npm:^1.5.10, url-parse@npm:^1.5.3": version: 1.5.10 resolution: "url-parse@npm:1.5.10" dependencies: @@ -21188,21 +20112,20 @@ __metadata: languageName: node linkType: hard -"use-memo-one@npm:^1.1.3": - version: 1.1.3 - resolution: "use-memo-one@npm:1.1.3" - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 8f08eba26d69406b61bb4b8dacdd5a92bd6aef5b53d346dfe87954f7330ee10ecabc937cc7854635155d46053828e85c10b5a5aff7a04720e6a97b9f42999bac +"url@npm:^0.11.0": + version: 0.11.3 + resolution: "url@npm:0.11.3" + dependencies: + punycode: ^1.4.1 + qs: ^6.11.2 + checksum: f9e7886f46a16f96d2e42fbcc5d682c231c55ef5442c1ff66150c0f6556f6e3a97d094a84f51be15ec2432711d212eb60426659ce418f5fcadeaa3f601532c4e languageName: node linkType: hard -"use-sync-external-store@npm:^1.4.0": - version: 1.5.0 - resolution: "use-sync-external-store@npm:1.5.0" - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - checksum: 5e639c9273200adb6985b512c96a3a02c458bc8ca1a72e91da9cdc6426144fc6538dca434b0f99b28fb1baabc82e1c383ba7900b25ccdcb43758fb058dc66c34 +"use@npm:^3.1.0": + version: 3.1.1 + resolution: "use@npm:3.1.1" + checksum: 08a130289f5238fcbf8f59a18951286a6e660d17acccc9d58d9b69dfa0ee19aa038e8f95721b00b432c36d1629a9e32a464bf2e7e0ae6a244c42ddb30bdd8b33 languageName: node linkType: hard @@ -21213,6 +20136,16 @@ __metadata: languageName: node linkType: hard +"util.promisify@npm:1.0.0": + version: 1.0.0 + resolution: "util.promisify@npm:1.0.0" + dependencies: + define-properties: ^1.1.2 + object.getownpropertydescriptors: ^2.0.3 + checksum: 482e857d676adee506c5c3a10212fd6a06a51d827a9b6d5396a8e593db53b4bb7064f77c5071357d8cd76072542de5cc1c08bc6d7c10cf43fa22dc3bc67556f1 + languageName: node + linkType: hard + "util.promisify@npm:~1.0.0": version: 1.0.1 resolution: "util.promisify@npm:1.0.1" @@ -21225,6 +20158,37 @@ __metadata: languageName: node linkType: hard +"util@npm:^0.10.4": + version: 0.10.4 + resolution: "util@npm:0.10.4" + dependencies: + inherits: 2.0.3 + checksum: 913f9a90d05a60e91f91af01b8bd37e06bca4cc02d7b49e01089f9d5b78be2fffd61fb1a41b517de7238c5fc7337fa939c62d1fb4eb82e014894c7bee6637aaf + languageName: node + linkType: hard + +"util@npm:^0.11.0": + version: 0.11.1 + resolution: "util@npm:0.11.1" + dependencies: + inherits: 2.0.3 + checksum: 80bee6a2edf5ab08dcb97bfe55ca62289b4e66f762ada201f2c5104cb5e46474c8b334f6504d055c0e6a8fda10999add9bcbd81ba765e7f37b17dc767331aa55 + languageName: node + linkType: hard + +"util@npm:^0.12.3": + version: 0.12.5 + resolution: "util@npm:0.12.5" + dependencies: + inherits: ^2.0.3 + is-arguments: ^1.0.4 + is-generator-function: ^1.0.7 + is-typed-array: ^1.1.3 + which-typed-array: ^1.1.2 + checksum: 705e51f0de5b446f4edec10739752ac25856541e0254ea1e7e45e5b9f9b0cb105bc4bd415736a6210edc68245a7f903bf085ffb08dd7deb8a0e847f60538a38a + languageName: node + linkType: hard + "utila@npm:~0.4": version: 0.4.0 resolution: "utila@npm:0.4.0" @@ -21239,16 +20203,16 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^11.1.0": - version: 11.1.0 - resolution: "uuid@npm:11.1.0" +"uuid@npm:^3.3.2": + version: 3.4.0 + resolution: "uuid@npm:3.4.0" bin: - uuid: dist/esm/bin/uuid - checksum: 840f19758543c4631e58a29439e51b5b669d5f34b4dd2700b6a1d15c5708c7a6e0c3e2c8c4a2eae761a3a7caa7e9884d00c86c02622ba91137bd3deade6b4b4a + uuid: ./bin/uuid + checksum: 58de2feed61c59060b40f8203c0e4ed7fd6f99d42534a499f1741218a1dd0c129f4aa1de797bcf822c8ea5da7e4137aa3673431a96dae729047f7aca7b27866f languageName: node linkType: hard -"uuid@npm:^8.3.2": +"uuid@npm:^8.3.0, uuid@npm:^8.3.2": version: 8.3.2 resolution: "uuid@npm:8.3.2" bin: @@ -21257,7 +20221,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^9.0.0, uuid@npm:^9.0.1": +"uuid@npm:^9.0.0": version: 9.0.1 resolution: "uuid@npm:9.0.1" bin: @@ -21280,21 +20244,31 @@ __metadata: languageName: node linkType: hard -"v8-to-istanbul@npm:^8.1.0": - version: 8.1.1 - resolution: "v8-to-istanbul@npm:8.1.1" +"v8-to-istanbul@npm:^7.0.0": + version: 7.1.2 + resolution: "v8-to-istanbul@npm:7.1.2" dependencies: "@types/istanbul-lib-coverage": ^2.0.1 convert-source-map: ^1.6.0 source-map: ^0.7.3 - checksum: 54ce92bec2727879626f623d02c8d193f0c7e919941fa373ec135189a8382265117f5316ea317a1e12a5f9c13d84d8449052a731fe3306fa4beaafbfa4cab229 + checksum: e52b48764f55aed62ff87f2b5f710c874f992cd1313eac8f438bf65aeeb0689153d85bb76e39514fd90ba3521d6ebea929a8ae1339b6d7b0cf18fb0ed13d8b40 + languageName: node + linkType: hard + +"validate-npm-package-license@npm:^3.0.1": + version: 3.0.4 + resolution: "validate-npm-package-license@npm:3.0.4" + dependencies: + spdx-correct: ^3.0.0 + spdx-expression-parse: ^3.0.0 + checksum: 35703ac889d419cf2aceef63daeadbe4e77227c39ab6287eeb6c1b36a746b364f50ba22e88591f5d017bc54685d8137bc2d328d0a896e4d3fd22093c0f32a9ad languageName: node linkType: hard "validator@npm:^13.9.0": - version: 13.15.15 - resolution: "validator@npm:13.15.15" - checksum: 10c1b9215a25c31497c481cf4a3ee3e17dcf0b8a219445788e7167ed1b93b8597bbf657bd5c8ca22199b699c3ab41df902c23526cc514075c4b71bd19a13d02c + version: 13.11.0 + resolution: "validator@npm:13.11.0" + checksum: d1e0c27022681420756da25bc03eb08d5f0c66fb008f8ff02ebc95812b77c6be6e03d3bd05cf80ca702e23eeb73dadd66b4b3683173ea2a0bc7cc72820bee131 languageName: node linkType: hard @@ -21305,271 +20279,138 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:^1.1.2, vary@npm:~1.1.2": +"vary@npm:^1, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: ae0123222c6df65b437669d63dfa8c36cee20a504101b2fcd97b8bf76f91259c17f9f2b4d70a1e3c6bbcee7f51b28392833adb6b2770b23b01abec84e369660b languageName: node linkType: hard -"vfile-message@npm:^4.0.0": - version: 4.0.3 - resolution: "vfile-message@npm:4.0.3" - dependencies: - "@types/unist": ^3.0.0 - unist-util-stringify-position: ^4.0.0 - checksum: f5e8516f2aa0feb4c866d507543d4e90f9ab309e2c988577dbf4ebd268d495f72f2b48149849d14300164d5d60b5f74b5641cd285bb4408a3942b758683d9276 - languageName: node - linkType: hard - -"vfile@npm:^6.0.0": - version: 6.0.3 - resolution: "vfile@npm:6.0.3" - dependencies: - "@types/unist": ^3.0.0 - vfile-message: ^4.0.0 - checksum: 152b6729be1af70df723efb65c1a1170fd483d41086557da3651eea69a1dd1f0c22ea4344834d56d30734b9185bcab63e22edc81d3f0e9bed8aa4660d61080af - languageName: node - linkType: hard - -"victory-vendor@npm:^36.6.8": - version: 36.9.2 - resolution: "victory-vendor@npm:36.9.2" - dependencies: - "@types/d3-array": ^3.0.3 - "@types/d3-ease": ^3.0.0 - "@types/d3-interpolate": ^3.0.1 - "@types/d3-scale": ^4.0.2 - "@types/d3-shape": ^3.1.0 - "@types/d3-time": ^3.0.0 - "@types/d3-timer": ^3.0.0 - d3-array: ^3.1.6 - d3-ease: ^3.0.1 - d3-interpolate: ^3.0.1 - d3-scale: ^4.0.2 - d3-shape: ^3.1.0 - d3-time: ^3.0.0 - d3-timer: ^3.0.1 - checksum: a755110e287b700202d08ac81982093ab100edaa9d61beef1476d59e9705605bd8299a3aa41fa04b933a12bd66737f4c8f7d18448dd6488c69d4f72480023a2e - languageName: node - linkType: hard - -"vite-node@npm:2.1.9": - version: 2.1.9 - resolution: "vite-node@npm:2.1.9" - dependencies: - cac: ^6.7.14 - debug: ^4.3.7 - es-module-lexer: ^1.5.4 - pathe: ^1.1.2 - vite: ^5.0.0 - bin: - vite-node: vite-node.mjs - checksum: 716d37649834ecea547b43121ee89b2e4f9ca65ff6ce26214770ecfefe070b8c7245c9fdd0f92fb232d266e153629d04af9a4dc4fc350abfa521e5e46434b7b2 - languageName: node - linkType: hard - -"vite-node@npm:3.2.4": - version: 3.2.4 - resolution: "vite-node@npm:3.2.4" - dependencies: - cac: ^6.7.14 - debug: ^4.4.1 - es-module-lexer: ^1.7.0 - pathe: ^2.0.3 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 - bin: - vite-node: vite-node.mjs - checksum: 2051394d48f5eefdee4afc9c5fd5dcbf7eb36d345043ba035c7782e10b33fbbd14318062c4e32e00d473a31a559fb628d67c023e82a4903016db3ac6bfdb3fe7 - languageName: node - linkType: hard - -"vite@npm:6.0.7": - version: 6.0.7 - resolution: "vite@npm:6.0.7" - dependencies: - esbuild: ^0.24.2 - fsevents: ~2.3.3 - postcss: ^8.4.49 - rollup: ^4.23.0 - peerDependencies: - "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: ">=1.21.0" - less: "*" - lightningcss: ^1.21.0 - sass: "*" - sass-embedded: "*" - stylus: "*" - sugarss: "*" - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - dependenciesMeta: - fsevents: - optional: true - peerDependenciesMeta: - "@types/node": - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - bin: - vite: bin/vite.js - checksum: 0a948bcd33cf1891a1079ccea6d7e2d1e030ed5d1ad86c9de41a5cb2935da50f77ef699a57ea12fa4a332d9def5494e80d75ea6504758d9d1d9a139f3c1c7fbe - languageName: node - linkType: hard - -"vite@npm:^5.0.0": - version: 5.4.20 - resolution: "vite@npm:5.4.20" - dependencies: - esbuild: ^0.21.3 - fsevents: ~2.3.3 - postcss: ^8.4.43 - rollup: ^4.20.0 - peerDependencies: - "@types/node": ^18.0.0 || >=20.0.0 - less: "*" - lightningcss: ^1.21.0 - sass: "*" - sass-embedded: "*" - stylus: "*" - sugarss: "*" - terser: ^5.4.0 - dependenciesMeta: - fsevents: - optional: true - 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 +"vendors@npm:^1.0.0": + version: 1.0.4 + resolution: "vendors@npm:1.0.4" + checksum: 4b16e0bc18dbdd7ac8dd745c776c08f6c73e9a7f620ffd9faf94a3d86a35feaf4c6cb1bbdb304d2381548a30d0abe69b83eeb1b7b1bf5bb33935e64b28812681 + languageName: node + linkType: hard + +"vfile-message@npm:^2.0.0": + version: 2.0.4 + resolution: "vfile-message@npm:2.0.4" + dependencies: + "@types/unist": ^2.0.0 + unist-util-stringify-position: ^2.0.0 + checksum: 1bade499790f46ca5aba04bdce07a1e37c2636a8872e05cf32c26becc912826710b7eb063d30c5754fdfaeedc8a7658e78df10b3bc535c844890ec8a184f5643 + languageName: node + linkType: hard + +"vfile@npm:^4.0.0": + version: 4.2.1 + resolution: "vfile@npm:4.2.1" + dependencies: + "@types/unist": ^2.0.0 + is-buffer: ^2.0.0 + unist-util-stringify-position: ^2.0.0 + vfile-message: ^2.0.0 + checksum: ee5726e10d170472cde778fc22e0f7499caa096eb85babea5d0ce0941455b721037ee1c9e6ae506ca2803250acd313d0f464328ead0b55cfe7cb6315f1b462d6 + languageName: node + linkType: hard + +"vite-node@npm:0.32.4": + version: 0.32.4 + resolution: "vite-node@npm:0.32.4" + dependencies: + cac: ^6.7.14 + debug: ^4.3.4 + mlly: ^1.4.0 + pathe: ^1.1.1 + picocolors: ^1.0.0 + vite: ^3.0.0 || ^4.0.0 bin: - vite: bin/vite.js - checksum: 67af97e818977e92d1e55bc35d45f58d41eba6fc87f2a18435d3402adb07f4c4ec1ba838d954829f80f7784e65b65f8d147db695cfaefe45f667ee283530770d + vite-node: vite-node.mjs + checksum: 6edb7aafcc30b97213435e7b3bfa43e2133feadd46680c0e54b44064f9e38f9b6e3a75f7c0ccde6bf3b6f34cb9681ec6510fb966a11f9ca7239e9473200a4a24 languageName: node linkType: hard -"vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": - version: 7.1.5 - resolution: "vite@npm:7.1.5" +"vite@npm:^3.0.0 || ^4.0.0, vite@npm:^4.4.5": + version: 4.5.3 + resolution: "vite@npm:4.5.3" dependencies: - esbuild: ^0.25.0 - fdir: ^6.5.0 - fsevents: ~2.3.3 - picomatch: ^4.0.3 - postcss: ^8.5.6 - rollup: ^4.43.0 - tinyglobby: ^0.2.15 + esbuild: ^0.18.10 + fsevents: ~2.3.2 + postcss: ^8.4.27 + rollup: ^3.27.1 peerDependencies: - "@types/node": ^20.19.0 || >=22.12.0 - jiti: ">=1.21.0" - less: ^4.0.0 + "@types/node": ">= 14" + less: "*" lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: ">=0.54.8" - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 + sass: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 dependenciesMeta: fsevents: optional: true peerDependenciesMeta: "@types/node": optional: true - jiti: - optional: true less: optional: true lightningcss: optional: true sass: optional: true - sass-embedded: - optional: true stylus: optional: true sugarss: optional: true terser: optional: true - tsx: - optional: true - yaml: - optional: true bin: vite: bin/vite.js - checksum: 14922d98024a1d93ebe8f3ce38af586c83d55f037f8c5fe8664103d7aa0785d0747f3edf8cb6550dcfa071b90bfd40bce56581d9cb14a19a53d29abb9f3415f5 + checksum: fd3f512ce48ca2a1fe60ad0376283b832de9272725fdbc65064ae9248f792de87b0f27a89573115e23e26784800daca329f8a9234d298ba6f60e808a9c63883c languageName: node linkType: hard -"vitest@npm:^2.1.8": - version: 2.1.9 - resolution: "vitest@npm:2.1.9" +"vitest@npm:^0.32.1": + version: 0.32.4 + resolution: "vitest@npm:0.32.4" dependencies: - "@vitest/expect": 2.1.9 - "@vitest/mocker": 2.1.9 - "@vitest/pretty-format": ^2.1.9 - "@vitest/runner": 2.1.9 - "@vitest/snapshot": 2.1.9 - "@vitest/spy": 2.1.9 - "@vitest/utils": 2.1.9 - chai: ^5.1.2 - debug: ^4.3.7 - expect-type: ^1.1.0 - magic-string: ^0.30.12 - pathe: ^1.1.2 - std-env: ^3.8.0 - tinybench: ^2.9.0 - tinyexec: ^0.3.1 - tinypool: ^1.0.1 - tinyrainbow: ^1.2.0 - vite: ^5.0.0 - vite-node: 2.1.9 - why-is-node-running: ^2.3.0 + "@types/chai": ^4.3.5 + "@types/chai-subset": ^1.3.3 + "@types/node": "*" + "@vitest/expect": 0.32.4 + "@vitest/runner": 0.32.4 + "@vitest/snapshot": 0.32.4 + "@vitest/spy": 0.32.4 + "@vitest/utils": 0.32.4 + acorn: ^8.9.0 + acorn-walk: ^8.2.0 + cac: ^6.7.14 + chai: ^4.3.7 + debug: ^4.3.4 + local-pkg: ^0.4.3 + magic-string: ^0.30.0 + pathe: ^1.1.1 + picocolors: ^1.0.0 + std-env: ^3.3.3 + strip-literal: ^1.0.1 + tinybench: ^2.5.0 + tinypool: ^0.5.0 + vite: ^3.0.0 || ^4.0.0 + vite-node: 0.32.4 + why-is-node-running: ^2.2.2 peerDependencies: "@edge-runtime/vm": "*" - "@types/node": ^18.0.0 || >=20.0.0 - "@vitest/browser": 2.1.9 - "@vitest/ui": 2.1.9 + "@vitest/browser": "*" + "@vitest/ui": "*" happy-dom: "*" jsdom: "*" + playwright: "*" + safaridriver: "*" + webdriverio: "*" peerDependenciesMeta: "@edge-runtime/vm": optional: true - "@types/node": - optional: true "@vitest/browser": optional: true "@vitest/ui": @@ -21578,65 +20419,22 @@ __metadata: optional: true jsdom: optional: true - bin: - vitest: vitest.mjs - checksum: 20db77529f843930ef1626103c898b27528d6d68d6c44753ec823e318f26bbdeb3bc56e6fb80e3f1ecc34382107d32e1f4e709e23198f414fecc9298ab225fa8 - languageName: node - linkType: hard - -"vitest@npm:^3.0.0": - version: 3.2.4 - resolution: "vitest@npm:3.2.4" - dependencies: - "@types/chai": ^5.2.2 - "@vitest/expect": 3.2.4 - "@vitest/mocker": 3.2.4 - "@vitest/pretty-format": ^3.2.4 - "@vitest/runner": 3.2.4 - "@vitest/snapshot": 3.2.4 - "@vitest/spy": 3.2.4 - "@vitest/utils": 3.2.4 - chai: ^5.2.0 - debug: ^4.4.1 - expect-type: ^1.2.1 - magic-string: ^0.30.17 - pathe: ^2.0.3 - picomatch: ^4.0.2 - std-env: ^3.9.0 - tinybench: ^2.9.0 - tinyexec: ^0.3.2 - tinyglobby: ^0.2.14 - tinypool: ^1.1.1 - tinyrainbow: ^2.0.0 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 - vite-node: 3.2.4 - why-is-node-running: ^2.3.0 - peerDependencies: - "@edge-runtime/vm": "*" - "@types/debug": ^4.1.12 - "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 - "@vitest/browser": 3.2.4 - "@vitest/ui": 3.2.4 - happy-dom: "*" - jsdom: "*" - peerDependenciesMeta: - "@edge-runtime/vm": - optional: true - "@types/debug": - optional: true - "@types/node": - optional: true - "@vitest/browser": - optional: true - "@vitest/ui": + playwright: optional: true - happy-dom: + safaridriver: optional: true - jsdom: + webdriverio: optional: true bin: vitest: vitest.mjs - checksum: e9aa14a2c4471c2e0364d1d7032303db8754fac9e5e9ada92fca8ebf61ee78d2c5d4386bff25913940a22ea7d78ab435c8dd85785d681b23e2c489d6c17dd382 + checksum: 0f3347aac5656e6ba14c2f82d8fc5bfa333766ec745f7250f02a28d4cf6b35e645a300f0116a7db542430f59edb96cfeb3d2bc87856b84c776c25d10581f051b + languageName: node + linkType: hard + +"vm-browserify@npm:^1.0.1": + version: 1.1.2 + resolution: "vm-browserify@npm:1.1.2" + checksum: 10a1c50aab54ff8b4c9042c15fc64aefccce8d2fb90c0640403242db0ee7fb269f9b102bdb69cfb435d7ef3180d61fd4fb004a043a12709abaf9056cfd7e039d languageName: node linkType: hard @@ -21658,7 +20456,7 @@ __metadata: languageName: node linkType: hard -"walker@npm:^1.0.7": +"walker@npm:^1.0.7, walker@npm:~1.0.5": version: 1.0.8 resolution: "walker@npm:1.0.8" dependencies: @@ -21667,22 +20465,29 @@ __metadata: languageName: node linkType: hard -"warning@npm:^4.0.0": - version: 4.0.3 - resolution: "warning@npm:4.0.3" +"watchpack-chokidar2@npm:^2.0.1": + version: 2.0.1 + resolution: "watchpack-chokidar2@npm:2.0.1" dependencies: - loose-envify: ^1.0.0 - checksum: 4f2cb6a9575e4faf71ddad9ad1ae7a00d0a75d24521c193fa464f30e6b04027bd97aa5d9546b0e13d3a150ab402eda216d59c1d0f2d6ca60124d96cd40dfa35c + chokidar: ^2.1.8 + checksum: acf0f9ebca0c0b2fd1fe87ba557670477a6c0410bf1a653a726e68eb0620aa94fd9a43027a160a76bc793a21ea12e215e1e87dafe762682c13ef92ad4daf7b58 languageName: node linkType: hard -"watchpack@npm:^2.4.1": - version: 2.4.4 - resolution: "watchpack@npm:2.4.4" +"watchpack@npm:^1.7.4": + version: 1.7.5 + resolution: "watchpack@npm:1.7.5" dependencies: - glob-to-regexp: ^0.4.1 + chokidar: ^3.4.1 graceful-fs: ^4.1.2 - checksum: 469514a04bcdd7ea77d4b3c62d1f087eafbce64cbc728c89355d5710ee01311533456122da7c585d3654d5bfcf09e6085db1a6eb274c4762a18e370526d17561 + neo-async: ^2.5.0 + watchpack-chokidar2: ^2.0.1 + dependenciesMeta: + chokidar: + optional: true + watchpack-chokidar2: + optional: true + checksum: 8b7cb8c8df8f4dd0e8ac47693c0141c4f020a4b031411247d600eca31522fde6f1f9a3a6f6518b46e71f7971b0ed5734c08c60d7fdd2530e7262776286f69236 languageName: node linkType: hard @@ -21695,10 +20500,32 @@ __metadata: languageName: node linkType: hard -"web-vitals@npm:^4.2.4": - version: 4.2.4 - resolution: "web-vitals@npm:4.2.4" - checksum: 5b3ffe1db33f23aebf8cc8560ac574401a95939baafde5841835c1bb1c01f9a2478442f319f77aa0d7914739fc2f6b020c5d5b128c16c5c77ca6be2f9dfbbde6 +"wcwidth@npm:^1.0.1": + version: 1.0.1 + resolution: "wcwidth@npm:1.0.1" + dependencies: + defaults: ^1.0.3 + checksum: 814e9d1ddcc9798f7377ffa448a5a3892232b9275ebb30a41b529607691c0491de47cba426e917a4d08ded3ee7e9ba2f3fe32e62ee3cd9c7d3bafb7754bd553c + languageName: node + linkType: hard + +"web-encoding@npm:^1.1.5": + version: 1.1.5 + resolution: "web-encoding@npm:1.1.5" + dependencies: + "@zxing/text-encoding": 0.9.0 + util: ^0.12.3 + dependenciesMeta: + "@zxing/text-encoding": + optional: true + checksum: 2234a2b122f41006ce07859b3c0bf2e18f46144fda2907d5db0b571b76aa5c26977c646100ad9c00d2f8a4f6f2b848bc02147845d8c447ab365ec4eff376338d + languageName: node + linkType: hard + +"web-vitals@npm:^0.2.4": + version: 0.2.4 + resolution: "web-vitals@npm:0.2.4" + checksum: 128a4e87730b0a02fb6af3eef7d31f9a79b4646e83cfe4465aa8ce6054fe16f7b1f4125a384f1b4f039091bd9513cb54b4e559c0b10ae953c01900786a16b1c2 languageName: node linkType: hard @@ -21709,13 +20536,6 @@ __metadata: languageName: node linkType: hard -"webidl-conversions@npm:^4.0.2": - version: 4.0.2 - resolution: "webidl-conversions@npm:4.0.2" - checksum: c93d8dfe908a0140a4ae9c0ebc87a33805b416a33ee638a605b551523eec94a9632165e54632f6d57a39c5f948c4bab10e0e066525e9a4b87a79f0d04fbca374 - languageName: node - linkType: hard - "webidl-conversions@npm:^5.0.0": version: 5.0.0 resolution: "webidl-conversions@npm:5.0.0" @@ -21730,81 +20550,94 @@ __metadata: languageName: node linkType: hard -"webpack-dev-middleware@npm:^5.3.4": - version: 5.3.4 - resolution: "webpack-dev-middleware@npm:5.3.4" +"webpack-dev-middleware@npm:^3.7.2": + version: 3.7.3 + resolution: "webpack-dev-middleware@npm:3.7.3" dependencies: - colorette: ^2.0.10 - memfs: ^3.4.3 - mime-types: ^2.1.31 + memory-fs: ^0.4.1 + mime: ^2.4.4 + mkdirp: ^0.5.1 range-parser: ^1.2.1 - schema-utils: ^4.0.0 + webpack-log: ^2.0.0 peerDependencies: webpack: ^4.0.0 || ^5.0.0 - checksum: 90cf3e27d0714c1a745454a1794f491b7076434939340605b9ee8718ba2b85385b120939754e9fdbd6569811e749dee53eec319e0d600e70e0b0baffd8e3fb13 + checksum: faa3cdd7b82d23c35b8f45903556eadd92b0795c76f3e08e234d53f7bab3de13331096a71968e7e9905770ae5de7a4f75ddf09f66d1e0bbabfecbb30db0f71e3 languageName: node linkType: hard -"webpack-dev-server@npm:^4.6.0": - version: 4.15.2 - resolution: "webpack-dev-server@npm:4.15.2" +"webpack-dev-server@npm:3.11.1": + version: 3.11.1 + resolution: "webpack-dev-server@npm:3.11.1" dependencies: - "@types/bonjour": ^3.5.9 - "@types/connect-history-api-fallback": ^1.3.5 - "@types/express": ^4.17.13 - "@types/serve-index": ^1.9.1 - "@types/serve-static": ^1.13.10 - "@types/sockjs": ^0.3.33 - "@types/ws": ^8.5.5 - ansi-html-community: ^0.0.8 - bonjour-service: ^1.0.11 - chokidar: ^3.5.3 - colorette: ^2.0.10 + ansi-html: 0.0.7 + bonjour: ^3.5.0 + chokidar: ^2.1.8 compression: ^1.7.4 - connect-history-api-fallback: ^2.0.0 - default-gateway: ^6.0.3 - express: ^4.17.3 - graceful-fs: ^4.2.6 - html-entities: ^2.3.2 - http-proxy-middleware: ^2.0.3 - ipaddr.js: ^2.0.1 - launch-editor: ^2.6.0 - open: ^8.0.9 - p-retry: ^4.5.0 - rimraf: ^3.0.2 - schema-utils: ^4.0.0 - selfsigned: ^2.1.1 + connect-history-api-fallback: ^1.6.0 + debug: ^4.1.1 + del: ^4.1.1 + express: ^4.17.1 + html-entities: ^1.3.1 + http-proxy-middleware: 0.19.1 + import-local: ^2.0.0 + internal-ip: ^4.3.0 + ip: ^1.1.5 + is-absolute-url: ^3.0.3 + killable: ^1.0.1 + loglevel: ^1.6.8 + opn: ^5.5.0 + p-retry: ^3.0.1 + portfinder: ^1.0.26 + schema-utils: ^1.0.0 + selfsigned: ^1.10.8 + semver: ^6.3.0 serve-index: ^1.9.1 - sockjs: ^0.3.24 + sockjs: ^0.3.21 + sockjs-client: ^1.5.0 spdy: ^4.0.2 - webpack-dev-middleware: ^5.3.4 - ws: ^8.13.0 + strip-ansi: ^3.0.1 + supports-color: ^6.1.0 + url: ^0.11.0 + webpack-dev-middleware: ^3.7.2 + webpack-log: ^2.0.0 + ws: ^6.2.1 + yargs: ^13.3.2 peerDependencies: - webpack: ^4.37.0 || ^5.0.0 + webpack: ^4.0.0 || ^5.0.0 peerDependenciesMeta: - webpack: - optional: true webpack-cli: optional: true bin: webpack-dev-server: bin/webpack-dev-server.js - checksum: 123507129cb4d55fdc5fabdd177574f31133605748372bb11353307b7a583ef25c6fd27b6addf56bf070ba44c88d5da861771c2ec55f52405082ec9efd01f039 + checksum: 6c6e6b6c207c192585f9943fc9945058832a39a12bbf0368798d73a96264b813ab816cb14985c1ca3c90cc567f59fcad6f2fada8f30f2f0136904cfaf43eb87d languageName: node linkType: hard -"webpack-manifest-plugin@npm:^4.0.2": - version: 4.1.1 - resolution: "webpack-manifest-plugin@npm:4.1.1" +"webpack-log@npm:^2.0.0": + version: 2.0.0 + resolution: "webpack-log@npm:2.0.0" + dependencies: + ansi-colors: ^3.0.0 + uuid: ^3.3.2 + checksum: 4757179310995e20633ec2d77a8c1ac11e4135c84745f57148692f8195f1c0f8ec122c77d0dc16fc484b7d301df6674f36c9fc6b1ff06b5cf142abaaf5d24f4f + languageName: node + linkType: hard + +"webpack-manifest-plugin@npm:2.2.0": + version: 2.2.0 + resolution: "webpack-manifest-plugin@npm:2.2.0" dependencies: - tapable: ^2.0.0 - webpack-sources: ^2.2.0 + fs-extra: ^7.0.0 + lodash: ">=3.5 <5" + object.entries: ^1.1.0 + tapable: ^1.0.0 peerDependencies: - webpack: ^4.44.2 || ^5.47.0 - checksum: 426982030d3b0ef26432d98960ee1fa33889d8f0ed79b3d2c8e37be9b4e4beba7524c60631297ea557c642a340b76d70b0eb6a1e08b86a769409037185795038 + webpack: 2 || 3 || 4 + checksum: ed1387774031a59bc1bd5f79150e7a49dcf5048a6d5e9652672637bed7f93df6220cbd88b2e371e7c8c8e7640b3a8ed6895f771c6b05a8bb90b721f82001ac25 languageName: node linkType: hard -"webpack-sources@npm:^1.4.3": +"webpack-sources@npm:^1.1.0, webpack-sources@npm:^1.3.0, webpack-sources@npm:^1.4.0, webpack-sources@npm:^1.4.1, webpack-sources@npm:^1.4.3": version: 1.4.3 resolution: "webpack-sources@npm:1.4.3" dependencies: @@ -21814,58 +20647,41 @@ __metadata: languageName: node linkType: hard -"webpack-sources@npm:^2.2.0": - version: 2.3.1 - resolution: "webpack-sources@npm:2.3.1" - dependencies: - source-list-map: ^2.0.1 - source-map: ^0.6.1 - checksum: 6fd67f2274a84c5f51ad89767112ec8b47727134bf0f2ba0cff458c970f18966939a24128bdbddba621cd66eeb2bef0552642a9333cd8e54514f7b2a71776346 - languageName: node - linkType: hard - -"webpack-sources@npm:^3.3.3": - version: 3.3.3 - resolution: "webpack-sources@npm:3.3.3" - checksum: 243d438ec4dfe805cca20fa66d111114b1f277b8ecfa95bb6ee0a6c7d996aee682539952028c2b203a6c170e6ef56f71ecf3e366e90bf1cb58b0ae982176b651 - languageName: node - linkType: hard - -"webpack@npm:^5.64.4": - version: 5.101.3 - resolution: "webpack@npm:5.101.3" +"webpack@npm:4.44.2": + version: 4.44.2 + resolution: "webpack@npm:4.44.2" dependencies: - "@types/eslint-scope": ^3.7.7 - "@types/estree": ^1.0.8 - "@types/json-schema": ^7.0.15 - "@webassemblyjs/ast": ^1.14.1 - "@webassemblyjs/wasm-edit": ^1.14.1 - "@webassemblyjs/wasm-parser": ^1.14.1 - acorn: ^8.15.0 - acorn-import-phases: ^1.0.3 - browserslist: ^4.24.0 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-module-context": 1.9.0 + "@webassemblyjs/wasm-edit": 1.9.0 + "@webassemblyjs/wasm-parser": 1.9.0 + acorn: ^6.4.1 + ajv: ^6.10.2 + ajv-keywords: ^3.4.1 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.17.3 - 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: ^4.3.2 - tapable: ^2.1.1 - terser-webpack-plugin: ^5.3.11 - watchpack: ^2.4.1 - webpack-sources: ^3.3.3 + enhanced-resolve: ^4.3.0 + eslint-scope: ^4.0.3 + json-parse-better-errors: ^1.0.2 + loader-runner: ^2.4.0 + loader-utils: ^1.2.3 + memory-fs: ^0.4.1 + micromatch: ^3.1.10 + mkdirp: ^0.5.3 + neo-async: ^2.6.1 + node-libs-browser: ^2.2.1 + schema-utils: ^1.0.0 + tapable: ^1.1.3 + terser-webpack-plugin: ^1.4.3 + watchpack: ^1.7.4 + webpack-sources: ^1.4.1 peerDependenciesMeta: webpack-cli: optional: true + webpack-command: + optional: true bin: webpack: bin/webpack.js - checksum: d23fd86b6bc9854f9b488830d9aa123a7f654ee22849bc8670d0a22add88951f6d9cab1d04087758b642fc31115e3b97e0ac56b80b2200c04c486067aa945663 + checksum: 3d42ee6af7a0ff14fc00136d02f4a36381fd5b6ad0636b95a8b83e6d99bc7e02f888f4994c095ae986e567033fe7bb1d445e27afe49d2872b8fe5c3a57d20de6 languageName: node linkType: hard @@ -21896,7 +20712,7 @@ __metadata: languageName: node linkType: hard -"whatwg-fetch@npm:^3.6.2": +"whatwg-fetch@npm:^3.4.1": version: 3.6.20 resolution: "whatwg-fetch@npm:3.6.20" checksum: c58851ea2c4efe5c2235f13450f426824cf0253c1d45da28f45900290ae602a20aff2ab43346f16ec58917d5562e159cd691efa368354b2e82918c2146a519c5 @@ -21920,17 +20736,6 @@ __metadata: languageName: node linkType: hard -"whatwg-url@npm:^7.0.0": - version: 7.1.0 - resolution: "whatwg-url@npm:7.1.0" - dependencies: - lodash.sortby: ^4.7.0 - tr46: ^1.0.1 - webidl-conversions: ^4.0.2 - checksum: fecb07c87290b47d2ec2fb6d6ca26daad3c9e211e0e531dd7566e7ff95b5b3525a57d4f32640ad4adf057717e0c215731db842ad761e61d947e81010e05cf5fd - languageName: node - linkType: hard - "whatwg-url@npm:^8.0.0, whatwg-url@npm:^8.5.0": version: 8.7.0 resolution: "whatwg-url@npm:8.7.0" @@ -21942,41 +20747,40 @@ __metadata: languageName: node linkType: hard -"which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1": - version: 1.1.1 - resolution: "which-boxed-primitive@npm:1.1.1" +"which-boxed-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "which-boxed-primitive@npm:1.0.2" dependencies: - is-bigint: ^1.1.0 - is-boolean-object: ^1.2.1 - is-number-object: ^1.1.1 - is-string: ^1.1.1 - is-symbol: ^1.1.1 - checksum: ee41d0260e4fd39551ad77700c7047d3d281ec03d356f5e5c8393fe160ba0db53ef446ff547d05f76ffabfd8ad9df7c9a827e12d4cccdbc8fccf9239ff8ac21e + is-bigint: ^1.0.1 + is-boolean-object: ^1.1.0 + is-number-object: ^1.0.4 + is-string: ^1.0.5 + is-symbol: ^1.0.3 + checksum: 53ce774c7379071729533922adcca47220228405e1895f26673bbd71bdf7fb09bee38c1d6399395927c6289476b5ae0629863427fd151491b71c4b6cb04f3a5e languageName: node linkType: hard -"which-builtin-type@npm:^1.2.1": - version: 1.2.1 - resolution: "which-builtin-type@npm:1.2.1" +"which-builtin-type@npm:^1.1.3": + version: 1.1.3 + resolution: "which-builtin-type@npm:1.1.3" dependencies: - call-bound: ^1.0.2 - function.prototype.name: ^1.1.6 - has-tostringtag: ^1.0.2 + function.prototype.name: ^1.1.5 + has-tostringtag: ^1.0.0 is-async-function: ^2.0.0 - is-date-object: ^1.1.0 - is-finalizationregistry: ^1.1.0 + is-date-object: ^1.0.5 + is-finalizationregistry: ^1.0.2 is-generator-function: ^1.0.10 - is-regex: ^1.2.1 + is-regex: ^1.1.4 is-weakref: ^1.0.2 isarray: ^2.0.5 - which-boxed-primitive: ^1.1.0 - which-collection: ^1.0.2 - which-typed-array: ^1.1.16 - checksum: 7a3617ba0e7cafb795f74db418df889867d12bce39a477f3ee29c6092aa64d396955bf2a64eae3726d8578440e26777695544057b373c45a8bcf5fbe920bf633 + which-boxed-primitive: ^1.0.2 + which-collection: ^1.0.1 + which-typed-array: ^1.1.9 + checksum: 43730f7d8660ff9e33d1d3f9f9451c4784265ee7bf222babc35e61674a11a08e1c2925019d6c03154fcaaca4541df43abe35d2720843b9b4cbcebdcc31408f36 languageName: node linkType: hard -"which-collection@npm:^1.0.2": +"which-collection@npm:^1.0.1": version: 1.0.2 resolution: "which-collection@npm:1.0.2" dependencies: @@ -21995,22 +20799,20 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19": - version: 1.1.19 - resolution: "which-typed-array@npm:1.1.19" +"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": + version: 1.1.15 + resolution: "which-typed-array@npm:1.1.15" dependencies: available-typed-arrays: ^1.0.7 - call-bind: ^1.0.8 - call-bound: ^1.0.4 - for-each: ^0.3.5 - get-proto: ^1.0.1 - gopd: ^1.2.0 + call-bind: ^1.0.7 + for-each: ^0.3.3 + gopd: ^1.0.1 has-tostringtag: ^1.0.2 - checksum: 162d2a07f68ea323f88ed9419861487ce5d02cb876f2cf9dd1e428d04a63133f93a54f89308f337b27cabd312ee3d027cae4a79002b2f0a85b79b9ef4c190670 + checksum: 65227dcbfadf5677aacc43ec84356d17b5500cb8b8753059bb4397de5cd0c2de681d24e1a7bd575633f976a95f88233abfd6549c2105ef4ebd58af8aa1807c75 languageName: node linkType: hard -"which@npm:^1.3.1": +"which@npm:^1.2.9, which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" dependencies: @@ -22021,7 +20823,7 @@ __metadata: languageName: node linkType: hard -"which@npm:^2.0.1": +"which@npm:^2.0.1, which@npm:^2.0.2": version: 2.0.2 resolution: "which@npm:2.0.2" dependencies: @@ -22032,238 +20834,238 @@ __metadata: languageName: node linkType: hard -"which@npm:^5.0.0": - version: 5.0.0 - resolution: "which@npm:5.0.0" +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" dependencies: isexe: ^3.1.1 bin: node-which: bin/which.js - checksum: 6ec99e89ba32c7e748b8a3144e64bfc74aa63e2b2eacbb61a0060ad0b961eb1a632b08fb1de067ed59b002cec3e21de18299216ebf2325ef0f78e0f121e14e90 + checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 languageName: node linkType: hard -"why-is-node-running@npm:^2.3.0": - version: 2.3.0 - resolution: "why-is-node-running@npm:2.3.0" +"why-is-node-running@npm:^2.2.2": + version: 2.2.2 + resolution: "why-is-node-running@npm:2.2.2" dependencies: siginfo: ^2.0.0 stackback: 0.0.2 bin: why-is-node-running: cli.js - checksum: 58ebbf406e243ace97083027f0df7ff4c2108baf2595bb29317718ef207cc7a8104e41b711ff65d6fa354f25daa8756b67f2f04931a4fd6ba9d13ae8197496fb + checksum: 50820428f6a82dfc3cbce661570bcae9b658723217359b6037b67e495255409b4c8bc7931745f5c175df71210450464517cab32b2f7458ac9c40b4925065200a languageName: node linkType: hard -"word-wrap@npm:^1.2.5, word-wrap@npm:~1.2.3": +"word-wrap@npm:~1.2.3": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" checksum: f93ba3586fc181f94afdaff3a6fef27920b4b6d9eaefed0f428f8e07adea2a7f54a5f2830ce59406c8416f033f86902b91eb824072354645eea687dff3691ccb languageName: node linkType: hard -"workbox-background-sync@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-background-sync@npm:6.6.0" +"workbox-background-sync@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-background-sync@npm:5.1.4" dependencies: - idb: ^7.0.1 - workbox-core: 6.6.0 - checksum: ac2990110643aef62ca0be54e962296de7b09593b0262bd09fe4893978a42fa1f256c6d989ed472a31ae500b2255b80c6678530a6024eafb0b2f3a93a3c94a5f + workbox-core: ^5.1.4 + checksum: 14655d0254813d2580935c88fe4768eb4794158a3c0700505aa06784dcd8d7498563e8b55152f0a4afb609163e76787a3a3eb61813b810bd76830c866d6ceb9e languageName: node linkType: hard -"workbox-broadcast-update@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-broadcast-update@npm:6.6.0" +"workbox-broadcast-update@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-broadcast-update@npm:5.1.4" dependencies: - workbox-core: 6.6.0 - checksum: 46a74b3b703244eb363e1731a2d6fe1fb2cd9b82d454733dfc6941fd35b76a852685f56db92408383ac50d564c2fd4282f0c6c4db60ba9beb5f311ea8f944dc7 + workbox-core: ^5.1.4 + checksum: b56df2fde652c2efa8afbb8880562aaac6932be313ddcbbb688bb48beeb3164c928a644407f359168789a31592c765f63526608afe6cd803ac89402f786064d1 languageName: node linkType: hard -"workbox-build@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-build@npm:6.6.0" - dependencies: - "@apideck/better-ajv-errors": ^0.3.1 - "@babel/core": ^7.11.1 - "@babel/preset-env": ^7.11.0 - "@babel/runtime": ^7.11.2 - "@rollup/plugin-babel": ^5.2.0 - "@rollup/plugin-node-resolve": ^11.2.1 - "@rollup/plugin-replace": ^2.4.1 - "@surma/rollup-plugin-off-main-thread": ^2.2.3 - ajv: ^8.6.0 +"workbox-build@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-build@npm:5.1.4" + dependencies: + "@babel/core": ^7.8.4 + "@babel/preset-env": ^7.8.4 + "@babel/runtime": ^7.8.4 + "@hapi/joi": ^15.1.0 + "@rollup/plugin-node-resolve": ^7.1.1 + "@rollup/plugin-replace": ^2.3.1 + "@surma/rollup-plugin-off-main-thread": ^1.1.1 common-tags: ^1.8.0 fast-json-stable-stringify: ^2.1.0 - fs-extra: ^9.0.1 + fs-extra: ^8.1.0 glob: ^7.1.6 - lodash: ^4.17.20 + lodash.template: ^4.5.0 pretty-bytes: ^5.3.0 - rollup: ^2.43.1 - rollup-plugin-terser: ^7.0.0 - source-map: ^0.8.0-beta.0 + rollup: ^1.31.1 + rollup-plugin-babel: ^4.3.3 + rollup-plugin-terser: ^5.3.1 + source-map: ^0.7.3 + source-map-url: ^0.4.0 stringify-object: ^3.3.0 - strip-comments: ^2.0.1 - tempy: ^0.6.0 + strip-comments: ^1.0.2 + tempy: ^0.3.0 upath: ^1.2.0 - workbox-background-sync: 6.6.0 - workbox-broadcast-update: 6.6.0 - workbox-cacheable-response: 6.6.0 - workbox-core: 6.6.0 - workbox-expiration: 6.6.0 - workbox-google-analytics: 6.6.0 - workbox-navigation-preload: 6.6.0 - workbox-precaching: 6.6.0 - workbox-range-requests: 6.6.0 - workbox-recipes: 6.6.0 - workbox-routing: 6.6.0 - workbox-strategies: 6.6.0 - workbox-streams: 6.6.0 - workbox-sw: 6.6.0 - workbox-window: 6.6.0 - checksum: cd1a6c413659c2fd66f4438012f65b211cc748bb594c79bf0d9a60de0cefff3f8a4a23ab06f32c62064c37397ffffc1b77d3328658b7556ea7ff88e57f6ee4fd - languageName: node - linkType: hard - -"workbox-cacheable-response@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-cacheable-response@npm:6.6.0" + workbox-background-sync: ^5.1.4 + workbox-broadcast-update: ^5.1.4 + workbox-cacheable-response: ^5.1.4 + workbox-core: ^5.1.4 + workbox-expiration: ^5.1.4 + workbox-google-analytics: ^5.1.4 + workbox-navigation-preload: ^5.1.4 + workbox-precaching: ^5.1.4 + workbox-range-requests: ^5.1.4 + workbox-routing: ^5.1.4 + workbox-strategies: ^5.1.4 + workbox-streams: ^5.1.4 + workbox-sw: ^5.1.4 + workbox-window: ^5.1.4 + checksum: 873833d0ea5c39c3f9adae9b2cd8ff33c013ff57f189dbec94d4d02917281495f38bbfa508d24425176ea8d31d6a27590658c83c30d44d9d5a9f4eb4d0798694 + languageName: node + linkType: hard + +"workbox-cacheable-response@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-cacheable-response@npm:5.1.4" dependencies: - workbox-core: 6.6.0 - checksum: 9e4e00c53679fd2020874cbdf54bb17560fd12353120ea08ca6213e5a11bf08139072616d79f5f8ab80d09f00efde94b003fe9bf5b6e23815be30d7aca760835 + workbox-core: ^5.1.4 + checksum: 3d8940dbee11880fdd86d76f85c063cf0a42d722be828332acf2f69ff5eaaedc8a0d779e44175adba4e8485f98392052539b2126df79125cebcec57dea0bee3c languageName: node linkType: hard -"workbox-core@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-core@npm:6.6.0" - checksum: 7d773a866b73a733780c52b895f9cf7bec926c9187395c307174deefba9a0a2fcd1edce0d1ca12b8a6c95ca9cf7755ccc1885b03bc82ebcfc4843e015bd84d7b +"workbox-core@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-core@npm:5.1.4" + checksum: 6062bc3131bb7fcf1922be619cbc28ba528b033ba18acced5e42eb62b6c0a763814e905106c081c1c100a5d520ef104957e99e592e5e954767df76db49a7c874 languageName: node linkType: hard -"workbox-expiration@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-expiration@npm:6.6.0" +"workbox-expiration@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-expiration@npm:5.1.4" dependencies: - idb: ^7.0.1 - workbox-core: 6.6.0 - checksum: b100b9c512754bc3e1a9c7c7d20d215d72c601a7b956333ca7753704a771a9f00e1732e9b774da4549bae390dd3cd138c6392f6a25fd67f7dcd84f89b0df7e9c + workbox-core: ^5.1.4 + checksum: c4648a008d19ee1281d5d588e10f14bd01530d8601c6ebf27e63b109663530fd381709539f1dd8a32e75d68a04e40e5f31ec6fbcc9ea052ee39000a2d76ade50 languageName: node linkType: hard -"workbox-google-analytics@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-google-analytics@npm:6.6.0" +"workbox-google-analytics@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-google-analytics@npm:5.1.4" dependencies: - workbox-background-sync: 6.6.0 - workbox-core: 6.6.0 - workbox-routing: 6.6.0 - workbox-strategies: 6.6.0 - checksum: 7b287da7517ae416aae8ea1494830bb517a29ab9786b2a8b8bf98971377b83715070e784399065ab101d4bba381ab0abbb8bd0962b3010bc01f54fdafb0b6702 + workbox-background-sync: ^5.1.4 + workbox-core: ^5.1.4 + workbox-routing: ^5.1.4 + workbox-strategies: ^5.1.4 + checksum: 2783e93f8a5aeccc038f51a9960c05aebd104fd8d113b5fd78a09bac2da8ed8e2be4c9fd7d8a6751682301d6b5e36ba055240a74a3591b4e887aabb2784cd531 languageName: node linkType: hard -"workbox-navigation-preload@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-navigation-preload@npm:6.6.0" +"workbox-navigation-preload@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-navigation-preload@npm:5.1.4" dependencies: - workbox-core: 6.6.0 - checksum: d254465648e45ec6b6d7c3471354336501901d3872622ea9ba1aa1f935d4d52941d0f92fa6c06e7363e10dbac4874d5d4bff7d99cbe094925046f562a37e88cc + workbox-core: ^5.1.4 + checksum: ed6b19f063f17e2dd12ef08594ea338fcf96d994ea8f7d9b2987099cb08a890c73f139a23b68c9c5523308fba4634f24aca079deb7d00684c8d76fdfb07b0fc9 languageName: node linkType: hard -"workbox-precaching@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-precaching@npm:6.6.0" +"workbox-precaching@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-precaching@npm:5.1.4" dependencies: - workbox-core: 6.6.0 - workbox-routing: 6.6.0 - workbox-strategies: 6.6.0 - checksum: 62e5ee2e40568a56d4131bba461623579f56b9bd273aa7d2805e43151057f413c2ef32fb3d007aff0a5ac3ad84d5feae87408284249a487a5d51c3775c46c816 + workbox-core: ^5.1.4 + checksum: 5593c5b9c3c928bb5d3b4c998625be610d05a3b55523e5abb0fc5f12ff2e32412114e933e60d54ba9e2661fa3cbbbab7e11f91c7170742cfe9525437d1c44ae8 languageName: node linkType: hard -"workbox-range-requests@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-range-requests@npm:6.6.0" +"workbox-range-requests@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-range-requests@npm:5.1.4" dependencies: - workbox-core: 6.6.0 - checksum: a55d1a364b2155548695dc8f6f85baade196d7d1bec980bcdbda80236803b14167995a81b944cffe932a94c4d556466773121afe3661a6f0a13403cbe96d8d9f + workbox-core: ^5.1.4 + checksum: c67b467023e85a45599c411079907585c4d4b7aab77205dd905cd0d8b1487aa248469bc2f89045e8bd4a08eed4ede14795fc9089d01beff65ff3c6f2f1deff45 languageName: node linkType: hard -"workbox-recipes@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-recipes@npm:6.6.0" +"workbox-routing@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-routing@npm:5.1.4" dependencies: - workbox-cacheable-response: 6.6.0 - workbox-core: 6.6.0 - workbox-expiration: 6.6.0 - workbox-precaching: 6.6.0 - workbox-routing: 6.6.0 - workbox-strategies: 6.6.0 - checksum: f2ecf38502260703e4b0dcef67e3ac26d615f2c90f6d863ca7308db52454f67934ba842fd577ee807d9f510f1a277fd66af7caf57d39e50a181d05dbb3e550a7 + workbox-core: ^5.1.4 + checksum: 4199a02b433eb645dfcaf2a5056a04d79f337b6f368b1ab5aa18262857835d4b995536062c294d6f4db6da236235b5736af4b29d0ea1b0c3f0db339b04d3cd40 languageName: node linkType: hard -"workbox-routing@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-routing@npm:6.6.0" +"workbox-strategies@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-strategies@npm:5.1.4" dependencies: - workbox-core: 6.6.0 - checksum: 7a70b836196eb67332d33a94c0b57859781fe869e81a9c95452d3f4f368d3199f8c3da632dbc10425fde902a1930cf8cfd83f6434ad2b586904ce68cd9f35c6d + workbox-core: ^5.1.4 + workbox-routing: ^5.1.4 + checksum: 6ed247bfc0037331043cd0e772c6fd8d48e487875fac75d6692eb3936536ca2d4ac5ac9d12ec9b0ad5eefd4a69afd1ad2a993829ce3a373390880a019fd33d3d languageName: node linkType: hard -"workbox-strategies@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-strategies@npm:6.6.0" +"workbox-streams@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-streams@npm:5.1.4" dependencies: - workbox-core: 6.6.0 - checksum: 236232a77fb4a4847d1e9ae6c7c9bd9c6b9449209baab9d8d90f78240326a9c0f69551b408ebf9e76610d86da15563bf27439b7e885a7bac01dfd08047c0dd7b + workbox-core: ^5.1.4 + workbox-routing: ^5.1.4 + checksum: daaedb22dae6eb4723e7a21d758854adb36b75f1fa2453a914b6768628d91555e3db76fccb70a101f5cf1a39056e783eab1c8b0f4a59649f7ef4fad173c6f7d3 languageName: node linkType: hard -"workbox-streams@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-streams@npm:6.6.0" +"workbox-sw@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-sw@npm:5.1.4" + checksum: eda970f62c26715b806828cab3000240843bab2e6577c341ccd30747a77a60d23f4f08d8d85fba680bfefa95c673c4d48a62a969a2540916dcf6506c627c69cc + languageName: node + linkType: hard + +"workbox-webpack-plugin@npm:5.1.4": + version: 5.1.4 + resolution: "workbox-webpack-plugin@npm:5.1.4" dependencies: - workbox-core: 6.6.0 - workbox-routing: 6.6.0 - checksum: 64a295e48e44e3fa4743b5baec646fc9117428e7592033475e38c461e45c294910712f322c32417d354b22999902ef8035119e070e61e159e531d878d991fc33 + "@babel/runtime": ^7.5.5 + fast-json-stable-stringify: ^2.0.0 + source-map-url: ^0.4.0 + upath: ^1.1.2 + webpack-sources: ^1.3.0 + workbox-build: ^5.1.4 + peerDependencies: + webpack: ^4.0.0 + checksum: 7a9093d4ccfedc27ee6716443bcb7ce12d1f92831f48d09e6cf829a62d2ba7948a84ed38964923136d6b296e8f60bda359645a82c5a19e2c5a8e8aab6dae0a55 languageName: node linkType: hard -"workbox-sw@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-sw@npm:6.6.0" - checksum: bb5f8695de02f89c7955465dcbd568299915565008dc8a068c5d19c1347f75d417640b9f61590e16b169b703e77d02f8b1e10c4b241f74f43cfe76175bfa5fed +"workbox-window@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-window@npm:5.1.4" + dependencies: + workbox-core: ^5.1.4 + checksum: bd5bc967ea1202c555db4360892518f5479027d05e4bd02fd38ebef3faf6605ee7e3887225e0920624cd2685e5217c3c4bd43a7d458860d186400c12f410df5b languageName: node linkType: hard -"workbox-webpack-plugin@npm:^6.4.1": - version: 6.6.0 - resolution: "workbox-webpack-plugin@npm:6.6.0" +"worker-farm@npm:^1.7.0": + version: 1.7.0 + resolution: "worker-farm@npm:1.7.0" dependencies: - fast-json-stable-stringify: ^2.1.0 - pretty-bytes: ^5.4.1 - upath: ^1.2.0 - webpack-sources: ^1.4.3 - workbox-build: 6.6.0 - peerDependencies: - webpack: ^4.4.0 || ^5.9.0 - checksum: b8e04a342f2d45086f28ae56e4806d74dd153c3b750855533a55954f4e85752113e76a6d79a32206eb697a342725897834c9e7976894374d8698cd950477d37a + errno: ~0.1.7 + checksum: eab917530e1feddf157ec749e9c91b73a886142daa7fdf3490bccbf7b548b2576c43ab8d0a98e72ac755cbc101ca8647a7b1ff2485fddb9e8f53c40c77f5a719 languageName: node linkType: hard -"workbox-window@npm:6.6.0": - version: 6.6.0 - resolution: "workbox-window@npm:6.6.0" +"worker-rpc@npm:^0.1.0": + version: 0.1.1 + resolution: "worker-rpc@npm:0.1.1" dependencies: - "@types/trusted-types": ^2.0.2 - workbox-core: 6.6.0 - checksum: bb1dd031c1525317ceffbdc3e4f502a70dce461fd6355146e1050c1090f3c640bf65edf42a5d2a3b91b4d0c313df32c1405d88bf701d44c0e3ebc492cd77fe14 + microevent.ts: ~0.1.1 + checksum: 8f8607506172f44c05490f3ccf13e5c1f430eeb9b6116a405919c186b8b17add13bbb22467a0dbcd18ec7fcb080709a15738182e0003c5fbe2144721ea00f357 languageName: node linkType: hard @@ -22278,7 +21080,18 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^6.2.0": +"wrap-ansi@npm:^5.1.0": + version: 5.1.0 + resolution: "wrap-ansi@npm:5.1.0" + dependencies: + ansi-styles: ^3.2.0 + string-width: ^3.0.0 + strip-ansi: ^5.0.0 + checksum: 9b48c862220e541eb0daa22661b38b947973fc57054e91be5b0f2dcc77741a6875ccab4ebe970a394b4682c8dfc17e888266a105fb8b0a9b23c19245e781ceae + languageName: node + linkType: hard + +"wrap-ansi@npm:^6.0.1, wrap-ansi@npm:^6.2.0": version: 6.2.0 resolution: "wrap-ansi@npm:6.2.0" dependencies: @@ -22319,33 +21132,27 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.4.6": - version: 7.5.10 - resolution: "ws@npm:7.5.10" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: f9bb062abf54cc8f02d94ca86dcd349c3945d63851f5d07a3a61c2fcb755b15a88e943a63cf580cbdb5b74436d67ef6b67f745b8f7c0814e411379138e1863cb +"ws@npm:^6.2.1": + version: 6.2.2 + resolution: "ws@npm:6.2.2" + dependencies: + async-limiter: ~1.0.0 + checksum: aec3154ec51477c094ac2cb5946a156e17561a581fa27005cbf22c53ac57f8d4e5f791dd4bbba6a488602cb28778c8ab7df06251d590507c3c550fd8ebeee949 languageName: node linkType: hard -"ws@npm:^8.13.0": - version: 8.18.3 - resolution: "ws@npm:8.18.3" +"ws@npm:^7.4.6": + version: 7.5.9 + resolution: "ws@npm:7.5.9" peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" + utf-8-validate: ^5.0.2 peerDependenciesMeta: bufferutil: optional: true utf-8-validate: optional: true - checksum: d64ef1631227bd0c5fe21b3eb3646c9c91229402fb963d12d87b49af0a1ef757277083af23a5f85742bae1e520feddfb434cb882ea59249b15673c16dc3f36e0 + checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 languageName: node linkType: hard @@ -22363,7 +21170,7 @@ __metadata: languageName: node linkType: hard -"xtend@npm:^4.0.0": +"xtend@npm:^4.0.0, xtend@npm:~4.0.1": version: 4.0.2 resolution: "xtend@npm:4.0.2" checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a @@ -22398,26 +21205,27 @@ __metadata: languageName: node linkType: hard -"yallist@npm:^5.0.0": - version: 5.0.0 - resolution: "yallist@npm:5.0.0" - checksum: eba51182400b9f35b017daa7f419f434424410691bbc5de4f4240cc830fdef906b504424992700dc047f16b4d99100a6f8b8b11175c193f38008e9c96322b6a5 - languageName: node - linkType: hard - -"yaml@npm:^1.10.0, yaml@npm:^1.10.2, yaml@npm:^1.7.2": +"yaml@npm:^1.10.0": version: 1.10.2 resolution: "yaml@npm:1.10.2" checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f languageName: node linkType: hard -"yaml@npm:^2.3.4": - version: 2.8.1 - resolution: "yaml@npm:2.8.1" - bin: - yaml: bin.mjs - checksum: 35b46150d48bc1da2fd5b1521a48a4fa36d68deaabe496f3c3fa9646d5796b6b974f3930a02c4b5aee6c85c860d7d7f79009416724465e835f40b87898c36de4 +"yargs-parser@npm:20.x": + version: 20.2.9 + resolution: "yargs-parser@npm:20.2.9" + checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 + languageName: node + linkType: hard + +"yargs-parser@npm:^13.1.2": + version: 13.1.2 + resolution: "yargs-parser@npm:13.1.2" + dependencies: + camelcase: ^5.0.0 + decamelize: ^1.2.0 + checksum: c8bb6f44d39a4acd94462e96d4e85469df865de6f4326e0ab1ac23ae4a835e5dd2ddfe588317ebf80c3a7e37e741bd5cb0dc8d92bcc5812baefb7df7c885e86b languageName: node linkType: hard @@ -22431,13 +21239,6 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^20.2.2": - version: 20.2.9 - resolution: "yargs-parser@npm:20.2.9" - checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 - languageName: node - linkType: hard - "yargs-parser@npm:^21.1.1": version: 21.1.1 resolution: "yargs-parser@npm:21.1.1" @@ -22445,22 +21246,25 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.7.2, yargs@npm:^17.3.1, yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" +"yargs@npm:^13.3.0, yargs@npm:^13.3.2": + version: 13.3.2 + resolution: "yargs@npm:13.3.2" dependencies: - cliui: ^8.0.1 - escalade: ^3.1.1 - get-caller-file: ^2.0.5 + cliui: ^5.0.0 + find-up: ^3.0.0 + get-caller-file: ^2.0.1 require-directory: ^2.1.1 - string-width: ^4.2.3 - y18n: ^5.0.5 - yargs-parser: ^21.1.1 - checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + require-main-filename: ^2.0.0 + set-blocking: ^2.0.0 + string-width: ^3.0.0 + which-module: ^2.0.0 + y18n: ^4.0.0 + yargs-parser: ^13.1.2 + checksum: 75c13e837eb2bb25717957ba58d277e864efc0cca7f945c98bdf6477e6ec2f9be6afa9ed8a876b251a21423500c148d7b91e88dee7adea6029bdec97af1ef3e8 languageName: node linkType: hard -"yargs@npm:^15.3.1": +"yargs@npm:^15.4.1": version: 15.4.1 resolution: "yargs@npm:15.4.1" dependencies: @@ -22479,18 +21283,18 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^16.2.0": - version: 16.2.0 - resolution: "yargs@npm:16.2.0" +"yargs@npm:^17.3.1": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" dependencies: - cliui: ^7.0.2 + cliui: ^8.0.1 escalade: ^3.1.1 get-caller-file: ^2.0.5 require-directory: ^2.1.1 - string-width: ^4.2.0 + string-width: ^4.2.3 y18n: ^5.0.5 - yargs-parser: ^20.2.2 - checksum: b14afbb51e3251a204d81937c86a7e9d4bdbf9a2bcee38226c900d00f522969ab675703bee2a6f99f8e20103f608382936034e64d921b74df82b63c07c5e8f59 + yargs-parser: ^21.1.1 + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a languageName: node linkType: hard @@ -22508,28 +21312,24 @@ __metadata: languageName: node linkType: hard -"yoctocolors-cjs@npm:^2.1.2": - version: 2.1.3 - resolution: "yoctocolors-cjs@npm:2.1.3" - checksum: 207df586996c3b604fa85903f81cc54676f1f372613a0c7247f0d24b1ca781905685075d06955211c4d5d4f629d7d5628464f8af0a42d286b7a8ff88e9dadcb8 +"yocto-queue@npm:^1.0.0": + version: 1.0.0 + resolution: "yocto-queue@npm:1.0.0" + checksum: 2cac84540f65c64ccc1683c267edce396b26b1e931aa429660aefac8fbe0188167b7aee815a3c22fa59a28a58d898d1a2b1825048f834d8d629f4c2a5d443801 languageName: node linkType: hard -"yup@npm:^1.6.1": - version: 1.7.0 - resolution: "yup@npm:1.7.0" +"yup@npm:^0.32.11": + version: 0.32.11 + resolution: "yup@npm:0.32.11" dependencies: - property-expr: ^2.0.5 - tiny-case: ^1.0.3 + "@babel/runtime": ^7.15.4 + "@types/lodash": ^4.14.175 + lodash: ^4.17.21 + lodash-es: ^4.17.21 + nanoclone: ^0.2.1 + property-expr: ^2.0.4 toposort: ^2.0.2 - type-fest: ^2.19.0 - checksum: 845f4bb66df547208c1906a15d03a0cd838789dc22fa9ae948247752f360b273834f7d607176285d8c11779bb143640c65ae5f8f4045351505b17413a183aea9 - languageName: node - linkType: hard - -"zwitch@npm:^2.0.0": - version: 2.0.4 - resolution: "zwitch@npm:2.0.4" - checksum: f22ec5fc2d5f02c423c93d35cdfa83573a3a3bd98c66b927c368ea4d0e7252a500df2a90a6b45522be536a96a73404393c958e945fdba95e6832c200791702b6 + checksum: 43a16786b47cc910fed4891cebdd89df6d6e31702e9462e8f969c73eac88551ce750732608012201ea6b93802c8847cb0aa27b5d57370640f4ecf30f9f97d4b0 languageName: node linkType: hard From b0320aa075098cb477504dc1113aaa94a4d87a19 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 15 Sep 2025 21:50:07 -0400 Subject: [PATCH 039/477] #3565 Added transformers that applies to new machinery model --- .../prisma-query-args/machinery.query-args.ts | 21 ++++++ src/backend/src/services/calendar.services.ts | 3 +- .../src/transformers/calendar.transformer.ts | 27 ++++++++ src/shared/index.ts | 3 +- src/shared/src/types/calendar-types.ts | 65 +++++++++++++++++++ 5 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 src/backend/src/prisma-query-args/machinery.query-args.ts create mode 100644 src/backend/src/transformers/calendar.transformer.ts create mode 100644 src/shared/src/types/calendar-types.ts diff --git a/src/backend/src/prisma-query-args/machinery.query-args.ts b/src/backend/src/prisma-query-args/machinery.query-args.ts new file mode 100644 index 0000000000..991fda3bdf --- /dev/null +++ b/src/backend/src/prisma-query-args/machinery.query-args.ts @@ -0,0 +1,21 @@ +import { Prisma } from '@prisma/client'; + +export type ShopQueryArgs = ReturnType; +export type ShopMachineryQueryArgs = ReturnType; +export type MachineryQueryArgs = ReturnType; + +export const getShopQueryArgs = () => Prisma.validator()({}); + +export const getShopMachineryQueryArgs = () => + Prisma.validator()({ + include: { + shop: getShopQueryArgs() + } + }); + +export const getMachineryQueryArgs = () => + Prisma.validator()({ + include: { + shops: getShopMachineryQueryArgs() + } + }); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index e94589add3..80cbd19a53 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -3,6 +3,7 @@ import { isAdmin } from 'shared'; import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; +import { machineryTransformer } from '../transformers/calendar.transformer'; export default class CalendarService { /** @@ -54,6 +55,6 @@ export default class CalendarService { } }); - return newMachinery; + return machineryTransformer(newMachinery); } } diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts new file mode 100644 index 0000000000..012aff97ff --- /dev/null +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -0,0 +1,27 @@ +import { Prisma } from '@prisma/client'; +import { Machinery, Shop, ShopMachinery } from 'shared'; +import { MachineryQueryArgs, ShopQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; + +export const shopTransformer = (shop: Prisma.ShopGetPayload): Shop => { + return { + name: shop.name, + description: shop.description + }; +}; + +export const shopMachineryTransformer = ( + shopMachinery: Prisma.ShopMachineryGetPayload +): ShopMachinery => { + return { + shop: shopTransformer(shopMachinery.shop), + quantity: shopMachinery.quantity, + description: shopMachinery.description ?? undefined + }; +}; + +export const machineryTransformer = (machinery: Prisma.MachineryGetPayload): Machinery => { + return { + name: machinery.name, + shops: machinery.shops.map(shopMachineryTransformer) + }; +}; diff --git a/src/shared/index.ts b/src/shared/index.ts index 1b96e36456..3f69d7e131 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -19,7 +19,6 @@ export * from './src/types/pop-up-types'; export * from './src/types/announcements.types'; export * from './src/types/part-review.types'; export * from './src/types/finance-types'; - export * from './src/validate-wbs'; export * from './src/date-utils'; @@ -30,4 +29,6 @@ export * from './src/permission-utils'; export * from './src/types/bom-types'; export * from './src/types/statistics-types'; +export * from './src/types/calendar-types'; + export * from './src/utils'; diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts new file mode 100644 index 0000000000..4ca68ccfc9 --- /dev/null +++ b/src/shared/src/types/calendar-types.ts @@ -0,0 +1,65 @@ +import { WorkPackage } from './project-types'; +import { Availability, User } from './user-types'; + +export interface Calendar { + name: string; + description: string; + color: string; + eventTypes: EventType[]; +} + +export enum DayOfWeek { + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY, + SUNDAY +} + +export interface ScheduleSlot { + days: DayOfWeek[]; + startTime?: Date; + endTime?: Date; + recurrenceNumber: number; + initialDateScheduled: Date; + allDay: Boolean; +} + +export interface EventType { + name: string; +} + +export interface Shop { + name: string; + description: string; +} + +export interface ShopMachinery { + shop: Shop; + quantity: number; + description?: string; +} + +export interface Machinery { + name: string; + shops: ShopMachinery[]; +} + +export interface Event { + name: string; + approved: boolean; + eventTypeId: string; + approvedBy?: User; + scheduledTimes?: ScheduleSlot[]; + people?: User[]; + location?: string; + zoomLink?: string; + availability?: Availability[]; + shop?: Shop[]; + machinery?: Machinery[]; + workPackage?: WorkPackage[]; + documentIds?: string[]; + description?: string; +} From 8e2e7ddaf6ac93f6c67cc8ea523c25efbe6a266a Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 15 Sep 2025 21:55:34 -0400 Subject: [PATCH 040/477] #3565 updated machinery test for new returned transformer model --- src/backend/tests/unit/calendar.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index c11923eb2c..c47045f4a9 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -56,8 +56,8 @@ describe('Machinery Tests', () => { expect(result.name).toEqual('Iron Man Mark 42 CNC Mill'); expect(result.shops).toHaveLength(1); expect(result.shops[0].quantity).toBe(2); - expect(result.shops[0].shopId).toBe(shopId); - expect(result.shops[0].description).toBe(null); + expect(result.shops[0].shop.name).toBe('Precision Manufacturing Lab'); + expect(result.shops[0].description).toBe(undefined); }); }); }); From fbf724a62c9813e38fdf2264a76d7ab07e33a34a Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Tue, 16 Sep 2025 09:07:14 -0400 Subject: [PATCH 041/477] new yarn lock fix --- yarn.lock | 22127 +++++++++++++++++++++++++++------------------------- 1 file changed, 11667 insertions(+), 10460 deletions(-) diff --git a/yarn.lock b/yarn.lock index 563831aede..8e4ee5ee83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,36 +5,514 @@ __metadata: version: 6 cacheKey: 8 -"@aashutoshrathi/word-wrap@npm:^1.2.3": - version: 1.2.6 - resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" - checksum: ada901b9e7c680d190f1d012c84217ce0063d8f5c5a7725bb91ec3c5ed99bb7572680eb2d2938a531ccbaec39a95422fcd8a6b4a13110c7d98dd75402f66a0cd +"@adobe/css-tools@npm:^4.4.0": + version: 4.4.4 + resolution: "@adobe/css-tools@npm:4.4.4" + checksum: 452b82cd9f42aacc57eeaf0b11e36c6864eb482e8a347054cb986503d221d1f7c1418710d2007858d8919afdbd31357149c2c16bd080ded15506f13608d16cf2 languageName: node linkType: hard -"@adobe/css-tools@npm:^4.0.1": - version: 4.3.3 - resolution: "@adobe/css-tools@npm:4.3.3" - checksum: d21f3786b84911fee59c995a146644a85c98692979097b26484ffa9e442fb1a92ccd68ce984e3e7cf8d5933c3560fbc0ad3e3cd1de50b9a723d1c012e793bbcb +"@alloc/quick-lru@npm:^5.2.0": + version: 5.2.0 + resolution: "@alloc/quick-lru@npm:5.2.0" + checksum: bdc35758b552bcf045733ac047fb7f9a07c4678b944c641adfbd41f798b4b91fffd0fdc0df2578d9b0afc7b4d636aa6e110ead5d6281a2adc1ab90efd7f057f8 languageName: node linkType: hard -"@ampproject/remapping@npm:^2.2.0": - version: 2.3.0 - resolution: "@ampproject/remapping@npm:2.3.0" +"@apideck/better-ajv-errors@npm:^0.3.1": + version: 0.3.6 + resolution: "@apideck/better-ajv-errors@npm:0.3.6" dependencies: - "@jridgewell/gen-mapping": ^0.3.5 - "@jridgewell/trace-mapping": ^0.3.24 - checksum: d3ad7b89d973df059c4e8e6d7c972cbeb1bb2f18f002a3bd04ae0707da214cb06cc06929b65aa2313b9347463df2914772298bae8b1d7973f246bb3f2ab3e8f0 + json-schema: ^0.4.0 + jsonpointer: ^5.0.0 + leven: ^3.1.0 + peerDependencies: + ajv: ">=8" + checksum: b70ec9aae3b30ba1ac06948e585cd96aabbfe7ef6a1c27dc51e56c425f01290a58e9beb19ed95ee64da9f32df3e9276cd1ea58e78792741d74a519cb56955491 languageName: node linkType: hard -"@babel/code-frame@npm:7.10.4": - version: 7.10.4 - resolution: "@babel/code-frame@npm:7.10.4" +"@aws-crypto/sha256-browser@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/sha256-browser@npm:5.2.0" dependencies: - "@babel/highlight": ^7.10.4 - checksum: feb4543c8a509fe30f0f6e8d7aa84f82b41148b963b826cd330e34986f649a85cb63b2f13dd4effdf434ac555d16f14940b8ea5f4433297c2f5ff85486ded019 + "@aws-crypto/sha256-js": ^5.2.0 + "@aws-crypto/supports-web-crypto": ^5.2.0 + "@aws-crypto/util": ^5.2.0 + "@aws-sdk/types": ^3.222.0 + "@aws-sdk/util-locate-window": ^3.0.0 + "@smithy/util-utf8": ^2.0.0 + tslib: ^2.6.2 + checksum: 773f12f2026d82a6bb4a23a8f491894a6d32525bd9b8bfbc12896526cf11882a7607a671c478c45f9cd7d6ba1caaed48a62b67c6f725244bd83a1275108f46c7 + languageName: node + linkType: hard + +"@aws-crypto/sha256-js@npm:5.2.0, @aws-crypto/sha256-js@npm:^5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/sha256-js@npm:5.2.0" + dependencies: + "@aws-crypto/util": ^5.2.0 + "@aws-sdk/types": ^3.222.0 + tslib: ^2.6.2 + checksum: 007fbe0436d714d0d0d282e2b61c90e45adcb9ad75eac9ac7ba03d32b56624afd09b2a9ceb4d659661cf17c51d74d1900ab6b00eacafc002da1101664955ca53 + languageName: node + linkType: hard + +"@aws-crypto/supports-web-crypto@npm:^5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/supports-web-crypto@npm:5.2.0" + dependencies: + tslib: ^2.6.2 + checksum: 6ffc21de48b2b2c3e918193101d7e8fe949d47b37688892e1c39eaedaa938be80c0f404fe1c874c30cce16781026777a53bf47d5d90143ca91d0feb7c4a6f830 + languageName: node + linkType: hard + +"@aws-crypto/util@npm:^5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/util@npm:5.2.0" + dependencies: + "@aws-sdk/types": ^3.222.0 + "@smithy/util-utf8": ^2.0.0 + tslib: ^2.6.2 + checksum: f0f81d9d2771c59946cfec48b86cb23d39f78a966c4a1f89d4753abdc3cb38de06f907d1e6450059b121d48ac65d612ab88bdb70014553a077fc3dabddfbf8d6 + languageName: node + linkType: hard + +"@aws-sdk/client-ses@npm:^3.731.1": + version: 3.888.0 + resolution: "@aws-sdk/client-ses@npm:3.888.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.888.0 + "@aws-sdk/credential-provider-node": 3.888.0 + "@aws-sdk/middleware-host-header": 3.887.0 + "@aws-sdk/middleware-logger": 3.887.0 + "@aws-sdk/middleware-recursion-detection": 3.887.0 + "@aws-sdk/middleware-user-agent": 3.888.0 + "@aws-sdk/region-config-resolver": 3.887.0 + "@aws-sdk/types": 3.887.0 + "@aws-sdk/util-endpoints": 3.887.0 + "@aws-sdk/util-user-agent-browser": 3.887.0 + "@aws-sdk/util-user-agent-node": 3.888.0 + "@smithy/config-resolver": ^4.2.1 + "@smithy/core": ^3.11.0 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/hash-node": ^4.1.1 + "@smithy/invalid-dependency": ^4.1.1 + "@smithy/middleware-content-length": ^4.1.1 + "@smithy/middleware-endpoint": ^4.2.1 + "@smithy/middleware-retry": ^4.2.1 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/middleware-stack": ^4.1.1 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-body-length-node": ^4.1.0 + "@smithy/util-defaults-mode-browser": ^4.1.1 + "@smithy/util-defaults-mode-node": ^4.1.1 + "@smithy/util-endpoints": ^3.1.1 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-retry": ^4.1.1 + "@smithy/util-utf8": ^4.1.0 + "@smithy/util-waiter": ^4.1.1 + tslib: ^2.6.2 + checksum: 818bd91245081edb2e16d3e8c05f0c9a74868dd46b9f3fa1b4d57496636961a3a09ce7837471abaebe0e2697c7732366d5af3b8d9b9ece65c4d3c0a7e1419619 + languageName: node + linkType: hard + +"@aws-sdk/client-sso@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/client-sso@npm:3.888.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.888.0 + "@aws-sdk/middleware-host-header": 3.887.0 + "@aws-sdk/middleware-logger": 3.887.0 + "@aws-sdk/middleware-recursion-detection": 3.887.0 + "@aws-sdk/middleware-user-agent": 3.888.0 + "@aws-sdk/region-config-resolver": 3.887.0 + "@aws-sdk/types": 3.887.0 + "@aws-sdk/util-endpoints": 3.887.0 + "@aws-sdk/util-user-agent-browser": 3.887.0 + "@aws-sdk/util-user-agent-node": 3.888.0 + "@smithy/config-resolver": ^4.2.1 + "@smithy/core": ^3.11.0 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/hash-node": ^4.1.1 + "@smithy/invalid-dependency": ^4.1.1 + "@smithy/middleware-content-length": ^4.1.1 + "@smithy/middleware-endpoint": ^4.2.1 + "@smithy/middleware-retry": ^4.2.1 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/middleware-stack": ^4.1.1 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-body-length-node": ^4.1.0 + "@smithy/util-defaults-mode-browser": ^4.1.1 + "@smithy/util-defaults-mode-node": ^4.1.1 + "@smithy/util-endpoints": ^3.1.1 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-retry": ^4.1.1 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: 0aa68ee0144cf56c31034c520c39fd8c53b73083bd6ce1ad0ac32ecbefd497e280b5638a00b8078c26e4687b4a083161468b94f4d79d0e51132c98044d2628ab + languageName: node + linkType: hard + +"@aws-sdk/core@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/core@npm:3.888.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@aws-sdk/xml-builder": 3.887.0 + "@smithy/core": ^3.11.0 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/property-provider": ^4.0.5 + "@smithy/protocol-http": ^5.2.1 + "@smithy/signature-v4": ^5.1.3 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-utf8": ^4.1.0 + fast-xml-parser: 5.2.5 + tslib: ^2.6.2 + checksum: baf26845beaf66f796130337365e2992751e37fd632ea75ad0bfc8f955aea704c69112fc107a0c13a5af7e932707c3a40fc490c9634cdda4acf6050f5ca63deb + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-env@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 4c5012bcb95966db2a72ad7700fc3b5bbb4f7e4dea43f215b972b2d868ed40c8b7c7d1cec4fe53b0bda9b5f6c142480716561707609022f0fd91f033c2450a9c + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-http@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/property-provider": ^4.0.5 + "@smithy/protocol-http": ^5.2.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/util-stream": ^4.3.1 + tslib: ^2.6.2 + checksum: cd83cae0e01c65bc91ff922670d5c1933463726bbb44a68c6ee726f6b0799dc8d596ca7ef15e1abfb7fb9c88322f337e2bd303f65d66dfd5859055be35061d86 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-ini@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/credential-provider-env": 3.888.0 + "@aws-sdk/credential-provider-http": 3.888.0 + "@aws-sdk/credential-provider-process": 3.888.0 + "@aws-sdk/credential-provider-sso": 3.888.0 + "@aws-sdk/credential-provider-web-identity": 3.888.0 + "@aws-sdk/nested-clients": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/credential-provider-imds": ^4.0.7 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: aa551d529f378ef9558a16ea01e043f742646f38347469e2b1cbe3e2e094ca30cd272911750c62dd56908c9ff704c459014f6fbf3a25fd61e8f0e7e61f3a41bb + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-node@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.888.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.888.0 + "@aws-sdk/credential-provider-http": 3.888.0 + "@aws-sdk/credential-provider-ini": 3.888.0 + "@aws-sdk/credential-provider-process": 3.888.0 + "@aws-sdk/credential-provider-sso": 3.888.0 + "@aws-sdk/credential-provider-web-identity": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/credential-provider-imds": ^4.0.7 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: cac63c05516ebf645068f8f68f1932db4691b1368ceced7260cd6ad6b10e4bf6be30962c150e3db69aab86e31609576610b85e62293fc4b4c71b4c96991e9ada + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-process@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 51290738eb782230758767994c677bec5a7da72756b7a780e5eaff04ed2812d7612e74df90892eac89c1f06ad164f2c657da0d999a786158e7e4af972a9dc7e0 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-sso@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.888.0" + dependencies: + "@aws-sdk/client-sso": 3.888.0 + "@aws-sdk/core": 3.888.0 + "@aws-sdk/token-providers": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 69e040bd12cea21134669ce8635741a754c940e5c9b053bf208d498b7878ca35ed047405eddf8264c8e44f09258166c8701b75776aa9002f8fc28e6b9a498580 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-web-identity@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/nested-clients": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: f4a6855190f47b00c5150d8e89c588e2beb65232829a4e2cef398aab2fddd775124541cead84c4ae5b59f1cabd4e566127ae23cb909841ce8e34a2d8f4fbc623 + languageName: node + linkType: hard + +"@aws-sdk/middleware-host-header@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: f07a901c5165d8eaf831bc0968f12c77c2b74cde53c7a6f61caadc87578172be162e4e0df6fdf7df0a182d282716603f01b4d818b2f2ba2856ad0ecb82de7816 + languageName: node + linkType: hard + +"@aws-sdk/middleware-logger@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/middleware-logger@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 6f4a95ed164378d6104207ec6b0da8d61452a74a67c95156e42be33d00f29daa53badc7a0461f269223eaeb0d5eff520d8fc4e25cc615657c0d5a897dbd7546f + languageName: node + linkType: hard + +"@aws-sdk/middleware-recursion-detection@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@aws/lambda-invoke-store": ^0.0.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: c8cdef1bcbe1228b918c6fa8fd7f149fb46c0004ee661b04138d95f167eeae9abfac68ca5597b70fa501efc292024ce7369161459cdcb2f6615587c428c6baac + languageName: node + linkType: hard + +"@aws-sdk/middleware-user-agent@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@aws-sdk/util-endpoints": 3.887.0 + "@smithy/core": ^3.11.0 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 17eeaa35c7a9b4e0505e7d5feb705c41dbdcdf4809ef39562fa8bd6e964ef5b9d3669eb6f307e535ce3f7a00c466b4080948a822ee9d7e14fa2c4257dc0c5eb3 + languageName: node + linkType: hard + +"@aws-sdk/nested-clients@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/nested-clients@npm:3.888.0" + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.888.0 + "@aws-sdk/middleware-host-header": 3.887.0 + "@aws-sdk/middleware-logger": 3.887.0 + "@aws-sdk/middleware-recursion-detection": 3.887.0 + "@aws-sdk/middleware-user-agent": 3.888.0 + "@aws-sdk/region-config-resolver": 3.887.0 + "@aws-sdk/types": 3.887.0 + "@aws-sdk/util-endpoints": 3.887.0 + "@aws-sdk/util-user-agent-browser": 3.887.0 + "@aws-sdk/util-user-agent-node": 3.888.0 + "@smithy/config-resolver": ^4.2.1 + "@smithy/core": ^3.11.0 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/hash-node": ^4.1.1 + "@smithy/invalid-dependency": ^4.1.1 + "@smithy/middleware-content-length": ^4.1.1 + "@smithy/middleware-endpoint": ^4.2.1 + "@smithy/middleware-retry": ^4.2.1 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/middleware-stack": ^4.1.1 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/smithy-client": ^4.6.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-body-length-node": ^4.1.0 + "@smithy/util-defaults-mode-browser": ^4.1.1 + "@smithy/util-defaults-mode-node": ^4.1.1 + "@smithy/util-endpoints": ^3.1.1 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-retry": ^4.1.1 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: 699aaea06f8d0fe720470003ec70ede15e8781d50dbf28ed827ed7dd85318b3684995996859c1c5e0350ba9829f39f6721f1229b2c0e06f2a0e4cf77fee89f4b + languageName: node + linkType: hard + +"@aws-sdk/region-config-resolver@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-config-provider": ^4.0.0 + "@smithy/util-middleware": ^4.1.1 + tslib: ^2.6.2 + checksum: aced1bf4e3dce92fa76337a774551cf88e72a25e44f7582a9897ce52e73d309791fab22ba4900f364715afc73190c9e5a1d8934077aa04a63d8ef9cd9bf3f4ad + languageName: node + linkType: hard + +"@aws-sdk/token-providers@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/token-providers@npm:3.888.0" + dependencies: + "@aws-sdk/core": 3.888.0 + "@aws-sdk/nested-clients": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/property-provider": ^4.0.5 + "@smithy/shared-ini-file-loader": ^4.0.5 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 8e2e6ac2fc480f6d1b38a3563f274d2096bc7aad1ea46e875ce08955c7bb37b8c3f2ce7c457f414af94b5d7053499589909f15ceb5de8c28bd9a596c24b6fa6c + languageName: node + linkType: hard + +"@aws-sdk/types@npm:3.887.0, @aws-sdk/types@npm:^3.222.0": + version: 3.887.0 + resolution: "@aws-sdk/types@npm:3.887.0" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 141d3fcd3bf5b95e13df81b8cf1554f2cc2f4783922265ea344ab60105ea4453a9b4fae7df5da8652f9ede9e83fba8b06bc1c95566329d0541810d711ff1dad9 + languageName: node + linkType: hard + +"@aws-sdk/util-endpoints@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/util-endpoints@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-endpoints": ^3.1.1 + tslib: ^2.6.2 + checksum: aced26165e63871ac44e0cd9393729cb437d8b2f277c34cc45d51c9964e43c5bea4762c948ee04e9a93c5d98b037923de23d0b69973f256480f533285d0db45d + languageName: node + linkType: hard + +"@aws-sdk/util-locate-window@npm:^3.0.0": + version: 3.873.0 + resolution: "@aws-sdk/util-locate-window@npm:3.873.0" + dependencies: + tslib: ^2.6.2 + checksum: ff98e8fa00504ae62bf25605e708ac77693b11b628e0234b0a5bd03e6021e0ca12677ea494b1463c2ef70b483b5b30b2a08dfe5806788a570b3d7becae15591e + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-browser@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.887.0" + dependencies: + "@aws-sdk/types": 3.887.0 + "@smithy/types": ^4.5.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 18c5f77fd5e60129c7944c7f2d8b5b6c61783c12d59492193b25dcb6631d1c48896d5ffdec4ffd579ed75ae781c8fb91747e25cf4e7927b6f37b41b059e3035c + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-node@npm:3.888.0": + version: 3.888.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.888.0" + dependencies: + "@aws-sdk/middleware-user-agent": 3.888.0 + "@aws-sdk/types": 3.887.0 + "@smithy/node-config-provider": ^4.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: f2e273f44e078aeeaad678a592a69c315e0307a557f48759cba5d78f2ae501faed18c2497ea27e35796a11642ea6f9eeff2629947db07621b3a553e7fc81884c + languageName: node + linkType: hard + +"@aws-sdk/xml-builder@npm:3.887.0": + version: 3.887.0 + resolution: "@aws-sdk/xml-builder@npm:3.887.0" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: c2937d705a6ba6e3635279532eb984548117086520e9569df97ce400c6d7b9d1a74b47e720089857e2e5bd2a68f2b8273e746a79938ece0b875cca5b7ddbd844 + languageName: node + linkType: hard + +"@aws/lambda-invoke-store@npm:^0.0.1": + version: 0.0.1 + resolution: "@aws/lambda-invoke-store@npm:0.0.1" + checksum: af732ba2cd343daa49d4933827b4bdc80449641fbdf465ad4a97a818adf6f355454942a2b59a6a297c261c1b3fff11ea69c93b9564ed5e33fcdcf30f993c722d languageName: node linkType: hard @@ -47,397 +525,354 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.1, @babel/code-frame@npm:^7.24.2, @babel/code-frame@npm:^7.5.5": - version: 7.24.2 - resolution: "@babel/code-frame@npm:7.24.2" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.8.3": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" dependencies: - "@babel/highlight": ^7.24.2 - picocolors: ^1.0.0 - checksum: 70e867340cfe09ca5488b2f36372c45cabf43c79a5b6426e6df5ef0611ff5dfa75a57dda841895693de6008f32c21a7c97027a8c7bcabd63a7d17416cbead6f8 + "@babel/helper-validator-identifier": ^7.27.1 + js-tokens: ^4.0.0 + picocolors: ^1.1.1 + checksum: 5874edc5d37406c4a0bb14cf79c8e51ad412fb0423d176775ac14fc0259831be1bf95bdda9c2aa651126990505e09a9f0ed85deaa99893bc316d2682c5115bdc languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.23.5, @babel/compat-data@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/compat-data@npm:7.24.4" - checksum: 52ce371658dc7796c9447c9cb3b9c0659370d141b76997f21c5e0028cca4d026ca546b84bc8d157ce7ca30bd353d89f9238504eb8b7aefa9b1f178b4c100c2d4 +"@babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7, @babel/compat-data@npm:^7.28.0": + version: 7.28.4 + resolution: "@babel/compat-data@npm:7.28.4" + checksum: 9f6f5289bbe5a29e3f9c737577a797205a91f19371b50af8942257d9cb590d44eb950154e4f2a3d5de4105f97a49d6fbc8daebe0db1e6eee04f5a4bf73536bfc languageName: node linkType: hard -"@babel/core@npm:7.12.3": - version: 7.12.3 - resolution: "@babel/core@npm:7.12.3" +"@babel/core@npm:^7.1.0, @babel/core@npm:^7.11.1, @babel/core@npm:^7.12.3, @babel/core@npm:^7.16.0, @babel/core@npm:^7.20.5, @babel/core@npm:^7.28.0, @babel/core@npm:^7.7.2, @babel/core@npm:^7.8.0": + version: 7.28.4 + resolution: "@babel/core@npm:7.28.4" dependencies: - "@babel/code-frame": ^7.10.4 - "@babel/generator": ^7.12.1 - "@babel/helper-module-transforms": ^7.12.1 - "@babel/helpers": ^7.12.1 - "@babel/parser": ^7.12.3 - "@babel/template": ^7.10.4 - "@babel/traverse": ^7.12.1 - "@babel/types": ^7.12.1 - convert-source-map: ^1.7.0 - debug: ^4.1.0 - gensync: ^1.0.0-beta.1 - json5: ^2.1.2 - lodash: ^4.17.19 - resolve: ^1.3.2 - semver: ^5.4.1 - source-map: ^0.5.0 - checksum: 29ee14dd7ae66c1af84d1b2864e1e9e1bec23b89f41e414917b10151ae1fcb6d3b6a8a25d028a7e22dba3bb7b69eb1f7f0d844797341357e36fa71ff967fb4a5 - languageName: node - linkType: hard - -"@babel/core@npm:^7.1.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.16.0, @babel/core@npm:^7.20.5, @babel/core@npm:^7.23.5, @babel/core@npm:^7.7.5, @babel/core@npm:^7.8.4": - version: 7.24.4 - resolution: "@babel/core@npm:7.24.4" - dependencies: - "@ampproject/remapping": ^2.2.0 - "@babel/code-frame": ^7.24.2 - "@babel/generator": ^7.24.4 - "@babel/helper-compilation-targets": ^7.23.6 - "@babel/helper-module-transforms": ^7.23.3 - "@babel/helpers": ^7.24.4 - "@babel/parser": ^7.24.4 - "@babel/template": ^7.24.0 - "@babel/traverse": ^7.24.1 - "@babel/types": ^7.24.0 + "@babel/code-frame": ^7.27.1 + "@babel/generator": ^7.28.3 + "@babel/helper-compilation-targets": ^7.27.2 + "@babel/helper-module-transforms": ^7.28.3 + "@babel/helpers": ^7.28.4 + "@babel/parser": ^7.28.4 + "@babel/template": ^7.27.2 + "@babel/traverse": ^7.28.4 + "@babel/types": ^7.28.4 + "@jridgewell/remapping": ^2.3.5 convert-source-map: ^2.0.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.3 semver: ^6.3.1 - checksum: 15ecad7581f3329995956ba461961b1af7bed48901f14fe962ccd3217edca60049e9e6ad4ce48134618397e6c90230168c842e2c28e47ef1f16c97dbbf663c61 + checksum: f55b90b2c61a6461f5c0ccab74d32af9c67448c43c629529ba7ec3c61d87fa8c408cc9305bfb1f5b09e671d25436d44eaf75c48dee5dc0a5c5e21c01290f5134 languageName: node linkType: hard -"@babel/generator@npm:^7.12.1, @babel/generator@npm:^7.24.1, @babel/generator@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/generator@npm:7.24.4" +"@babel/eslint-parser@npm:^7.16.3": + version: 7.28.4 + resolution: "@babel/eslint-parser@npm:7.28.4" dependencies: - "@babel/types": ^7.24.0 - "@jridgewell/gen-mapping": ^0.3.5 - "@jridgewell/trace-mapping": ^0.3.25 - jsesc: ^2.5.1 - checksum: 1b6146c31386c9df3eb594a2c36b5c98da4f67f7c06edb3d68a442b92516b21bb5ba3ad7dbe0058fe76625ed24d66923e15c95b0df75ef1907d4068921a699b8 + "@nicolo-ribaudo/eslint-scope-5-internals": 5.1.1-v1 + eslint-visitor-keys: ^2.1.0 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.11.0 + eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 + checksum: 32fb41c8648e169bc8570e25b4657475e165e1a49b8c6610f9bf86f311bbcc8dfa73f004977015688763aa6af17f48c690720bbc7b7b99695557adb267a9a7ff languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" +"@babel/generator@npm:^7.28.3, @babel/generator@npm:^7.7.2": + version: 7.28.3 + resolution: "@babel/generator@npm:7.28.3" dependencies: - "@babel/types": ^7.22.5 - checksum: 53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d + "@babel/parser": ^7.28.3 + "@babel/types": ^7.28.2 + "@jridgewell/gen-mapping": ^0.3.12 + "@jridgewell/trace-mapping": ^0.3.28 + jsesc: ^3.0.2 + checksum: e2202bf2b9c8a94f7e7a0a049fda0ee037d055c46922e85afa3bbc53309113f859b8193894f991045d7865226028b8f4f06152ed315ab414451932016dba5e42 languageName: node linkType: hard -"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15" +"@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" dependencies: - "@babel/types": ^7.22.15 - checksum: 639c697a1c729f9fafa2dd4c9af2e18568190299b5907bd4c2d0bc818fcbd1e83ffeecc2af24327a7faa7ac4c34edd9d7940510a5e66296c19bad17001cf5c7a + "@babel/types": ^7.27.3 + checksum: 63863a5c936ef82b546ca289c9d1b18fabfc24da5c4ee382830b124e2e79b68d626207febc8d4bffc720f50b2ee65691d7d12cc0308679dee2cd6bdc926b7190 languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.23.6": - version: 7.23.6 - resolution: "@babel/helper-compilation-targets@npm:7.23.6" +"@babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/helper-compilation-targets@npm:7.27.2" dependencies: - "@babel/compat-data": ^7.23.5 - "@babel/helper-validator-option": ^7.23.5 - browserslist: ^4.22.2 + "@babel/compat-data": ^7.27.2 + "@babel/helper-validator-option": ^7.27.1 + browserslist: ^4.24.0 lru-cache: ^5.1.1 semver: ^6.3.1 - checksum: c630b98d4527ac8fe2c58d9a06e785dfb2b73ec71b7c4f2ddf90f814b5f75b547f3c015f110a010fd31f76e3864daaf09f3adcd2f6acdbfb18a8de3a48717590 + checksum: 7b95328237de85d7af1dea010a4daa28e79f961dda48b652860d5893ce9b136fc8b9ea1f126d8e0a24963b09ba5c6631dcb907b4ce109b04452d34a6ae979807 languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.24.1, @babel/helper-create-class-features-plugin@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/helper-create-class-features-plugin@npm:7.24.4" +"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.27.1, @babel/helper-create-class-features-plugin@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/helper-create-class-features-plugin@npm:7.28.3" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-function-name": ^7.23.0 - "@babel/helper-member-expression-to-functions": ^7.23.0 - "@babel/helper-optimise-call-expression": ^7.22.5 - "@babel/helper-replace-supers": ^7.24.1 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 - "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/helper-annotate-as-pure": ^7.27.3 + "@babel/helper-member-expression-to-functions": ^7.27.1 + "@babel/helper-optimise-call-expression": ^7.27.1 + "@babel/helper-replace-supers": ^7.27.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 + "@babel/traverse": ^7.28.3 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 75b0a51ae1f7232932559779b78711c271404d02d069156d1bd9a7982c165c5134058d2ec2d8b5f2e42026ee4f52ba2a30c86a7aa3bce6b5fd0991eb721abc8c + checksum: 6d918e5e9c88ad1a262ab7b1a3caede1bbf95f8276c96846d8b0c1af251c85a0c868a9f1bbbaebdeb199e44dfd0e10fbe22935e56bedd1aa41ba4a7162bfa86c languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.15, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15" +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - regexpu-core: ^5.3.1 + "@babel/helper-annotate-as-pure": ^7.27.1 + regexpu-core: ^6.2.0 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 0243b8d4854f1dc8861b1029a46d3f6393ad72f366a5a08e36a4648aa682044f06da4c6e87a456260e1e1b33c999f898ba591a0760842c1387bcc93fbf2151a6 + checksum: 2ede6bbad0016a9262fd281ce8f1a5d69e6179dcec4ea282830e924c29a29b66b0544ecb92e4ef4acdaf2c4c990931d7dc442dbcd6a8bcec4bad73923ef70934 languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@npm:^0.6.1, @babel/helper-define-polyfill-provider@npm:^0.6.2": - version: 0.6.2 - resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2" +"@babel/helper-define-polyfill-provider@npm:^0.6.5": + version: 0.6.5 + resolution: "@babel/helper-define-polyfill-provider@npm:0.6.5" dependencies: - "@babel/helper-compilation-targets": ^7.22.6 - "@babel/helper-plugin-utils": ^7.22.5 - debug: ^4.1.1 + "@babel/helper-compilation-targets": ^7.27.2 + "@babel/helper-plugin-utils": ^7.27.1 + debug: ^4.4.1 lodash.debounce: ^4.0.8 - resolve: ^1.14.2 + resolve: ^1.22.10 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 2bba965ea9a4887ddf9c11d51d740ab473bd7597b787d042c325f6a45912dfe908c2d6bb1d837bf82f7e9fa51e6ad5150563c58131d2bb85515e63d971414a9c - languageName: node - linkType: hard - -"@babel/helper-environment-visitor@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-environment-visitor@npm:7.22.20" - checksum: d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69 + checksum: 9fd3b09b209c8ed0d3d8bc1f494f1368b9e1f6e46195af4ce948630fe97d7dafde4882eedace270b319bf6555ddf35e220c77505f6d634f621766cdccbba0aae languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/helper-function-name@npm:7.23.0" - dependencies: - "@babel/template": ^7.22.15 - "@babel/types": ^7.23.0 - checksum: e44542257b2d4634a1f979244eb2a4ad8e6d75eb6761b4cfceb56b562f7db150d134bc538c8e6adca3783e3bc31be949071527aa8e3aab7867d1ad2d84a26e10 - languageName: node - linkType: hard - -"@babel/helper-hoist-variables@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-hoist-variables@npm:7.22.5" - dependencies: - "@babel/types": ^7.22.5 - checksum: 394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc +"@babel/helper-globals@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/helper-globals@npm:7.28.0" + checksum: d8d7b91c12dad1ee747968af0cb73baf91053b2bcf78634da2c2c4991fb45ede9bd0c8f9b5f3254881242bc0921218fcb7c28ae885477c25177147e978ce4397 languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/helper-member-expression-to-functions@npm:7.23.0" +"@babel/helper-member-expression-to-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-member-expression-to-functions@npm:7.27.1" dependencies: - "@babel/types": ^7.23.0 - checksum: 494659361370c979ada711ca685e2efe9460683c36db1b283b446122596602c901e291e09f2f980ecedfe6e0f2bd5386cb59768285446530df10c14df1024e75 + "@babel/traverse": ^7.27.1 + "@babel/types": ^7.27.1 + checksum: b13a3d120015a6fd2f6e6c2ff789cd12498745ef028710cba612cfb751b91ace700c3f96c1689228d1dcb41e9d4cf83d6dff8627dcb0c8da12d79440e783c6b8 languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.24.1, @babel/helper-module-imports@npm:^7.24.3": - version: 7.24.3 - resolution: "@babel/helper-module-imports@npm:7.24.3" +"@babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-module-imports@npm:7.27.1" dependencies: - "@babel/types": ^7.24.0 - checksum: c23492189ba97a1ec7d37012336a5661174e8b88194836b6bbf90d13c3b72c1db4626263c654454986f924c6da8be7ba7f9447876d709cd00bd6ffde6ec00796 + "@babel/traverse": ^7.27.1 + "@babel/types": ^7.27.1 + checksum: 92d01c71c0e4aacdc2babce418a9a1a27a8f7d770a210ffa0f3933f321befab18b655bc1241bebc40767516731de0b85639140c42e45a8210abe1e792f115b28 languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.12.1, @babel/helper-module-transforms@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/helper-module-transforms@npm:7.23.3" +"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/helper-module-transforms@npm:7.28.3" dependencies: - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-module-imports": ^7.22.15 - "@babel/helper-simple-access": ^7.22.5 - "@babel/helper-split-export-declaration": ^7.22.6 - "@babel/helper-validator-identifier": ^7.22.20 + "@babel/helper-module-imports": ^7.27.1 + "@babel/helper-validator-identifier": ^7.27.1 + "@babel/traverse": ^7.28.3 peerDependencies: "@babel/core": ^7.0.0 - checksum: 5d0895cfba0e16ae16f3aa92fee108517023ad89a855289c4eb1d46f7aef4519adf8e6f971e1d55ac20c5461610e17213f1144097a8f932e768a9132e2278d71 + checksum: 7cf7b79da0fa626d6c84bfc7b35c079a2559caecaa2ff645b0f1db0d741507aa4df6b5b98a3283e8ac4e89094af271d805bf5701e5c4f916e622797b7c8cbb18 languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" +"@babel/helper-optimise-call-expression@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" dependencies: - "@babel/types": ^7.22.5 - checksum: c70ef6cc6b6ed32eeeec4482127e8be5451d0e5282d5495d5d569d39eb04d7f1d66ec99b327f45d1d5842a9ad8c22d48567e93fc502003a47de78d122e355f7c + "@babel/types": ^7.27.1 + checksum: 0fb7ee824a384529d6b74f8a58279f9b56bfe3cce332168067dddeab2552d8eeb56dc8eaf86c04a3a09166a316cb92dfc79c4c623cd034ad4c563952c98b464f languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": - version: 7.24.0 - resolution: "@babel/helper-plugin-utils@npm:7.24.0" - checksum: e2baa0eede34d2fa2265947042aa84d444aa48dc51e9feedea55b67fc1bc3ab051387e18b33ca7748285a6061390831ab82f8a2c767d08470b93500ec727e9b9 +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0": + version: 7.27.1 + resolution: "@babel/helper-plugin-utils@npm:7.27.1" + checksum: 5d715055301badab62bdb2336075a77f8dc8bd290cad2bc1b37ea3bf1b3efc40594d308082229f239deb4d6b5b80b0a73bce000e595ea74416e0339c11037047 languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20" +"@babel/helper-remap-async-to-generator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-wrap-function": ^7.22.20 + "@babel/helper-annotate-as-pure": ^7.27.1 + "@babel/helper-wrap-function": ^7.27.1 + "@babel/traverse": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 2fe6300a6f1b58211dffa0aed1b45d4958506d096543663dba83bd9251fe8d670fa909143a65b45e72acb49e7e20fbdb73eae315d9ddaced467948c3329986e7 + checksum: 0747397ba013f87dbf575454a76c18210d61c7c9af0f697546b4bcac670b54ddc156330234407b397f0c948738c304c228e0223039bc45eab4fbf46966a5e8cc languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/helper-replace-supers@npm:7.24.1" +"@babel/helper-replace-supers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-replace-supers@npm:7.27.1" dependencies: - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-member-expression-to-functions": ^7.23.0 - "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-member-expression-to-functions": ^7.27.1 + "@babel/helper-optimise-call-expression": ^7.27.1 + "@babel/traverse": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: c04182c34a3195c6396de2f2945f86cb60daa94ca7392db09bd8b0d4e7a15b02fbe1947c70f6062c87eadaea6d7135207129efa35cf458ea0987bab8c0f02d5a - languageName: node - linkType: hard - -"@babel/helper-simple-access@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-simple-access@npm:7.22.5" - dependencies: - "@babel/types": ^7.22.5 - checksum: fe9686714caf7d70aedb46c3cce090f8b915b206e09225f1e4dbc416786c2fdbbee40b38b23c268b7ccef749dd2db35f255338fb4f2444429874d900dede5ad2 - languageName: node - linkType: hard - -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0, @babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" - dependencies: - "@babel/types": ^7.22.5 - checksum: 1012ef2295eb12dc073f2b9edf3425661e9b8432a3387e62a8bc27c42963f1f216ab3124228015c748770b2257b4f1fda882ca8fa34c0bf485e929ae5bc45244 + checksum: 3690266c304f21008690ba68062f889a363583cabc13c3d033b94513953147af3e0a3fdb48fa1bb9fa3734b64e221fc65e5222ab70837f02321b7225f487c6ef languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:^7.22.6": - version: 7.22.6 - resolution: "@babel/helper-split-export-declaration@npm:7.22.6" +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0, @babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" dependencies: - "@babel/types": ^7.22.5 - checksum: e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921 + "@babel/traverse": ^7.27.1 + "@babel/types": ^7.27.1 + checksum: 4f380c5d0e0769fa6942a468b0c2d7c8f0c438f941aaa88f785f8752c103631d0904c7b4e76207a3b0e6588b2dec376595370d92ca8f8f1b422c14a69aa146d4 languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.23.4": - version: 7.24.1 - resolution: "@babel/helper-string-parser@npm:7.24.1" - checksum: 8404e865b06013979a12406aab4c0e8d2e377199deec09dfe9f57b833b0c9ce7b6e8c1c553f2da8d0bcd240c5005bd7a269f4fef0d628aeb7d5fe035c436fb67 +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 0a8464adc4b39b138aedcb443b09f4005d86207d7126e5e079177e05c3116107d856ec08282b365e9a79a9872f40f4092a6127f8d74c8a01c1ef789dacfc25d6 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-validator-identifier@npm:7.22.20" - checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc +"@babel/helper-validator-identifier@npm:^7.25.9, @babel/helper-validator-identifier@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-identifier@npm:7.27.1" + checksum: 3c7e8391e59d6c85baeefe9afb86432f2ab821c6232b00ea9082a51d3e7e95a2f3fb083d74dc1f49ac82cf238e1d2295dafcb001f7b0fab479f3f56af5eaaa47 languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/helper-validator-option@npm:7.23.5" - checksum: 537cde2330a8aede223552510e8a13e9c1c8798afee3757995a7d4acae564124fe2bf7e7c3d90d62d3657434a74340a274b3b3b1c6f17e9a2be1f48af29cb09e +"@babel/helper-validator-option@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-option@npm:7.27.1" + checksum: db73e6a308092531c629ee5de7f0d04390835b21a263be2644276cb27da2384b64676cab9f22cd8d8dbd854c92b1d7d56fc8517cf0070c35d1c14a8c828b0903 languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-wrap-function@npm:7.22.20" +"@babel/helper-wrap-function@npm:^7.27.1": + version: 7.28.3 + resolution: "@babel/helper-wrap-function@npm:7.28.3" dependencies: - "@babel/helper-function-name": ^7.22.5 - "@babel/template": ^7.22.15 - "@babel/types": ^7.22.19 - checksum: 221ed9b5572612aeb571e4ce6a256f2dee85b3c9536f1dd5e611b0255e5f59a3d0ec392d8d46d4152149156a8109f92f20379b1d6d36abb613176e0e33f05fca + "@babel/template": ^7.27.2 + "@babel/traverse": ^7.28.3 + "@babel/types": ^7.28.2 + checksum: 0ebdfdc918fdd0c1cf6ff15ba4c664974d0cdf21a017af560d58b00c379df3bf2e55f13a44fe3225668bca169da174f6cb97a96c4e987fb728fdb8f9a39db302 languageName: node linkType: hard -"@babel/helpers@npm:^7.12.1, @babel/helpers@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/helpers@npm:7.24.4" +"@babel/helpers@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/helpers@npm:7.28.4" dependencies: - "@babel/template": ^7.24.0 - "@babel/traverse": ^7.24.1 - "@babel/types": ^7.24.0 - checksum: ecd2dc0b3b32e24b97fa3bcda432dd3235b77c2be1e16eafc35b8ef8f6c461faa99796a8bc2431a408c98b4aabfd572c160e2b67ecea4c5c9dd3a8314a97994a + "@babel/template": ^7.27.2 + "@babel/types": ^7.28.4 + checksum: a8706219e0bd60c18bbb8e010aa122e9b14e7e7e67c21cc101e6f1b5e79dcb9a18d674f655997f85daaf421aa138cf284710bb04371a2255a0a3137f097430b4 languageName: node linkType: hard -"@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.24.2": - version: 7.24.2 - resolution: "@babel/highlight@npm:7.24.2" +"@babel/highlight@npm:^7.10.4": + version: 7.25.9 + resolution: "@babel/highlight@npm:7.25.9" dependencies: - "@babel/helper-validator-identifier": ^7.22.20 + "@babel/helper-validator-identifier": ^7.25.9 chalk: ^2.4.2 js-tokens: ^4.0.0 picocolors: ^1.0.0 - checksum: 5f17b131cc3ebf3ab285a62cf98a404aef1bd71a6be045e748f8d5bf66d6a6e1aefd62f5972c84369472e8d9f22a614c58a89cd331eb60b7ba965b31b1bbeaf5 + checksum: a6e0ac0a1c4bef7401915ca3442ab2b7ae4adf360262ca96b91396bfb9578abb28c316abf5e34460b780696db833b550238d9256bdaca60fade4ba7a67645064 languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.3, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.7.0": - version: 7.24.4 - resolution: "@babel/parser@npm:7.24.4" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/parser@npm:7.28.4" + dependencies: + "@babel/types": ^7.28.4 bin: parser: ./bin/babel-parser.js - checksum: 94c9e3e592894cd6fc57c519f4e06b65463df9be5f01739bb0d0bfce7ffcf99b3c2fdadd44dc59cc858ba2739ce6e469813a941c2f2dfacf333a3b2c9c5c8465 + checksum: d95e283fe1153039b396926ef567ca1ab114afb5c732a23bbcbbd0465ac59971aeb6a63f37593ce7671a52d34ec52b23008c999d68241b42d26928c540464063 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/traverse": ^7.27.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 72f24b9487e445fa61cf8be552aad394a648c2bb445c38d39d1df003186d9685b87dd8d388c950f438ea0ca44c82099d9c49252fb681c719cc72edf02bbe0304 languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.24.4" +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.27.1" dependencies: - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 0be3f41b1b865d7a4ed1a432337be48de67989d0b4e47def34a05097a804b6fc193115f97c954fd757339e0b80030ecf1d0a3d3fd6e7e91718644de0a5aae3d3 + checksum: eb7f4146dc01f1198ce559a90b077e58b951a07521ec414e3c7d4593bf6c4ab5c2af22242a7e9fec085e20299e0ba6ea97f44a45e84ab148141bf9eb959ad25e languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.24.1" +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: ec5fddc8db6de0e0082a883f21141d6f4f9f9f0bc190d662a732b5e9a506aae5d7d2337049a1bf055d7cb7add6f128036db6d4f47de5e9ac1be29e043c8b7ca8 + checksum: 621cfddfcc99a81e74f8b6f9101fd260b27500cb1a568e3ceae9cc8afe9aee45ac3bca3900a2b66c612b1a2366d29ef67d4df5a1c975be727eaad6906f98c2c6 languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.24.1" +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 - "@babel/plugin-transform-optional-chaining": ^7.24.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 + "@babel/plugin-transform-optional-chaining": ^7.27.1 peerDependencies: "@babel/core": ^7.13.0 - checksum: e18235463e716ac2443938aaec3c18b40c417a1746fba0fa4c26cf4d71326b76ef26c002081ab1b445abfae98e063d561519aa55672dddc1ef80b3940211ffbb + checksum: f07aa80272bd7a46b7ba11a4644da6c9b6a5a64e848dfaffdad6f02663adefd512e1aaebe664c4dd95f7ed4f80c872c7f8db8d8e34b47aae0930b412a28711a0 languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.24.1" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.28.3" dependencies: - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/traverse": ^7.28.3 peerDependencies: "@babel/core": ^7.0.0 - checksum: b5e5889ce5ef51e813e3063cd548f55eb3c88e925c3c08913f334e15d62496861e538ae52a3974e0c56a3044ed8fd5033faea67a64814324af56edc9865b7359 + checksum: c810e5d36030df6861ced35f0adbda7b4b41ac3e984422b32bee906564fd49374435f0a7a1a42eb0a9e6a5170c255f0ab31c163d5fc51fa5a816aa0420311029 languageName: node linkType: hard @@ -454,15 +889,15 @@ __metadata: linkType: hard "@babel/plugin-proposal-decorators@npm:^7.16.4": - version: 7.24.1 - resolution: "@babel/plugin-proposal-decorators@npm:7.24.1" + version: 7.28.0 + resolution: "@babel/plugin-proposal-decorators@npm:7.28.0" dependencies: - "@babel/helper-create-class-features-plugin": ^7.24.1 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-decorators": ^7.24.1 + "@babel/helper-create-class-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/plugin-syntax-decorators": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b9375c64656bf9ae6d2eeb965c40823e6447f0f4594979d037231884c0f3a92af97172087f35a05e90b8ca0ccb47551b013998e85853c1c634d47b341f4deece + checksum: b134907b09ba58f202c219de4eb6246a560441f9166f67b154c1dac32e8a6233e0f59ae9b4909dbd413e0c7dd0afb803a90a7a2fabc194e1b7543211a159eb87 languageName: node linkType: hard @@ -524,7 +959,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-private-property-in-object@npm:^7.16.0": +"@babel/plugin-proposal-private-property-in-object@npm:^7.16.7": version: 7.21.11 resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.11" dependencies: @@ -560,7 +995,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-class-properties@npm:^7.12.13, @babel/plugin-syntax-class-properties@npm:^7.8.3": +"@babel/plugin-syntax-class-properties@npm:^7.12.13": version: 7.12.13 resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" dependencies: @@ -582,73 +1017,51 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-decorators@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-syntax-decorators@npm:7.24.1" - dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 5933fdb1d8d2c0b4b80621ad65dacd4e1ccd836041557c2ddc4cb4c1f46a347fa72977fc519695a801c9cca8b9aaf90d7895ddd52cb4e510fbef5b9f03cb9568 - languageName: node - linkType: hard - -"@babel/plugin-syntax-dynamic-import@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": ^7.8.0 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: ce307af83cf433d4ec42932329fad25fa73138ab39c7436882ea28742e1c0066626d224e0ad2988724c82644e41601cef607b36194f695cb78a1fcdc959637bd - languageName: node - linkType: hard - -"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3" +"@babel/plugin-syntax-decorators@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-decorators@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.8.3 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 85740478be5b0de185228e7814451d74ab8ce0a26fcca7613955262a26e99e8e15e9da58f60c754b84515d4c679b590dbd3f2148f0f58025f4ae706f1c5a5d4a + checksum: c085b6083d9ce71f47563e05dddfff18a7611e376297b5a9eb35ef70e5919822f87bfba5b25276dfa55bdb6465943ba5d8d9a00f870611d63eaa1a148adc275e languageName: node linkType: hard -"@babel/plugin-syntax-flow@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-syntax-flow@npm:7.24.1" +"@babel/plugin-syntax-flow@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-flow@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 87dfe32f3a3ea77941034fb2a39fdfc9ea18a994b8df40c3659a11c8787b2bc5adea029259c4eafc03cd35f11628f6533aa2a06381db7fcbe3b2cc3c2a2bb54f + checksum: 7baca3171ed595d04c865b0ce46fca7f21900686df9d7fcd1017036ce78bb5483e33803de810831e68d39cf478953db69f49ae3f3de2e3207bc4ba49a96b6739 languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.24.1" +"@babel/plugin-syntax-import-assertions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2a463928a63b62052e9fb8f8b0018aa11a926e94f32c168260ae012afe864875c6176c6eb361e13f300542c31316dad791b08a5b8ed92436a3095c7a0e4fce65 + checksum: fb661d630808d67ecb85eabad25aac4e9696a20464bad4c4a6a0d3d40e4dc22557d47e9be3d591ec06429cf048cfe169b8891c373606344d51c4f3ac0f91d6d0 languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.24.1" +"@babel/plugin-syntax-import-attributes@npm:^7.24.7, @babel/plugin-syntax-import-attributes@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 87c8aa4a5ef931313f956871b27f2c051556f627b97ed21e9a5890ca4906b222d89062a956cde459816f5e0dec185ff128d7243d3fdc389504522acb88f0464e + checksum: 97973982fff1bbf86b3d1df13380567042887c50e2ae13a400d02a8ff2c9742a60a75e279bfb73019e1cd9710f04be5e6ab81f896e6678dcfcec8b135e8896cf languageName: node linkType: hard -"@babel/plugin-syntax-import-meta@npm:^7.10.4, @babel/plugin-syntax-import-meta@npm:^7.8.3": +"@babel/plugin-syntax-import-meta@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" dependencies: @@ -670,18 +1083,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-syntax-jsx@npm:7.24.1" +"@babel/plugin-syntax-jsx@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-syntax-jsx@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 712f7e7918cb679f106769f57cfab0bc99b311032665c428b98f4c3e2e6d567601d45386a4f246df6a80d741e1f94192b3f008800d66c4f1daae3ad825c243f0 + checksum: c6d1324cff286a369aa95d99b8abd21dd07821b5d3affd5fe7d6058c84cff9190743287826463ee57a7beecd10fa1e4bc99061df532ee14e188c1c8937b13e3a languageName: node linkType: hard -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" dependencies: @@ -703,7 +1116,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-numeric-separator@npm:^7.10.4, @babel/plugin-syntax-numeric-separator@npm:^7.8.3": +"@babel/plugin-syntax-numeric-separator@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" dependencies: @@ -758,7 +1171,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-top-level-await@npm:^7.14.5, @babel/plugin-syntax-top-level-await@npm:^7.8.3": +"@babel/plugin-syntax-top-level-await@npm:^7.14.5": version: 7.14.5 resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" dependencies: @@ -769,14 +1182,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-syntax-typescript@npm:7.24.1" +"@babel/plugin-syntax-typescript@npm:^7.27.1, @babel/plugin-syntax-typescript@npm:^7.7.2": + version: 7.27.1 + resolution: "@babel/plugin-syntax-typescript@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: bf4bd70788d5456b5f75572e47a2e31435c7c4e43609bd4dffd2cc0c7a6cf90aabcf6cd389e351854de9a64412a07d30effef5373251fe8f6a4c9db0c0163bda + checksum: 87836f7e32af624c2914c73cd6b9803cf324e07d43f61dbb973c6a86f75df725e12540d91fac7141c14b697aa9268fd064220998daced156e96ac3062d7afb41 languageName: node linkType: hard @@ -792,808 +1205,820 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.1" +"@babel/plugin-transform-arrow-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 58f9aa9b0de8382f8cfa3f1f1d40b69d98cd2f52340e2391733d0af745fdddda650ba392e509bc056157c880a2f52834a38ab2c5aa5569af8c61bb6ecbf45f34 + checksum: 62c2cc0ae2093336b1aa1376741c5ed245c0987d9e4b4c5313da4a38155509a7098b5acce582b6781cc0699381420010da2e3086353344abe0a6a0ec38961eb7 languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.24.3": - version: 7.24.3 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.24.3" +"@babel/plugin-transform-async-generator-functions@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.28.0" dependencies: - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-remap-async-to-generator": ^7.22.20 - "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-remap-async-to-generator": ^7.27.1 + "@babel/traverse": ^7.28.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 309af02610be65d937664435adb432a32d9b6eb42bb3d3232c377d27fbc57014774d931665a5bfdaff3d1841b72659e0ad7adcef84b709f251cb0b8444f19214 + checksum: 174aaccd7a8386fd7f32240c3f65a93cf60dcc5f6a2123cfbff44c0d22b424cd41de3a0c6d136b6a2fa60a8ca01550c261677284cb18a0daeab70730b2265f1d languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.1" +"@babel/plugin-transform-async-to-generator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.27.1" dependencies: - "@babel/helper-module-imports": ^7.24.1 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-remap-async-to-generator": ^7.22.20 + "@babel/helper-module-imports": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-remap-async-to-generator": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 429004a6596aa5c9e707b604156f49a146f8d029e31a3152b1649c0b56425264fda5fd38e5db1ddaeb33c3fe45c97dc8078d7abfafe3542a979b49f229801135 + checksum: d79d7a7ae7d416f6a48200017d027a6ba94c09c7617eea8b4e9c803630f00094c1a4fc32bf20ce3282567824ce3fcbda51653aac4003c71ea4e681b331338979 languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.1" +"@babel/plugin-transform-block-scoped-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d8e18bd57b156da1cd4d3c1780ab9ea03afed56c6824ca8e6e74f67959d7989a0e953ec370fe9b417759314f2eef30c8c437395ce63ada2e26c2f469e4704f82 + checksum: 7fb4988ca80cf1fc8345310d5edfe38e86b3a72a302675cdd09404d5064fe1d1fe1283ebe658ad2b71445ecef857bfb29a748064306b5f6c628e0084759c2201 languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/plugin-transform-block-scoping@npm:7.24.4" +"@babel/plugin-transform-block-scoping@npm:^7.28.0": + version: 7.28.4 + resolution: "@babel/plugin-transform-block-scoping@npm:7.28.4" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5229ffe1c55744b96f791521e2876b01ed05c81df67488a7453ce66c2faceb9d1d653089ce6f0abf512752e15e9acac0e75a797a860f24e05b4d36497c7c3183 + checksum: 7f62eae907c0b4f85b9cc024da949697e57d17f2107ca4a240011174762d4c546b856ccbd5ba83ecb4bc9eb50150ea46558d551a5b05d3f25aace88a65fa4e04 languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-class-properties@npm:7.24.1" +"@babel/plugin-transform-class-properties@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-class-properties@npm:7.27.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.24.1 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-create-class-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 95779e9eef0c0638b9631c297d48aee53ffdbb2b1b5221bf40d7eccd566a8e34f859ff3571f8f20b9159b67f1bff7d7dc81da191c15d69fbae5a645197eae7e0 + checksum: 475a6e5a9454912fe1bdc171941976ca10ea4e707675d671cdb5ce6b6761d84d1791ac61b6bca81a2e5f6430cb7b9d8e4b2392404110e69c28207a754e196294 languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.24.4": - version: 7.24.4 - resolution: "@babel/plugin-transform-class-static-block@npm:7.24.4" +"@babel/plugin-transform-class-static-block@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/plugin-transform-class-static-block@npm:7.28.3" dependencies: - "@babel/helper-create-class-features-plugin": ^7.24.4 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-class-static-block": ^7.14.5 + "@babel/helper-create-class-features-plugin": ^7.28.3 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.12.0 - checksum: 3b1db3308b57ba21d47772a9f183804234c23fd64c9ca40915d2d65c5dc7a48b49a6de16b8b90b7a354eacbb51232a862f0fca3dbd23e27d34641f511decddab + checksum: 9b2feaacbf29637ab35a3aae1df35a1129adec5400a1767443739557fb0d3bf8278bf0ec90aacf43dec9a7dd91428d01375020b70528713e1bc36a72776a104c + languageName: node + linkType: hard + +"@babel/plugin-transform-classes@npm:^7.28.3": + version: 7.28.4 + resolution: "@babel/plugin-transform-classes@npm:7.28.4" + dependencies: + "@babel/helper-annotate-as-pure": ^7.27.3 + "@babel/helper-compilation-targets": ^7.27.2 + "@babel/helper-globals": ^7.28.0 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-replace-supers": ^7.27.1 + "@babel/traverse": ^7.28.4 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: f412e00c86584a9094cc0a2f3dd181b8108a4dced477d609c5406beddd5bf79d05a7ea74db508dc4dcb37172f042d5ef98d3d6311ade61c7ea6fbbbb70f5ec29 languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-classes@npm:7.24.1" +"@babel/plugin-transform-computed-properties@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-compilation-targets": ^7.23.6 - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-function-name": ^7.23.0 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-replace-supers": ^7.24.1 - "@babel/helper-split-export-declaration": ^7.22.6 - globals: ^11.1.0 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/template": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e5337e707d731c9f4dcc107d09c9a99b90786bc0da6a250165919587ed818818f6cae2bbcceea880abef975c0411715c0c7f3f361ecd1526bf2eaca5ad26bb00 + checksum: 48bd20f7d631b08c51155751bf75b698d4a22cca36f41c22921ab92e53039c9ec5c3544e5282e18692325ef85d2e4a18c27e12c62b5e20c26fb0c92447e35224 languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-computed-properties@npm:7.24.1" +"@babel/plugin-transform-destructuring@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/plugin-transform-destructuring@npm:7.28.0" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/template": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/traverse": ^7.28.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f2832bcf100a70f348facbb395873318ef5b9ee4b0fb4104a420d9daaeb6003cc2ecc12fd8083dd2e4a7c2da873272ad73ff94de4497125a0cf473294ef9664e + checksum: 5b464d6a03c6eaa1327b60ffc1630ca977db0256938b34e281e65c81c965680e930a6bac043272942d6d4bbd7d1eddded0b7231779429ba51275e092e7367859 languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-destructuring@npm:7.24.1" +"@babel/plugin-transform-dotall-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-create-regexp-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 994fd3c513e40b8f1bdfdd7104ebdcef7c6a11a4e380086074496f586db3ac04cba0ae70babb820df6363b6700747b0556f6860783e046ace7c741a22f49ec5b + checksum: 2173e5b13f403538ffc6bd57b190cedf4caf320abc13a99e5b2721864e7148dbd3bd7c82d92377136af80432818f665fdd9a1fd33bc5549a4c91e24e5ce2413c languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.24.1" +"@babel/plugin-transform-duplicate-keys@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.15 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7f623d25b6f213b94ebc1754e9e31c1077c8e288626d8b7bfa76a97b067ce80ddcd0ede402a546706c65002c0ccf45cd5ec621511c2668eed31ebcabe8391d35 + checksum: ef2112d658338e3ff0827f39a53c0cfa211f1cbbe60363bca833a5269df389598ec965e7283600b46533c39cdca82307d0d69c0f518290ec5b00bb713044715b + languageName: node + linkType: hard + +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.27.1" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 2a109613535e6ac79240dced71429e988affd6a5b3d0cd0f563c8d6c208c51ce7bf2c300bc1150502376b26a51f279119b3358f1c0f2d2f8abca3bcd62e1ae46 languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.24.1" +"@babel/plugin-transform-dynamic-import@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a3b07c07cee441e185858a9bb9739bb72643173c18bf5f9f949dd2d4784ca124e56b01d0a270790fb1ff0cf75d436075db0a2b643fb4285ff9a21df9e8dc6284 + checksum: 7a9fbc8d17148b7f11a1d1ca3990d2c2cd44bd08a45dcaf14f20a017721235b9044b20e6168b6940282bb1b48fb78e6afbdfb9dd9d82fde614e15baa7d579932 languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.1" +"@babel/plugin-transform-explicit-resource-management@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/plugin-transform-explicit-resource-management@npm:7.28.0" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-dynamic-import": ^7.8.3 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/plugin-transform-destructuring": ^7.28.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 59fc561ee40b1a69f969c12c6c5fac206226d6642213985a569dd0f99f8e41c0f4eaedebd36936c255444a8335079842274c42a975a433beadb436d4c5abb79b + checksum: a44140097ed4854883c426613f4e8763237cd0fdab1c780514f4315f6c148d6b528d7a57fe6fdec4dbce28a21b70393ef3507b72dfec2e30bfc8d7db1ff19474 languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.24.1" +"@babel/plugin-transform-exponentiation-operator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.27.1" dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor": ^7.22.15 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f90841fe1a1e9f680b4209121d3e2992f923e85efcd322b26e5901c180ef44ff727fb89790803a23fac49af34c1ce2e480018027c22b4573b615512ac5b6fc50 + checksum: 4ff4a0f30babc457a5ae8564deda209599627c2ce647284a0e8e66f65b44f6d968cf77761a4cc31b45b61693f0810479248c79e681681d8ccb39d0c52944c1fd languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.1" +"@babel/plugin-transform-export-namespace-from@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-export-namespace-from": ^7.8.3 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: bc710ac231919df9555331885748385c11c5e695d7271824fe56fba51dd637d48d3e5cd52e1c69f2b1a384fbbb41552572bc1ca3a2285ee29571f002e9bb2421 + checksum: 85082923eca317094f08f4953d8ea2a6558b3117826c0b740676983902b7236df1f4213ad844cb38c2dae104753dbe8f1cc51f01567835d476d32f5f544a4385 languageName: node linkType: hard "@babel/plugin-transform-flow-strip-types@npm:^7.16.0": - version: 7.24.1 - resolution: "@babel/plugin-transform-flow-strip-types@npm:7.24.1" + version: 7.27.1 + resolution: "@babel/plugin-transform-flow-strip-types@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-flow": ^7.24.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/plugin-syntax-flow": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 83faac90c934e15a8fe813d90cbfdf8aa2cb2cc9108f55e4a1ecda1c3097735af6a0b6623057f059153b572bc1dd088aeb2ff24217e9de82ad2390ab1210d01b + checksum: 0885028866fadefef35292d5a27f878d6a12b6f83778f8731481d4503b49c258507882a7de2aafda9b62d5f6350042f1a06355b998d5ed5e85d693bfcb77b939 languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-for-of@npm:7.24.1" +"@babel/plugin-transform-for-of@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-for-of@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 990adde96ea1766ed6008c006c7040127bef59066533bb2977b246ea4a596fe450a528d1881a0db5f894deaf1b81654dfb494b19ad405b369be942738aa9c364 + checksum: c9224e08de5d80b2c834383d4359aa9e519db434291711434dd996a4f86b7b664ad67b45d65459b7ec11fa582e3e11a3c769b8a8ca71594bdd4e2f0503f84126 languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-function-name@npm:7.24.1" +"@babel/plugin-transform-function-name@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-function-name@npm:7.27.1" dependencies: - "@babel/helper-compilation-targets": ^7.23.6 - "@babel/helper-function-name": ^7.23.0 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-compilation-targets": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/traverse": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 31eb3c75297dda7265f78eba627c446f2324e30ec0124a645ccc3e9f341254aaa40d6787bd62b2280d77c0a5c9fbfce1da2c200ef7c7f8e0a1b16a8eb3644c6f + checksum: 26a2a183c3c52a96495967420a64afc5a09f743a230272a131668abf23001e393afa6371e6f8e6c60f4182bea210ed31d1caf866452d91009c1daac345a52f23 languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-json-strings@npm:7.24.1" +"@babel/plugin-transform-json-strings@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-json-strings@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-json-strings": ^7.8.3 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f42302d42fc81ac00d14e9e5d80405eb80477d7f9039d7208e712d6bcd486a4e3b32fdfa07b5f027d6c773723d8168193ee880f93b0e430c828e45f104fb82a4 + checksum: 2c05a02f63b49f47069271b3405a66c3c8038de5b995b0700b1bd9a5e2bb3e67abd01e4604629302a521f4d8122a4233944aefa16559fd4373d256cc5d3da57f languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-literals@npm:7.24.1" +"@babel/plugin-transform-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-literals@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2df94e9478571852483aca7588419e574d76bde97583e78551c286f498e01321e7dbb1d0ef67bee16e8f950688f79688809cfde370c5c4b84c14d841a3ef217a + checksum: 0a76d12ab19f32dd139964aea7da48cecdb7de0b75e207e576f0f700121fe92367d788f328bf4fb44b8261a0f605c97b44e62ae61cddbb67b14e94c88b411f95 languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.24.1" +"@babel/plugin-transform-logical-assignment-operators@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 895f2290adf457cbf327428bdb4fb90882a38a22f729bcf0629e8ad66b9b616d2721fbef488ac00411b647489d1dda1d20171bb3772d0796bb7ef5ecf057808a + checksum: 2757955d81d65cc4701c17b83720745f6858f7a1d1d58117e379c204f47adbeb066b778596b6168bdbf4a22c229aab595d79a9abc261d0c6bfd62d4419466e73 languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.1" +"@babel/plugin-transform-member-expression-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4ea641cc14a615f9084e45ad2319f95e2fee01c77ec9789685e7e11a6c286238a426a98f9c1ed91568a047d8ac834393e06e8c82d1ff01764b7aa61bee8e9023 + checksum: 804121430a6dcd431e6ffe99c6d1fbbc44b43478113b79c677629e7f877b4f78a06b69c6bfb2747fd84ee91879fe2eb32e4620b53124603086cf5b727593ebe8 languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-modules-amd@npm:7.24.1" +"@babel/plugin-transform-modules-amd@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-amd@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": ^7.23.3 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-module-transforms": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3d777c262f257e93f0405b13e178f9c4a0f31855b409f0191a76bb562a28c541326a027bfe6467fcb74752f3488c0333b5ff2de64feec1b3c4c6ace1747afa03 + checksum: 8bb36d448e438d5d30f4faf19120e8c18aa87730269e65d805bf6032824d175ed738057cc392c2c8a650028f1ae0f346cad8d6b723f31a037b586e2092a7be18 languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.1" +"@babel/plugin-transform-modules-commonjs@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": ^7.23.3 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-simple-access": ^7.22.5 + "@babel/helper-module-transforms": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 11402b34c49f76aa921b43c2d76f3f129a32544a1dc4f0d1e48b310f9036ab75269a6d8684ed0198b7a0b07bd7898b12f0cacceb26fbb167999fd2a819aa0802 + checksum: bc45c1beff9b145c982bd6a614af338893d38bce18a9df7d658c9084e0d8114b286dcd0e015132ae7b15dd966153cb13321e4800df9766d0ddd892d22bf09d2a languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.24.1" +"@babel/plugin-transform-modules-systemjs@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.27.1" dependencies: - "@babel/helper-hoist-variables": ^7.22.5 - "@babel/helper-module-transforms": ^7.23.3 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-validator-identifier": ^7.22.20 + "@babel/helper-module-transforms": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-validator-identifier": ^7.27.1 + "@babel/traverse": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 903766f6808f04278e887e4adec9b1efa741726279652dad255eaad0f5701df8f8ff0af25eb8541a00eb3c9eae2dccf337b085cfa011426ca33ed1f95d70bf75 + checksum: 7c17a8973676c18525d87f277944616596f1b154cc2b9263bfd78ecdbf5f4288ec46c7f58017321ca3e3d6dfeb96875467b95311a39719b475d42a157525d87f languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-modules-umd@npm:7.24.1" +"@babel/plugin-transform-modules-umd@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-umd@npm:7.27.1" dependencies: - "@babel/helper-module-transforms": ^7.23.3 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-module-transforms": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4922f5056d34de6fd59a1ab1c85bc3472afa706c776aceeb886289c9ac9117e6eb8e22d06c537eb5bc0ede6c30f6bd85210bdcc150dc0ae2d2373f8252df9364 + checksum: b007dd89231f2eeccf1c71a85629bcb692573303977a4b1c5f19a835ea6b5142c18ef07849bc6d752b874a11bc0ddf3c67468b77c8ee8310290b688a4f01ef31 languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5" +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-regexp-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 3ee564ddee620c035b928fdc942c5d17e9c4b98329b76f9cefac65c111135d925eb94ed324064cd7556d4f5123beec79abea1d4b97d1c8a2a5c748887a2eb623 + checksum: a711c92d9753df26cefc1792481e5cbff4fe4f32b383d76b25e36fa865d8023b1b9aa6338cf18f5c0e864c71a7fbe8115e840872ccd61a914d9953849c68de7d languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-new-target@npm:7.24.1" +"@babel/plugin-transform-new-target@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-new-target@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f56159ba56e8824840b8073f65073434e4bc4ef20e366bc03aa6cae9a4389365574fa72390e48aed76049edbc6eba1181eb810e58fae22c25946c62f9da13db4 + checksum: 32c8078d843bda001244509442d68fd3af088d7348ba883f45c262b2c817a27ffc553b0d78e7f7a763271b2ece7fac56151baad7a91fb21f5bb1d2f38e5acad7 languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.1" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 74025e191ceb7cefc619c15d33753aab81300a03d81b96ae249d9b599bc65878f962d608f452462d3aad5d6e334b7ab2b09a6bdcfe8d101fe77ac7aacca4261e + checksum: 1c6b3730748782d2178cc30f5cc37be7d7666148260f3f2dfc43999908bdd319bdfebaaf19cf04ac1f9dee0f7081093d3fa730cda5ae1b34bcd73ce406a78be7 languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.24.1" +"@babel/plugin-transform-numeric-separator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-numeric-separator": ^7.10.4 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3247bd7d409574fc06c59e0eb573ae7470d6d61ecf780df40b550102bb4406747d8f39dcbec57eb59406df6c565a86edd3b429e396ad02e4ce201ad92050832e + checksum: 049b958911de86d32408cd78017940a207e49c054ae9534ab53a32a57122cc592c0aae3c166d6f29bd1a7d75cc779d71883582dd76cb28b2fbb493e842d8ffca languageName: node linkType: hard "@babel/plugin-transform-object-assign@npm:^7.18.6": - version: 7.24.1 - resolution: "@babel/plugin-transform-object-assign@npm:7.24.1" + version: 7.27.1 + resolution: "@babel/plugin-transform-object-assign@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 88f56168f621501dc1aa796d569c76042367c2c3cb2c24f1419ed0783055a393f5722216a87abd9793365a0bd29b42a4e8055e93432c4b3657e6b5a22fe61c6f + checksum: 5541818d80f7f8cf30b1c701a3b3c8b2112b51d894ba6c7ad1012c8d0477a3a3445f66a7d5539238d4df3c17ee23b20b82e33f3a8e66fb0e3d8467f4901d65e0 languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.1" +"@babel/plugin-transform-object-rest-spread@npm:^7.28.0": + version: 7.28.4 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.4" dependencies: - "@babel/helper-compilation-targets": ^7.23.6 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-object-rest-spread": ^7.8.3 - "@babel/plugin-transform-parameters": ^7.24.1 + "@babel/helper-compilation-targets": ^7.27.2 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/plugin-transform-destructuring": ^7.28.0 + "@babel/plugin-transform-parameters": ^7.27.7 + "@babel/traverse": ^7.28.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d5d28b1f33c279a38299d34011421a4915e24b3846aa23a1aba947f1366ce673ddf8df09dd915e0f2c90c5327f798bf126dca013f8adff1fc8f09e18878b675a + checksum: 2063672ba4ac457a64b5c0c982439c7b08b4c70f0e743792b98240db5a05f1c063918d8366c92d4d6b2572e2e3452b300a23980b6668e4f54ff349f60d47ec48 languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-object-super@npm:7.24.1" +"@babel/plugin-transform-object-super@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-object-super@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-replace-supers": ^7.24.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-replace-supers": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d34d437456a54e2a5dcb26e9cf09ed4c55528f2a327c5edca92c93e9483c37176e228d00d6e0cf767f3d6fdbef45ae3a5d034a7c59337a009e20ae541c8220fa + checksum: 46b819cb9a6cd3cfefe42d07875fee414f18d5e66040366ae856116db560ad4e16f3899a0a7fddd6773e0d1458444f94b208b67c0e3b6977a27ea17a5c13dbf6 languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.1" +"@babel/plugin-transform-optional-catch-binding@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ff7c02449d32a6de41e003abb38537b4a1ad90b1eaa4c0b578cb1b55548201a677588a8c47f3e161c72738400ae811a6673ea7b8a734344755016ca0ac445dac + checksum: f4356b04cf21a98480f9788ea50f1f13ee88e89bb6393ba4b84d1f39a4a84c7928c9a4328e8f4c5b6deb218da68a8fd17bf4f46faec7653ddc20ffaaa5ba49f4 languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.1" +"@babel/plugin-transform-optional-chaining@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 - "@babel/plugin-syntax-optional-chaining": ^7.8.3 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0eb5f4abdeb1a101c0f67ef25eba4cce0978a74d8722f6222cdb179a28e60d21ab545eda231855f50169cd63d604ec8268cff44ae9370fd3a499a507c56c2bbd + checksum: c4428d31f182d724db6f10575669aad3dbccceb0dea26aa9071fa89f11b3456278da3097fcc78937639a13c105a82cd452dc0218ce51abdbcf7626a013b928a5 languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-parameters@npm:7.24.1" +"@babel/plugin-transform-parameters@npm:^7.27.7": + version: 7.27.7 + resolution: "@babel/plugin-transform-parameters@npm:7.27.7" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d183008e67b1a13b86c92fb64327a75cd8e13c13eb80d0b6952e15806f1b0c4c456d18360e451c6af73485b2c8f543608b0a29e5126c64eb625a31e970b65f80 + checksum: d51f195e1d6ac5d9fce583e9a70a5bfe403e62386e5eb06db9fbc6533f895a98ff7e7c3dcaa311a8e6fa7a9794466e81cdabcba6af9f59d787fb767bfe7868b4 languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-private-methods@npm:7.24.1" +"@babel/plugin-transform-private-methods@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-private-methods@npm:7.27.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.24.1 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-create-class-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7208c30bb3f3fbc73fb3a88bdcb78cd5cddaf6d523eb9d67c0c04e78f6fc6319ece89f4a5abc41777ceab16df55b3a13a4120e0efc9275ca6d2d89beaba80aa0 + checksum: c76f8f6056946466116e67eb9d8014a2d748ade2062636ab82045c1dac9c233aff10e597777bc5af6f26428beb845ceb41b95007abef7d0484da95789da56662 languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.24.1" +"@babel/plugin-transform-private-property-in-object@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-create-class-features-plugin": ^7.24.1 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-private-property-in-object": ^7.14.5 + "@babel/helper-annotate-as-pure": ^7.27.1 + "@babel/helper-create-class-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 47c123ca9975f7f6b20e6fe8fe89f621cd04b622539faf5ec037e2be7c3d53ce2506f7c785b1930dcdea11994eff79094a02715795218c7d6a0bdc11f2fb3ac2 + checksum: af539af1bd423aa46b9da83d649be716494ca80783841f47094b6741fa24e11141446027fd152ddff791dede9d4a76d0d5eb467402a2e584d7f5ea90e2673c7e languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-property-literals@npm:7.24.1" +"@babel/plugin-transform-property-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-property-literals@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a73646d7ecd95b3931a3ead82c7d5efeb46e68ba362de63eb437d33531f294ec18bd31b6d24238cd3b6a3b919a6310c4a0ba4a2629927721d4d10b0518eb7715 + checksum: 7caec27d5ed8870895c9faf4f71def72745d69da0d8e77903146a4e135fd7bed5778f5f9cebb36c5fba86338e6194dd67a08c033fc84b4299b7eceab6d9630cb languageName: node linkType: hard "@babel/plugin-transform-react-constant-elements@npm:^7.12.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-react-constant-elements@npm:7.24.1" + version: 7.27.1 + resolution: "@babel/plugin-transform-react-constant-elements@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 37fd10113b786a2462cf15366aa3a11a2a5bdba9bf8881b2544941f5ad6175ebc31116be5a53549c9fce56a08ded6e0b57adb45d6e42efb55d3bc0ff7afdd433 + checksum: 8372cf17ed551cd2e3da4f32a211881265692a17ad4c4fd40a8adcb89316d147db54f023630022ad7ec7474c4108647f67e3a62db43e515246a7574dcb5eeefe languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.16.0, @babel/plugin-transform-react-display-name@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-react-display-name@npm:7.24.1" +"@babel/plugin-transform-react-display-name@npm:^7.16.0, @babel/plugin-transform-react-display-name@npm:^7.27.1": + version: 7.28.0 + resolution: "@babel/plugin-transform-react-display-name@npm:7.28.0" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d87ac36073f923a25de0ed3cffac067ec5abc4cde63f7f4366881388fbea6dcbced0e4fefd3b7e99edfe58a4ce32ea4d4c523a577d2b9f0515b872ed02b3d8c3 + checksum: 268b1a9192974439d17949e170b01cac2a2aa003c844e2fe3b8361146f42f66487178cffdfa8ce862aa9e6c814bc37f879a70300cb3f067815d15fa6aad04e6d languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-development@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5" +"@babel/plugin-transform-react-jsx-development@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.27.1" dependencies: - "@babel/plugin-transform-react-jsx": ^7.22.5 + "@babel/plugin-transform-react-jsx": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 36bc3ff0b96bb0ef4723070a50cfdf2e72cfd903a59eba448f9fe92fea47574d6f22efd99364413719e1f3fb3c51b6c9b2990b87af088f8486a84b2a5f9e4560 + checksum: b88865d5b8c018992f2332da939faa15c4d4a864c9435a5937beaff3fe43781432cc42e0a5d5631098e0bd4066fc33f5fa72203b388b074c3545fe7aaa21e474 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-self@npm:^7.23.3": - version: 7.24.1 - resolution: "@babel/plugin-transform-react-jsx-self@npm:7.24.1" +"@babel/plugin-transform-react-jsx-self@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-jsx-self@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a0ff893b946bb0e501ad5aab43ce4b321ed9e74b94c0bc7191e2ee6409014fc96ee1a47dcb1ecdf445c44868564667ae16507ed4516dcacf6aa9c37a0ad28382 + checksum: 72cbae66a58c6c36f7e12e8ed79f292192d858dd4bb00e9e89d8b695e4c5cb6ef48eec84bffff421a5db93fd10412c581f1cccdb00264065df76f121995bdb68 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-source@npm:^7.23.3": - version: 7.24.1 - resolution: "@babel/plugin-transform-react-jsx-source@npm:7.24.1" +"@babel/plugin-transform-react-jsx-source@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-jsx-source@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 396ce878dc588e74113d38c5a1773e0850bb878a073238a74f8cdf62d968d56a644f5485bf4032dc095fe8863fe2bd9fbbbab6abc3adf69542e038ac5c689d4c + checksum: e2843362adb53692be5ee9fa07a386d2d8883daad2063a3575b3c373fc14cdf4ea7978c67a183cb631b4c9c8d77b2f48c24c088f8e65cc3600cb8e97d72a7161 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.22.5, @babel/plugin-transform-react-jsx@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/plugin-transform-react-jsx@npm:7.23.4" +"@babel/plugin-transform-react-jsx@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-jsx@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-module-imports": ^7.22.15 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/plugin-syntax-jsx": ^7.23.3 - "@babel/types": ^7.23.4 + "@babel/helper-annotate-as-pure": ^7.27.1 + "@babel/helper-module-imports": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/plugin-syntax-jsx": ^7.27.1 + "@babel/types": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d8b8c52e8e22e833bf77c8d1a53b0a57d1fd52ba9596a319d572de79446a8ed9d95521035bc1175c1589d1a6a34600d2e678fa81d81bac8fac121137097f1f0a + checksum: 960d36e5d11ba68e4fbf1e2b935c153cb6ea7b0004f838aaee8baf7de30462b8f0562743a39ce3c370cc70b8f79d3c549104a415a615b2b0055b71fd025df0f3 languageName: node linkType: hard -"@babel/plugin-transform-react-pure-annotations@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.24.1" +"@babel/plugin-transform-react-pure-annotations@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-annotate-as-pure": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 06a6bfe80f1f36408d07dd80c48cf9f61177c8e5d814e80ddbe88cfad81a8b86b3110e1fe9d1ac943db77e74497daa7f874b5490c788707106ad26ecfbe44813 + checksum: a6f591c5e85a1ab0685d4a25afe591fe8d11dc0b73c677cf9560ff8d540d036a1cce9efcb729fc9092def4d854dc304ffdc063a89a9247900b69c516bf971a4c languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-regenerator@npm:7.24.1" +"@babel/plugin-transform-regenerator@npm:^7.28.3": + version: 7.28.4 + resolution: "@babel/plugin-transform-regenerator@npm:7.28.4" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - regenerator-transform: ^0.15.2 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a04319388a0a7931c3f8e15715d01444c32519692178b70deccc86d53304e74c0f589a4268f6c68578d86f75e934dd1fe6e6ed9071f54ee8379f356f88ef6e42 + checksum: 2aa99b3a7b254a109e913fabbe1fb320ff40723988fde0e225212b7ef20f523a399a6e45077258b176c29715493b2a853cf7c130811692215adf33e5af99782b + languageName: node + linkType: hard + +"@babel/plugin-transform-regexp-modifiers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.27.1" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: f6cb385fe0e798bff7e9b20cf5912bf40e180895ff3610b1ccdce260f3c20daaebb3a99dc087c8168a99151cd3e16b94f4689fd5a4b01cf1834b45c133e620b2 languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-reserved-words@npm:7.24.1" +"@babel/plugin-transform-reserved-words@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-reserved-words@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 132c6040c65aabae2d98a39289efb5c51a8632546dc50d2ad032c8660aec307fbed74ef499856ea4f881fc8505905f49b48e0270585da2ea3d50b75e962afd89 + checksum: dea0b66742d2863b369c06c053e11e15ba785892ea19cccf7aef3c1bdaa38b6ab082e19984c5ea7810d275d9445c5400fcc385ad71ce707ed9256fadb102af3b languageName: node linkType: hard "@babel/plugin-transform-runtime@npm:^7.16.4": - version: 7.24.3 - resolution: "@babel/plugin-transform-runtime@npm:7.24.3" - dependencies: - "@babel/helper-module-imports": ^7.24.3 - "@babel/helper-plugin-utils": ^7.24.0 - babel-plugin-polyfill-corejs2: ^0.4.10 - babel-plugin-polyfill-corejs3: ^0.10.1 - babel-plugin-polyfill-regenerator: ^0.6.1 + version: 7.28.3 + resolution: "@babel/plugin-transform-runtime@npm:7.28.3" + dependencies: + "@babel/helper-module-imports": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + babel-plugin-polyfill-corejs2: ^0.4.14 + babel-plugin-polyfill-corejs3: ^0.13.0 + babel-plugin-polyfill-regenerator: ^0.6.5 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 719112524e6fe3e665385ad4425530dadb2ddee839023381ed9d77edf5ce2748f32cc0e38dacda1990c56a7ae0af4de6cdca2413ffaf307e9f75f8d2200d09a2 + checksum: 63d2fc05d5bfcb96f31be54b095d72a89f0a03c8de10f5d742b18b174e2731bcdc27292e8deec66c2e88cebf8298393123d5e767526f6fffbc75cb8144ef66c6 languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.1" +"@babel/plugin-transform-shorthand-properties@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 006a2032d1c57dca76579ce6598c679c2f20525afef0a36e9d42affe3c8cf33c1427581ad696b519cc75dfee46c5e8ecdf0c6a29ffb14250caa3e16dd68cb424 + checksum: fbba6e2aef0b69681acb68202aa249c0598e470cc0853d7ff5bd0171fd6a7ec31d77cfabcce9df6360fc8349eded7e4a65218c32551bd3fc0caaa1ac899ac6d4 languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-spread@npm:7.24.1" +"@babel/plugin-transform-spread@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-spread@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 622ef507e2b5120a9010b25d3df5186c06102ecad8751724a38ec924df8d3527688198fa490c47064eabba14ef2f961b3069855bd22a8c0a1e51a23eed348d02 + checksum: 58b08085ee9c29955ac3b68d61c1a79728d44d19a69cb5eb669794aeaf54c57c6647af7b979c1297e81ede3d08b3ddcb1936ef39a533f28ff3e399a9be54dab1 languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.24.1" +"@babel/plugin-transform-sticky-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e326e96a9eeb6bb01dbc4d3362f989411490671b97f62edf378b8fb102c463a018b777f28da65344d41b22aa6efcdfa01ed43d2b11fdcf202046d3174be137c5 + checksum: e1414a502efba92c7974681767e365a8cda6c5e9e5f33472a9eaa0ce2e75cea0a9bef881ff8dda37c7810ad902f98d3c00ead92a3ac3b73a79d011df85b5a189 languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-template-literals@npm:7.24.1" +"@babel/plugin-transform-template-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-template-literals@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4c9009c72321caf20e3b6328bbe9d7057006c5ae57b794cf247a37ca34d87dfec5e27284169a16df5a6235a083bf0f3ab9e1bfcb005d1c8b75b04aed75652621 + checksum: 93aad782503b691faef7c0893372d5243df3219b07f1f22cfc32c104af6a2e7acd6102c128439eab15336d048f1b214ca134b87b0630d8cd568bf447f78b25ce languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.1" +"@babel/plugin-transform-typeof-symbol@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 90251c02986aebe50937522a6e404cb83db1b1feda17c0244e97d6429ded1634340c8411536487d14c54495607e1b7c9dc4db4aed969d519f1ff1e363f9c2229 + checksum: ed8048c8de72c60969a64cf2273cc6d9275d8fa8db9bd25a1268273a00fb9cbd79931140311411bda1443aa56cb3961fb911d1795abacde7f0482f1d8fdf0356 languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.24.1": - version: 7.24.4 - resolution: "@babel/plugin-transform-typescript@npm:7.24.4" +"@babel/plugin-transform-typescript@npm:^7.27.1": + version: 7.28.0 + resolution: "@babel/plugin-transform-typescript@npm:7.28.0" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-create-class-features-plugin": ^7.24.4 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/plugin-syntax-typescript": ^7.24.1 + "@babel/helper-annotate-as-pure": ^7.27.3 + "@babel/helper-create-class-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 + "@babel/plugin-syntax-typescript": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 57a9a776b1910c706d28972e4b056ced3af8fc59c29b2a6205c2bb2a408141ddb59a8f2f6041f8467a7b260942818767f4ecabb9f63adf7fddf2afa25e774dfc + checksum: 14c1024bcd57fcd469d90cf0c15c3cd4e771e2eb2cd9afee3aa79b59c8ed103654f7c5c71cdb3bfe31c1d0cb08bfad8c80f5aa1d24b4b454bd21301d5925533d languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.24.1" +"@babel/plugin-transform-unicode-escapes@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d4d7cfea91af7be2768fb6bed902e00d6e3190bda738b5149c3a788d570e6cf48b974ec9548442850308ecd8fc9a67681f4ea8403129e7867bcb85adaf6ec238 + checksum: d817154bc10758ddd85b716e0bc1af1a1091e088400289ab6b78a1a4d609907ce3d2f1fd51a6fd0e0c8ecbb5f8e3aab4957e0747776d132d2379e85c3ef0520a languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.24.1" +"@babel/plugin-transform-unicode-property-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.15 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-create-regexp-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 276099b4483e707f80b054e2d29bc519158bfe52461ef5ff76f70727d592df17e30b1597ef4d8a0f04d810f6cb5a8dd887bdc1d0540af3744751710ef280090f + checksum: 5d99c89537d1ebaac3f526c04b162cf95a47d363d4829f78c6701a2c06ab78a48da66a94f853f85f44a3d72153410ba923e072bed4b7166fa097f503eb14131d languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.24.1" +"@babel/plugin-transform-unicode-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.15 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-create-regexp-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 400a0927bdb1425b4c0dc68a61b5b2d7d17c7d9f0e07317a1a6a373c080ef94be1dd65fdc4ac9a78fcdb58f89fd128450c7bc0d5b8ca0ae7eca3fbd98e50acba + checksum: a34d89a2b75fb78e66d97c3dc90d4877f7e31f43316b52176f95a5dee20e9bb56ecf158eafc42a001676ddf7b393d9e67650bad6b32f5405780f25fb83cd68e3 languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.24.1" +"@babel/plugin-transform-unicode-sets-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.27.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.15 - "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-create-regexp-features-plugin": ^7.27.1 + "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 364342fb8e382dfaa23628b88e6484dc1097e53fb7199f4d338f1e2cd71d839bb0a35a9b1380074f6a10adb2e98b79d53ca3ec78c0b8c557ca895ffff42180df + checksum: 295126074c7388ab05c82ef3ed0907a1ee4666bbdd763477ead9aba6eb2c74bdf65669416861ac93d337a4a27640963bb214acadc2697275ce95aab14868d57f languageName: node linkType: hard -"@babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.16.4, @babel/preset-env@npm:^7.8.4": - version: 7.24.4 - resolution: "@babel/preset-env@npm:7.24.4" +"@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.16.4": + version: 7.28.3 + resolution: "@babel/preset-env@npm:7.28.3" dependencies: - "@babel/compat-data": ^7.24.4 - "@babel/helper-compilation-targets": ^7.23.6 - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-validator-option": ^7.23.5 - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ^7.24.4 - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.24.1 - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.24.1 - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.24.1 + "@babel/compat-data": ^7.28.0 + "@babel/helper-compilation-targets": ^7.27.2 + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-validator-option": ^7.27.1 + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ^7.27.1 + "@babel/plugin-bugfix-safari-class-field-initializer-scope": ^7.27.1 + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.27.1 + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.27.1 + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.28.3 "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 - "@babel/plugin-syntax-async-generators": ^7.8.4 - "@babel/plugin-syntax-class-properties": ^7.12.13 - "@babel/plugin-syntax-class-static-block": ^7.14.5 - "@babel/plugin-syntax-dynamic-import": ^7.8.3 - "@babel/plugin-syntax-export-namespace-from": ^7.8.3 - "@babel/plugin-syntax-import-assertions": ^7.24.1 - "@babel/plugin-syntax-import-attributes": ^7.24.1 - "@babel/plugin-syntax-import-meta": ^7.10.4 - "@babel/plugin-syntax-json-strings": ^7.8.3 - "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 - "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 - "@babel/plugin-syntax-numeric-separator": ^7.10.4 - "@babel/plugin-syntax-object-rest-spread": ^7.8.3 - "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 - "@babel/plugin-syntax-optional-chaining": ^7.8.3 - "@babel/plugin-syntax-private-property-in-object": ^7.14.5 - "@babel/plugin-syntax-top-level-await": ^7.14.5 + "@babel/plugin-syntax-import-assertions": ^7.27.1 + "@babel/plugin-syntax-import-attributes": ^7.27.1 "@babel/plugin-syntax-unicode-sets-regex": ^7.18.6 - "@babel/plugin-transform-arrow-functions": ^7.24.1 - "@babel/plugin-transform-async-generator-functions": ^7.24.3 - "@babel/plugin-transform-async-to-generator": ^7.24.1 - "@babel/plugin-transform-block-scoped-functions": ^7.24.1 - "@babel/plugin-transform-block-scoping": ^7.24.4 - "@babel/plugin-transform-class-properties": ^7.24.1 - "@babel/plugin-transform-class-static-block": ^7.24.4 - "@babel/plugin-transform-classes": ^7.24.1 - "@babel/plugin-transform-computed-properties": ^7.24.1 - "@babel/plugin-transform-destructuring": ^7.24.1 - "@babel/plugin-transform-dotall-regex": ^7.24.1 - "@babel/plugin-transform-duplicate-keys": ^7.24.1 - "@babel/plugin-transform-dynamic-import": ^7.24.1 - "@babel/plugin-transform-exponentiation-operator": ^7.24.1 - "@babel/plugin-transform-export-namespace-from": ^7.24.1 - "@babel/plugin-transform-for-of": ^7.24.1 - "@babel/plugin-transform-function-name": ^7.24.1 - "@babel/plugin-transform-json-strings": ^7.24.1 - "@babel/plugin-transform-literals": ^7.24.1 - "@babel/plugin-transform-logical-assignment-operators": ^7.24.1 - "@babel/plugin-transform-member-expression-literals": ^7.24.1 - "@babel/plugin-transform-modules-amd": ^7.24.1 - "@babel/plugin-transform-modules-commonjs": ^7.24.1 - "@babel/plugin-transform-modules-systemjs": ^7.24.1 - "@babel/plugin-transform-modules-umd": ^7.24.1 - "@babel/plugin-transform-named-capturing-groups-regex": ^7.22.5 - "@babel/plugin-transform-new-target": ^7.24.1 - "@babel/plugin-transform-nullish-coalescing-operator": ^7.24.1 - "@babel/plugin-transform-numeric-separator": ^7.24.1 - "@babel/plugin-transform-object-rest-spread": ^7.24.1 - "@babel/plugin-transform-object-super": ^7.24.1 - "@babel/plugin-transform-optional-catch-binding": ^7.24.1 - "@babel/plugin-transform-optional-chaining": ^7.24.1 - "@babel/plugin-transform-parameters": ^7.24.1 - "@babel/plugin-transform-private-methods": ^7.24.1 - "@babel/plugin-transform-private-property-in-object": ^7.24.1 - "@babel/plugin-transform-property-literals": ^7.24.1 - "@babel/plugin-transform-regenerator": ^7.24.1 - "@babel/plugin-transform-reserved-words": ^7.24.1 - "@babel/plugin-transform-shorthand-properties": ^7.24.1 - "@babel/plugin-transform-spread": ^7.24.1 - "@babel/plugin-transform-sticky-regex": ^7.24.1 - "@babel/plugin-transform-template-literals": ^7.24.1 - "@babel/plugin-transform-typeof-symbol": ^7.24.1 - "@babel/plugin-transform-unicode-escapes": ^7.24.1 - "@babel/plugin-transform-unicode-property-regex": ^7.24.1 - "@babel/plugin-transform-unicode-regex": ^7.24.1 - "@babel/plugin-transform-unicode-sets-regex": ^7.24.1 + "@babel/plugin-transform-arrow-functions": ^7.27.1 + "@babel/plugin-transform-async-generator-functions": ^7.28.0 + "@babel/plugin-transform-async-to-generator": ^7.27.1 + "@babel/plugin-transform-block-scoped-functions": ^7.27.1 + "@babel/plugin-transform-block-scoping": ^7.28.0 + "@babel/plugin-transform-class-properties": ^7.27.1 + "@babel/plugin-transform-class-static-block": ^7.28.3 + "@babel/plugin-transform-classes": ^7.28.3 + "@babel/plugin-transform-computed-properties": ^7.27.1 + "@babel/plugin-transform-destructuring": ^7.28.0 + "@babel/plugin-transform-dotall-regex": ^7.27.1 + "@babel/plugin-transform-duplicate-keys": ^7.27.1 + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ^7.27.1 + "@babel/plugin-transform-dynamic-import": ^7.27.1 + "@babel/plugin-transform-explicit-resource-management": ^7.28.0 + "@babel/plugin-transform-exponentiation-operator": ^7.27.1 + "@babel/plugin-transform-export-namespace-from": ^7.27.1 + "@babel/plugin-transform-for-of": ^7.27.1 + "@babel/plugin-transform-function-name": ^7.27.1 + "@babel/plugin-transform-json-strings": ^7.27.1 + "@babel/plugin-transform-literals": ^7.27.1 + "@babel/plugin-transform-logical-assignment-operators": ^7.27.1 + "@babel/plugin-transform-member-expression-literals": ^7.27.1 + "@babel/plugin-transform-modules-amd": ^7.27.1 + "@babel/plugin-transform-modules-commonjs": ^7.27.1 + "@babel/plugin-transform-modules-systemjs": ^7.27.1 + "@babel/plugin-transform-modules-umd": ^7.27.1 + "@babel/plugin-transform-named-capturing-groups-regex": ^7.27.1 + "@babel/plugin-transform-new-target": ^7.27.1 + "@babel/plugin-transform-nullish-coalescing-operator": ^7.27.1 + "@babel/plugin-transform-numeric-separator": ^7.27.1 + "@babel/plugin-transform-object-rest-spread": ^7.28.0 + "@babel/plugin-transform-object-super": ^7.27.1 + "@babel/plugin-transform-optional-catch-binding": ^7.27.1 + "@babel/plugin-transform-optional-chaining": ^7.27.1 + "@babel/plugin-transform-parameters": ^7.27.7 + "@babel/plugin-transform-private-methods": ^7.27.1 + "@babel/plugin-transform-private-property-in-object": ^7.27.1 + "@babel/plugin-transform-property-literals": ^7.27.1 + "@babel/plugin-transform-regenerator": ^7.28.3 + "@babel/plugin-transform-regexp-modifiers": ^7.27.1 + "@babel/plugin-transform-reserved-words": ^7.27.1 + "@babel/plugin-transform-shorthand-properties": ^7.27.1 + "@babel/plugin-transform-spread": ^7.27.1 + "@babel/plugin-transform-sticky-regex": ^7.27.1 + "@babel/plugin-transform-template-literals": ^7.27.1 + "@babel/plugin-transform-typeof-symbol": ^7.27.1 + "@babel/plugin-transform-unicode-escapes": ^7.27.1 + "@babel/plugin-transform-unicode-property-regex": ^7.27.1 + "@babel/plugin-transform-unicode-regex": ^7.27.1 + "@babel/plugin-transform-unicode-sets-regex": ^7.27.1 "@babel/preset-modules": 0.1.6-no-external-plugins - babel-plugin-polyfill-corejs2: ^0.4.10 - babel-plugin-polyfill-corejs3: ^0.10.4 - babel-plugin-polyfill-regenerator: ^0.6.1 - core-js-compat: ^3.31.0 + babel-plugin-polyfill-corejs2: ^0.4.14 + babel-plugin-polyfill-corejs3: ^0.13.0 + babel-plugin-polyfill-regenerator: ^0.6.5 + core-js-compat: ^3.43.0 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5a057a6463f92b02bfe66257d3f2c76878815bc7847f2a716b0539d9f547eae2a9d1f0fc62a5c0eff6ab0504bb52e815829ef893e4586b641f8dd6a609d114f3 + checksum: c4e70f69b727d21eedd4de201ac082e951482f2d28a388e401e7937fd6f15bc1a49a63c12f59e87a18d237ac037a5b29d983f3bb82f1196d6444ae5b605ac6e2 languageName: node linkType: hard @@ -1611,99 +2036,76 @@ __metadata: linkType: hard "@babel/preset-react@npm:^7.12.5, @babel/preset-react@npm:^7.16.0, @babel/preset-react@npm:^7.18.6": - version: 7.24.1 - resolution: "@babel/preset-react@npm:7.24.1" - dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-validator-option": ^7.23.5 - "@babel/plugin-transform-react-display-name": ^7.24.1 - "@babel/plugin-transform-react-jsx": ^7.23.4 - "@babel/plugin-transform-react-jsx-development": ^7.22.5 - "@babel/plugin-transform-react-pure-annotations": ^7.24.1 + version: 7.27.1 + resolution: "@babel/preset-react@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-validator-option": ^7.27.1 + "@babel/plugin-transform-react-display-name": ^7.27.1 + "@babel/plugin-transform-react-jsx": ^7.27.1 + "@babel/plugin-transform-react-jsx-development": ^7.27.1 + "@babel/plugin-transform-react-pure-annotations": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 70e146a6de480cb4b6c5eb197003960a2d148d513e1f5b5d04ee954f255d68c935c2800da13e550267f47b894bd0214b2548181467b52a4bdc0a85020061b68c + checksum: 00bc146f9c742eed804c598d3f31b7d889c1baf8c768989b7f84a93ca527dd1518d3b86781e89ca45cae6dbee136510d3a121658e01416c5578aecf751517bb5 languageName: node linkType: hard "@babel/preset-typescript@npm:^7.16.0, @babel/preset-typescript@npm:^7.18.6": - version: 7.24.1 - resolution: "@babel/preset-typescript@npm:7.24.1" - dependencies: - "@babel/helper-plugin-utils": ^7.24.0 - "@babel/helper-validator-option": ^7.23.5 - "@babel/plugin-syntax-jsx": ^7.24.1 - "@babel/plugin-transform-modules-commonjs": ^7.24.1 - "@babel/plugin-transform-typescript": ^7.24.1 + version: 7.27.1 + resolution: "@babel/preset-typescript@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": ^7.27.1 + "@babel/helper-validator-option": ^7.27.1 + "@babel/plugin-syntax-jsx": ^7.27.1 + "@babel/plugin-transform-modules-commonjs": ^7.27.1 + "@babel/plugin-transform-typescript": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f3e0ff8c20dd5abc82614df2d7953f1549a98282b60809478f7dfb41c29be63720f2d1d7a51ef1f0d939b65e8666cb7d36e32bc4f8ac2b74c20664efd41e8bdd - languageName: node - linkType: hard - -"@babel/regjsgen@npm:^0.8.0": - version: 0.8.0 - resolution: "@babel/regjsgen@npm:0.8.0" - checksum: 89c338fee774770e5a487382170711014d49a68eb281e74f2b5eac88f38300a4ad545516a7786a8dd5702e9cf009c94c2f582d200f077ac5decd74c56b973730 - languageName: node - linkType: hard - -"@babel/runtime-corejs3@npm:^7.10.2": - version: 7.24.4 - resolution: "@babel/runtime-corejs3@npm:7.24.4" - dependencies: - core-js-pure: ^3.30.2 - regenerator-runtime: ^0.14.0 - checksum: 0c2e7c477de3dbf5cc6f2434cee3d78a34d87e8f1e2ea65840eb948d00f7d6968e0ef055449adf372a39d6214f8b9b2532506149b9d0e7ea3d09b1b84678ae6c + checksum: 38020f1b23e88ec4fbffd5737da455d8939244bddfb48a2516aef93fb5947bd9163fb807ce6eff3e43fa5ffe9113aa131305fef0fb5053998410bbfcfe6ce0ec languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.24.4 - resolution: "@babel/runtime@npm:7.24.4" - dependencies: - regenerator-runtime: ^0.14.0 - checksum: 2f27d4c0ffac7ae7999ac0385e1106f2a06992a8bdcbf3da06adcac7413863cd08c198c2e4e970041bbea849e17f02e1df18875539b6afba76c781b6b59a07c3 +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.28.3, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.7": + version: 7.28.4 + resolution: "@babel/runtime@npm:7.28.4" + checksum: 934b0a0460f7d06637d93fcd1a44ac49adc33518d17253b5a0b55ff4cb90a45d8fe78bf034b448911dbec7aff2a90b918697559f78d21c99ff8dbadae9565b55 languageName: node linkType: hard -"@babel/template@npm:^7.10.4, @babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0, @babel/template@npm:^7.3.3": - version: 7.24.0 - resolution: "@babel/template@npm:7.24.0" +"@babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": + version: 7.27.2 + resolution: "@babel/template@npm:7.27.2" dependencies: - "@babel/code-frame": ^7.23.5 - "@babel/parser": ^7.24.0 - "@babel/types": ^7.24.0 - checksum: f257b003c071a0cecdbfceca74185f18fe62c055469ab5c1d481aab12abeebed328e67e0a19fd978a2a8de97b28953fa4bc3da6d038a7345fdf37923b9fcdec8 + "@babel/code-frame": ^7.27.1 + "@babel/parser": ^7.27.2 + "@babel/types": ^7.27.1 + checksum: ff5628bc066060624afd970616090e5bba91c6240c2e4b458d13267a523572cbfcbf549391eec8217b94b064cf96571c6273f0c04b28a8567b96edc675c28e27 languageName: node linkType: hard -"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.12.1, @babel/traverse@npm:^7.24.1, @babel/traverse@npm:^7.7.0": - version: 7.24.1 - resolution: "@babel/traverse@npm:7.24.1" +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.7.2": + version: 7.28.4 + resolution: "@babel/traverse@npm:7.28.4" dependencies: - "@babel/code-frame": ^7.24.1 - "@babel/generator": ^7.24.1 - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-function-name": ^7.23.0 - "@babel/helper-hoist-variables": ^7.22.5 - "@babel/helper-split-export-declaration": ^7.22.6 - "@babel/parser": ^7.24.1 - "@babel/types": ^7.24.0 + "@babel/code-frame": ^7.27.1 + "@babel/generator": ^7.28.3 + "@babel/helper-globals": ^7.28.0 + "@babel/parser": ^7.28.4 + "@babel/template": ^7.27.2 + "@babel/types": ^7.28.4 debug: ^4.3.1 - globals: ^11.1.0 - checksum: 92a5ca906abfba9df17666d2001ab23f18600035f706a687055a0e392a690ae48d6fec67c8bd4ef19ba18699a77a5b7f85727e36b83f7d110141608fe0c24fe9 + checksum: d603b8ce4e55ba4fc7b28d3362cc2b1b20bc887e471c8a59fe87b2578c26803c9ef8fcd118081dd8283ea78e0e9a6df9d88c8520033c6aaf81eec30d2a669151 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.1, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0, @babel/types@npm:^7.8.3": - version: 7.24.0 - resolution: "@babel/types@npm:7.24.0" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": + version: 7.28.4 + resolution: "@babel/types@npm:7.28.4" dependencies: - "@babel/helper-string-parser": ^7.23.4 - "@babel/helper-validator-identifier": ^7.22.20 - to-fast-properties: ^2.0.0 - checksum: 4b574a37d490f621470ff36a5afaac6deca5546edcb9b5e316d39acbb20998e9c2be42f3fc0bf2b55906fc49ff2a5a6a097e8f5a726ee3f708a0b0ca93aed807 + "@babel/helper-string-parser": ^7.27.1 + "@babel/helper-validator-identifier": ^7.27.1 + checksum: a369b4fb73415a2ed902a15576b49696ae9777ddee394a7a904c62e6fbb31f43906b0147ae0b8f03ac17f20c248eac093df349e33c65c94617b12e524b759694 languageName: node linkType: hard @@ -1714,15 +2116,21 @@ __metadata: languageName: node linkType: hard -"@cnakazawa/watch@npm:^1.0.3": - version: 1.0.4 - resolution: "@cnakazawa/watch@npm:1.0.4" +"@bundled-es-modules/cookie@npm:^2.0.1": + version: 2.0.1 + resolution: "@bundled-es-modules/cookie@npm:2.0.1" dependencies: - exec-sh: ^0.3.2 - minimist: ^1.2.0 - bin: - watch: cli.js - checksum: 88f395ca0af2f3c0665b8ce7bb29e83647ec5d141e8735712aeeee4117081555436712966b6957aa1c461f6f826a4d23b0034e379c443a10e919f81c8748bf29 + cookie: ^0.7.2 + checksum: 4f210f9316a612f03a46c58f0e3de14b2598f36905433b5ac91e305a4185bd3cb0b141622fa54cff2fce18adbac0b5a8df67dca1874aabd81b7a631fc826e116 + languageName: node + linkType: hard + +"@bundled-es-modules/statuses@npm:^1.0.1": + version: 1.0.1 + resolution: "@bundled-es-modules/statuses@npm:1.0.1" + dependencies: + statuses: ^2.0.1 + checksum: bcaa7de192e73056950b5fd20e75140d8d09074b1adc4437924b2051bb02b4dbf568c96e67d53b220fb7d735c3446e2ba746599cb1793ab2d23dd2ef230a8622 languageName: node linkType: hard @@ -1735,727 +2143,1543 @@ __metadata: languageName: node linkType: hard -"@csstools/convert-colors@npm:^1.4.0": - version: 1.4.0 - resolution: "@csstools/convert-colors@npm:1.4.0" - checksum: 26069eeb845a506934c821c203feb97f5de634c5fbeb9978505a2271d6cfdb0ce400240fca9620a4ef2e68953928ea25aab92ea8454e0edf5cd074066d9ad57b +"@csstools/normalize.css@npm:*": + version: 12.1.1 + resolution: "@csstools/normalize.css@npm:12.1.1" + checksum: a356ee0fcb922f3e0bc23df4468bb4f27fc26c767e25359c079455fe30301d253d8a60c443859b04350c8174393edbb11bad2a9ef2f8cce0e371f6abf6c7ef36 languageName: node linkType: hard -"@csstools/normalize.css@npm:^10.1.0": - version: 10.1.0 - resolution: "@csstools/normalize.css@npm:10.1.0" - checksum: c0adedd58e16b73b6588377ca505bfbc3f6273ab1ba1b55dd343aa5e4c0bf81bd74f051a1317a0d383bdcd59af665ba34db00b0c51c7dbc176c1a536175c2b03 +"@csstools/postcss-cascade-layers@npm:^1.1.1": + version: 1.1.1 + resolution: "@csstools/postcss-cascade-layers@npm:1.1.1" + dependencies: + "@csstools/selector-specificity": ^2.0.2 + postcss-selector-parser: ^6.0.10 + peerDependencies: + postcss: ^8.2 + checksum: 8ecd6a929e8ddee3ad0834ab5017f50a569817ba8490d152b11c705c13cf3d9701f74792f375cbd72d8f33a4eeaabb3f984f1514adf8c5a530eb91be70c14cf4 languageName: node linkType: hard -"@emotion/babel-plugin@npm:^11.11.0": - version: 11.11.0 - resolution: "@emotion/babel-plugin@npm:11.11.0" +"@csstools/postcss-color-function@npm:^1.1.1": + version: 1.1.1 + resolution: "@csstools/postcss-color-function@npm:1.1.1" dependencies: - "@babel/helper-module-imports": ^7.16.7 - "@babel/runtime": ^7.18.3 - "@emotion/hash": ^0.9.1 - "@emotion/memoize": ^0.8.1 - "@emotion/serialize": ^1.1.2 - babel-plugin-macros: ^3.1.0 - convert-source-map: ^1.5.0 - escape-string-regexp: ^4.0.0 - find-root: ^1.1.0 - source-map: ^0.5.7 - stylis: 4.2.0 - checksum: 6b363edccc10290f7a23242c06f88e451b5feb2ab94152b18bb8883033db5934fb0e421e2d67d09907c13837c21218a3ac28c51707778a54d6cd3706c0c2f3f9 + "@csstools/postcss-progressive-custom-properties": ^1.1.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 087595985ebcc2fc42013d6305185d4cdc842d87fb261185db905dc31eaa24fc23a7cc068fa3da814b3c8b98164107ddaf1b4ab24f4ff5b2a7b5fbcd4c6ceec9 languageName: node linkType: hard -"@emotion/cache@npm:^11.11.0": - version: 11.11.0 - resolution: "@emotion/cache@npm:11.11.0" +"@csstools/postcss-font-format-keywords@npm:^1.0.1": + version: 1.0.1 + resolution: "@csstools/postcss-font-format-keywords@npm:1.0.1" dependencies: - "@emotion/memoize": ^0.8.1 - "@emotion/sheet": ^1.2.2 - "@emotion/utils": ^1.2.1 - "@emotion/weak-memoize": ^0.3.1 - stylis: 4.2.0 - checksum: 8eb1dc22beaa20c21a2e04c284d5a2630a018a9d51fb190e52de348c8d27f4e8ca4bbab003d68b4f6cd9cc1c569ca747a997797e0f76d6c734a660dc29decf08 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: ed8d9eab9793f0184e000709bcb155d4eb96c49a312e3ea9e549e006b74fd4aafac63cb9f9f01bec5b717a833539ff085c3f1ef7d273b97d587769ef637d50c1 languageName: node linkType: hard -"@emotion/hash@npm:^0.9.1": - version: 0.9.1 - resolution: "@emotion/hash@npm:0.9.1" - checksum: 716e17e48bf9047bf9383982c071de49f2615310fb4e986738931776f5a823bc1f29c84501abe0d3df91a3803c80122d24e28b57351bca9e01356ebb33d89876 +"@csstools/postcss-hwb-function@npm:^1.0.2": + version: 1.0.2 + resolution: "@csstools/postcss-hwb-function@npm:1.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 352ead754a692f7ed33a712c491012cab5c2f2946136a669a354237cfe8e6faca90c7389ee793cb329b9b0ddec984faa06d47e2f875933aaca417afff74ce6aa languageName: node linkType: hard -"@emotion/is-prop-valid@npm:^1.2.2": - version: 1.2.2 - resolution: "@emotion/is-prop-valid@npm:1.2.2" +"@csstools/postcss-ic-unit@npm:^1.0.1": + version: 1.0.1 + resolution: "@csstools/postcss-ic-unit@npm:1.0.1" dependencies: - "@emotion/memoize": ^0.8.1 - checksum: 61f6b128ea62b9f76b47955057d5d86fcbe2a6989d2cd1e583daac592901a950475a37d049b9f7a7c6aa8758a33b408735db759fdedfd1f629df0f85ab60ea25 + "@csstools/postcss-progressive-custom-properties": ^1.1.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 09c414c9b7762b5fbe837ff451d7a11e4890f1ed3c92edc3573f02f3d89747f6ac3f2270799b68a332bd7f5de05bb0dfffddb6323fc4020c2bea33ff58314533 languageName: node linkType: hard -"@emotion/memoize@npm:^0.8.1": - version: 0.8.1 - resolution: "@emotion/memoize@npm:0.8.1" - checksum: a19cc01a29fcc97514948eaab4dc34d8272e934466ed87c07f157887406bc318000c69ae6f813a9001c6a225364df04249842a50e692ef7a9873335fbcc141b0 +"@csstools/postcss-is-pseudo-class@npm:^2.0.7": + version: 2.0.7 + resolution: "@csstools/postcss-is-pseudo-class@npm:2.0.7" + dependencies: + "@csstools/selector-specificity": ^2.0.0 + postcss-selector-parser: ^6.0.10 + peerDependencies: + postcss: ^8.2 + checksum: a4494bb8e9a34826944ba6872c91c1e88268caab6d06968897f1a0cc75ca5cfc4989435961fc668a9c6842a6d17f4cda0055fa256d23e598b8bbc6f022956125 languageName: node linkType: hard -"@emotion/react@npm:^11.10.4": - version: 11.11.4 - resolution: "@emotion/react@npm:11.11.4" +"@csstools/postcss-nested-calc@npm:^1.0.0": + version: 1.0.0 + resolution: "@csstools/postcss-nested-calc@npm:1.0.0" dependencies: - "@babel/runtime": ^7.18.3 - "@emotion/babel-plugin": ^11.11.0 - "@emotion/cache": ^11.11.0 - "@emotion/serialize": ^1.1.3 - "@emotion/use-insertion-effect-with-fallbacks": ^1.0.1 - "@emotion/utils": ^1.2.1 - "@emotion/weak-memoize": ^0.3.1 - hoist-non-react-statics: ^3.3.1 + postcss-value-parser: ^4.2.0 peerDependencies: - react: ">=16.8.0" - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 6abaa7a05c5e1db31bffca7ac79169f5456990022cbb3794e6903221536609a60420f2b4888dd3f84e9634a304e394130cb88dc32c243a1dedc263e50da329f8 + postcss: ^8.2 + checksum: 53bb783dd61621c11c1e6e352f079577e2eb908de67947ceef31a178e070c06c223baae87acd5c3bd51c664515d2adc16166a129159168626111aff548583790 languageName: node linkType: hard -"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.1.4": - version: 1.1.4 - resolution: "@emotion/serialize@npm:1.1.4" +"@csstools/postcss-normalize-display-values@npm:^1.0.1": + version: 1.0.1 + resolution: "@csstools/postcss-normalize-display-values@npm:1.0.1" dependencies: - "@emotion/hash": ^0.9.1 - "@emotion/memoize": ^0.8.1 - "@emotion/unitless": ^0.8.1 - "@emotion/utils": ^1.2.1 - csstype: ^3.0.2 - checksum: 71b99f816a9c1d61a87c62cf4928da3894bb62213f3aff38b1ea9790b3368f084af98a3e5453b5055c2f36a7d70318d2fa9955b7b5676c2065b868062375df39 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 75901daec3869ba15e0adfd50d8e2e754ec06d55ac44fbd540748476388d223d53710fb3a3cbfe6695a2bab015a489fb47d9e3914ff211736923f8deb818dc0b languageName: node linkType: hard -"@emotion/sheet@npm:^1.2.2": - version: 1.2.2 - resolution: "@emotion/sheet@npm:1.2.2" - checksum: d973273c9c15f1c291ca2269728bf044bd3e92a67bca87943fa9ec6c3cd2b034f9a6bfe95ef1b5d983351d128c75b547b43ff196a00a3875f7e1d269793cecfe +"@csstools/postcss-oklab-function@npm:^1.1.1": + version: 1.1.1 + resolution: "@csstools/postcss-oklab-function@npm:1.1.1" + dependencies: + "@csstools/postcss-progressive-custom-properties": ^1.1.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: d66b789060b37ed810450d9a7d8319a0ae14e913c091f3e0ee482b3471538762e801d5eae3d62fda2f1eb1e88c76786d2c2b06c1172166eba1cca5e2a0dc95f2 languageName: node linkType: hard -"@emotion/styled@npm:^11.10.4": - version: 11.11.5 - resolution: "@emotion/styled@npm:11.11.5" +"@csstools/postcss-progressive-custom-properties@npm:^1.1.0, @csstools/postcss-progressive-custom-properties@npm:^1.3.0": + version: 1.3.0 + resolution: "@csstools/postcss-progressive-custom-properties@npm:1.3.0" dependencies: - "@babel/runtime": ^7.18.3 - "@emotion/babel-plugin": ^11.11.0 - "@emotion/is-prop-valid": ^1.2.2 - "@emotion/serialize": ^1.1.4 - "@emotion/use-insertion-effect-with-fallbacks": ^1.0.1 - "@emotion/utils": ^1.2.1 + postcss-value-parser: ^4.2.0 peerDependencies: - "@emotion/react": ^11.0.0-rc.0 - react: ">=16.8.0" - peerDependenciesMeta: - "@types/react": - optional: true - checksum: ad5fc42d00e8aa9597f6d9665986036d5ebe0e8f8155af6d95831c5e8fb2319fb837724e6c5cd59e5346f14c3263711b7ce7271d34688e974d1f32ffeecb37ba + postcss: ^8.3 + checksum: e281845fde5b8a80d06ec20147bd74e96a9351bebbec5e5c3a6fb37ea30a597ff84172601786a8a270662f58f708b4a3bf8d822d6318023def9773d2f6589962 languageName: node linkType: hard -"@emotion/unitless@npm:^0.8.1": - version: 0.8.1 - resolution: "@emotion/unitless@npm:0.8.1" - checksum: 385e21d184d27853bb350999471f00e1429fa4e83182f46cd2c164985999d9b46d558dc8b9cc89975cb337831ce50c31ac2f33b15502e85c299892e67e7b4a88 +"@csstools/postcss-stepped-value-functions@npm:^1.0.1": + version: 1.0.1 + resolution: "@csstools/postcss-stepped-value-functions@npm:1.0.1" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 2fc88713a0d49d142010652be8139b00719e407df1173e46047284f1befd0647e1fff67f259f9f55ac3b46bba6462b21f0aa192bd10a2989c51a8ce0d25fc495 languageName: node linkType: hard -"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.1": - version: 1.0.1 - resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1" +"@csstools/postcss-text-decoration-shorthand@npm:^1.0.0": + version: 1.0.0 + resolution: "@csstools/postcss-text-decoration-shorthand@npm:1.0.0" + dependencies: + postcss-value-parser: ^4.2.0 peerDependencies: - react: ">=16.8.0" - checksum: 700b6e5bbb37a9231f203bb3af11295eed01d73b2293abece0bc2a2237015e944d7b5114d4887ad9a79776504aa51ed2a8b0ddbc117c54495dd01a6b22f93786 + postcss: ^8.2 + checksum: d27aaf97872c42bec9f6fde4d8bf924e89f7886f0aca8e4fc5aaf2f9083b09bb43dbbfa29124fa36fcdeb2d4d3e0459a095acf62188260cd1577e9811bb1276e languageName: node linkType: hard -"@emotion/utils@npm:^1.2.1": - version: 1.2.1 - resolution: "@emotion/utils@npm:1.2.1" - checksum: e0b44be0705b56b079c55faff93952150be69e79b660ae70ddd5b6e09fc40eb1319654315a9f34bb479d7f4ec94be6068c061abbb9e18b9778ae180ad5d97c73 +"@csstools/postcss-trigonometric-functions@npm:^1.0.2": + version: 1.0.2 + resolution: "@csstools/postcss-trigonometric-functions@npm:1.0.2" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: f7f5b5f2492606b79a56f09e814ae8f10a2ae9e9c5fb8019f0e347a4a6c07953b2cc663fd4fa43a60e6994dfd958958f39df8ec760e2a646cfe71fe2bb119382 languageName: node linkType: hard -"@emotion/weak-memoize@npm:^0.3.1": - version: 0.3.1 - resolution: "@emotion/weak-memoize@npm:0.3.1" - checksum: b2be47caa24a8122622ea18cd2d650dbb4f8ad37b636dc41ed420c2e082f7f1e564ecdea68122b546df7f305b159bf5ab9ffee872abd0f052e687428459af594 +"@csstools/postcss-unset-value@npm:^1.0.2": + version: 1.0.2 + resolution: "@csstools/postcss-unset-value@npm:1.0.2" + peerDependencies: + postcss: ^8.2 + checksum: 3facdae154d6516ffd964f7582696f406465f11cf8dead503e0afdfecc99ebc25638ab2830affce4516131aa2db004458a235e439f575b04e9ef72ad82f55835 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm64@npm:0.18.20" - conditions: os=android & cpu=arm64 +"@csstools/selector-specificity@npm:^2.0.0, @csstools/selector-specificity@npm:^2.0.2": + version: 2.2.0 + resolution: "@csstools/selector-specificity@npm:2.2.0" + peerDependencies: + postcss-selector-parser: ^6.0.10 + checksum: 97c89f23b3b527d7bd51ed299969ed2b9fbb219a367948b44aefec228b8eda6ae0ad74fe8a82f9aac8ff32cfd00bb6d0c98d1daeab2e8fc6d5c4af25e5be5673 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm@npm:0.18.20" - conditions: os=android & cpu=arm +"@emotion/babel-plugin@npm:^11.13.5": + version: 11.13.5 + resolution: "@emotion/babel-plugin@npm:11.13.5" + dependencies: + "@babel/helper-module-imports": ^7.16.7 + "@babel/runtime": ^7.18.3 + "@emotion/hash": ^0.9.2 + "@emotion/memoize": ^0.9.0 + "@emotion/serialize": ^1.3.3 + babel-plugin-macros: ^3.1.0 + convert-source-map: ^1.5.0 + escape-string-regexp: ^4.0.0 + find-root: ^1.1.0 + source-map: ^0.5.7 + stylis: 4.2.0 + checksum: c41df7e6c19520e76d1939f884be878bf88b5ba00bd3de9d05c5b6c5baa5051686ab124d7317a0645de1b017b574d8139ae1d6390ec267fbe8e85a5252afb542 languageName: node linkType: hard -"@esbuild/android-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-x64@npm:0.18.20" - conditions: os=android & cpu=x64 +"@emotion/cache@npm:^11.13.5, @emotion/cache@npm:^11.14.0": + version: 11.14.0 + resolution: "@emotion/cache@npm:11.14.0" + dependencies: + "@emotion/memoize": ^0.9.0 + "@emotion/sheet": ^1.4.0 + "@emotion/utils": ^1.4.2 + "@emotion/weak-memoize": ^0.4.0 + stylis: 4.2.0 + checksum: 0a81591541ea43bc7851742e6444b7800d72e98006f94e775ae6ea0806662d14e0a86ff940f5f19d33b4bb2c427c882aa65d417e7322a6e0d5f20fe65ed920c9 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-arm64@npm:0.18.20" - conditions: os=darwin & cpu=arm64 +"@emotion/hash@npm:^0.9.2": + version: 0.9.2 + resolution: "@emotion/hash@npm:0.9.2" + checksum: 379bde2830ccb0328c2617ec009642321c0e009a46aa383dfbe75b679c6aea977ca698c832d225a893901f29d7b3eef0e38cf341f560f6b2b56f1ff23c172387 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-x64@npm:0.18.20" - conditions: os=darwin & cpu=x64 +"@emotion/is-prop-valid@npm:^1.3.0": + version: 1.4.0 + resolution: "@emotion/is-prop-valid@npm:1.4.0" + dependencies: + "@emotion/memoize": ^0.9.0 + checksum: 6b003cdc62106c2d5d12207c2d1352d674339252a2d7ac8d96974781d7c639833f35d22e7e331411795daaafa62f126c2824a4983584292b431e08b42877d51e languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-arm64@npm:0.18.20" - conditions: os=freebsd & cpu=arm64 +"@emotion/memoize@npm:^0.9.0": + version: 0.9.0 + resolution: "@emotion/memoize@npm:0.9.0" + checksum: 038132359397348e378c593a773b1148cd0cf0a2285ffd067a0f63447b945f5278860d9de718f906a74c7c940ba1783ac2ca18f1c06a307b01cc0e3944e783b1 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-x64@npm:0.18.20" - conditions: os=freebsd & cpu=x64 +"@emotion/react@npm:^11.10.4": + version: 11.14.0 + resolution: "@emotion/react@npm:11.14.0" + dependencies: + "@babel/runtime": ^7.18.3 + "@emotion/babel-plugin": ^11.13.5 + "@emotion/cache": ^11.14.0 + "@emotion/serialize": ^1.3.3 + "@emotion/use-insertion-effect-with-fallbacks": ^1.2.0 + "@emotion/utils": ^1.4.2 + "@emotion/weak-memoize": ^0.4.0 + hoist-non-react-statics: ^3.3.1 + peerDependencies: + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 3cf023b11d132b56168713764d6fced8e5a1f0687dfe0caa2782dfd428c8f9e30f9826a919965a311d87b523cd196722aaf75919cd0f6bd0fd57f8a6a0281500 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm64@npm:0.18.20" - conditions: os=linux & cpu=arm64 +"@emotion/serialize@npm:^1.3.3": + version: 1.3.3 + resolution: "@emotion/serialize@npm:1.3.3" + dependencies: + "@emotion/hash": ^0.9.2 + "@emotion/memoize": ^0.9.0 + "@emotion/unitless": ^0.10.0 + "@emotion/utils": ^1.4.2 + csstype: ^3.0.2 + checksum: 510331233767ae4e09e925287ca2c7269b320fa1d737ea86db5b3c861a734483ea832394c0c1fe5b21468fe335624a75e72818831d303ba38125f54f44ba02e7 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm@npm:0.18.20" - conditions: os=linux & cpu=arm +"@emotion/sheet@npm:^1.4.0": + version: 1.4.0 + resolution: "@emotion/sheet@npm:1.4.0" + checksum: eeb1212e3289db8e083e72e7e401cd6d1a84deece87e9ce184f7b96b9b5dbd6f070a89057255a6ff14d9865c3ce31f27c39248a053e4cdd875540359042586b4 languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ia32@npm:0.18.20" - conditions: os=linux & cpu=ia32 +"@emotion/styled@npm:^11.10.4": + version: 11.14.1 + resolution: "@emotion/styled@npm:11.14.1" + dependencies: + "@babel/runtime": ^7.18.3 + "@emotion/babel-plugin": ^11.13.5 + "@emotion/is-prop-valid": ^1.3.0 + "@emotion/serialize": ^1.3.3 + "@emotion/use-insertion-effect-with-fallbacks": ^1.2.0 + "@emotion/utils": ^1.4.2 + peerDependencies: + "@emotion/react": ^11.0.0-rc.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 86238d9f5c41232a73499e441fa9112e855545519d6772f489fa885634bb8f31b422a9ba9d1e8bc0b4ad66132f9d398b1c309d92c19c5ee21356b41671ec984a languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.14.54": - version: 0.14.54 - resolution: "@esbuild/linux-loong64@npm:0.14.54" - conditions: os=linux & cpu=loong64 +"@emotion/unitless@npm:^0.10.0": + version: 0.10.0 + resolution: "@emotion/unitless@npm:0.10.0" + checksum: d79346df31a933e6d33518e92636afeb603ce043f3857d0a39a2ac78a09ef0be8bedff40130930cb25df1beeee12d96ee38613963886fa377c681a89970b787c languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-loong64@npm:0.18.20" - conditions: os=linux & cpu=loong64 +"@emotion/use-insertion-effect-with-fallbacks@npm:^1.2.0": + version: 1.2.0 + resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.2.0" + peerDependencies: + react: ">=16.8.0" + checksum: 8ff6aec7f2924526ff8c8f8f93d4b8236376e2e12c435314a18c9a373016e24dfdf984e82bbc83712b8e90ff4783cd765eb39fc7050d1a43245e5728740ddd71 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-mips64el@npm:0.18.20" - conditions: os=linux & cpu=mips64el +"@emotion/utils@npm:^1.4.2": + version: 1.4.2 + resolution: "@emotion/utils@npm:1.4.2" + checksum: 04cf76849c6401205c058b82689fd0ec5bf501aed6974880fe9681a1d61543efb97e848f4c38664ac4a9068c7ad2d1cb84f73bde6cf95f1208aa3c28e0190321 languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ppc64@npm:0.18.20" - conditions: os=linux & cpu=ppc64 +"@emotion/weak-memoize@npm:^0.4.0": + version: 0.4.0 + resolution: "@emotion/weak-memoize@npm:0.4.0" + checksum: db5da0e89bd752c78b6bd65a1e56231f0abebe2f71c0bd8fc47dff96408f7065b02e214080f99924f6a3bfe7ee15afc48dad999d76df86b39b16e513f7a94f52 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-riscv64@npm:0.18.20" - conditions: os=linux & cpu=riscv64 +"@esbuild/aix-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/aix-ppc64@npm:0.21.5" + conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-s390x@npm:0.18.20" - conditions: os=linux & cpu=s390x +"@esbuild/aix-ppc64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/aix-ppc64@npm:0.24.2" + conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-x64@npm:0.18.20" - conditions: os=linux & cpu=x64 +"@esbuild/aix-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/aix-ppc64@npm:0.25.9" + conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/netbsd-x64@npm:0.18.20" - conditions: os=netbsd & cpu=x64 +"@esbuild/android-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/android-arm64@npm:0.17.19" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/openbsd-x64@npm:0.18.20" - conditions: os=openbsd & cpu=x64 +"@esbuild/android-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm64@npm:0.21.5" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/sunos-x64@npm:0.18.20" - conditions: os=sunos & cpu=x64 +"@esbuild/android-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/android-arm64@npm:0.24.2" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-arm64@npm:0.18.20" - conditions: os=win32 & cpu=arm64 +"@esbuild/android-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm64@npm:0.25.9" + conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-ia32@npm:0.18.20" - conditions: os=win32 & cpu=ia32 +"@esbuild/android-arm@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/android-arm@npm:0.17.19" + conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-x64@npm:0.18.20" - conditions: os=win32 & cpu=x64 +"@esbuild/android-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm@npm:0.21.5" + conditions: os=android & cpu=arm languageName: node linkType: hard -"@eslint/eslintrc@npm:^0.4.3": - version: 0.4.3 - resolution: "@eslint/eslintrc@npm:0.4.3" - dependencies: - ajv: ^6.12.4 - debug: ^4.1.1 - espree: ^7.3.0 - globals: ^13.9.0 - ignore: ^4.0.6 - import-fresh: ^3.2.1 - js-yaml: ^3.13.1 - minimatch: ^3.0.4 - strip-json-comments: ^3.1.1 - checksum: 03a7704150b868c318aab6a94d87a33d30dc2ec579d27374575014f06237ba1370ae11178db772f985ef680d469dc237e7b16a1c5d8edaaeb8c3733e7a95a6d3 +"@esbuild/android-arm@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/android-arm@npm:0.24.2" + conditions: os=android & cpu=arm languageName: node linkType: hard -"@floating-ui/core@npm:^1.0.0": - version: 1.6.0 - resolution: "@floating-ui/core@npm:1.6.0" - dependencies: - "@floating-ui/utils": ^0.2.1 - checksum: 2e25c53b0c124c5c9577972f8ae21d081f2f7895e6695836a53074463e8c65b47722744d6d2b5a993164936da006a268bcfe87fe68fd24dc235b1cb86bed3127 +"@esbuild/android-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm@npm:0.25.9" + conditions: os=android & cpu=arm languageName: node linkType: hard -"@floating-ui/dom@npm:^1.6.1": - version: 1.6.3 - resolution: "@floating-ui/dom@npm:1.6.3" - dependencies: - "@floating-ui/core": ^1.0.0 - "@floating-ui/utils": ^0.2.0 - checksum: 81cbb18ece3afc37992f436e469e7fabab2e433248e46fff4302d12493a175b0c64310f8a971e6e1eda7218df28ace6b70237b0f3c22fe12a21bba05b5579555 +"@esbuild/android-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/android-x64@npm:0.17.19" + conditions: os=android & cpu=x64 languageName: node linkType: hard -"@floating-ui/react-dom@npm:^2.0.8": - version: 2.0.8 - resolution: "@floating-ui/react-dom@npm:2.0.8" - dependencies: - "@floating-ui/dom": ^1.6.1 - peerDependencies: - react: ">=16.8.0" - react-dom: ">=16.8.0" - checksum: 5da7f13a69281e38859a3203a608fe9de1d850b332b355c10c0c2427c7b7209a0374c10f6295b6577c1a70237af8b678340bd4cc0a4b1c66436a94755d81e526 +"@esbuild/android-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-x64@npm:0.21.5" + conditions: os=android & cpu=x64 languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.1": - version: 0.2.1 - resolution: "@floating-ui/utils@npm:0.2.1" - checksum: 9ed4380653c7c217cd6f66ae51f20fdce433730dbc77f95b5abfb5a808f5fdb029c6ae249b4e0490a816f2453aa6e586d9a873cd157fdba4690f65628efc6e06 +"@esbuild/android-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/android-x64@npm:0.24.2" + conditions: os=android & cpu=x64 languageName: node linkType: hard -"@gar/promisify@npm:^1.0.1": - version: 1.1.3 - resolution: "@gar/promisify@npm:1.1.3" - checksum: 4059f790e2d07bf3c3ff3e0fec0daa8144fe35c1f6e0111c9921bd32106adaa97a4ab096ad7dab1e28ee6a9060083c4d1a4ada42a7f5f3f7a96b8812e2b757c1 +"@esbuild/android-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-x64@npm:0.25.9" + conditions: os=android & cpu=x64 languageName: node linkType: hard -"@hapi/address@npm:2.x.x": - version: 2.1.4 - resolution: "@hapi/address@npm:2.1.4" - checksum: 10341c3b650746c79ac2c57118efb05d45d850b33aef82a6f2ba89419fdbf1b6d337c8b085cc9bc1af7a5fb18379c07edaf3be7584426f40bd370ed6de29e965 +"@esbuild/darwin-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/darwin-arm64@npm:0.17.19" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@hapi/bourne@npm:1.x.x": - version: 1.3.2 - resolution: "@hapi/bourne@npm:1.3.2" - checksum: 8403a2e8297fbb49a0e4fca30e874590d96ecaf7165740804037ff30625f3fdea6353d9f7f4422607eb069a3f471900a3037df34285a95135d15c6a8b10094b0 +"@esbuild/darwin-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-arm64@npm:0.21.5" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@hapi/hoek@npm:8.x.x, @hapi/hoek@npm:^8.3.0": - version: 8.5.1 - resolution: "@hapi/hoek@npm:8.5.1" - checksum: 8f8ce36be4f5e5d7a712072d4a028a4a95beec7a7da3a7a6e9a0c07d697f04c19b37d93751db352c314ea831f7e2120569a035dc6a351ed8c0444f1d3b275621 +"@esbuild/darwin-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/darwin-arm64@npm:0.24.2" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@hapi/joi@npm:^15.1.0": - version: 15.1.1 - resolution: "@hapi/joi@npm:15.1.1" - dependencies: - "@hapi/address": 2.x.x - "@hapi/bourne": 1.x.x - "@hapi/hoek": 8.x.x - "@hapi/topo": 3.x.x - checksum: 5bc3df9d43d4a53c41fd172d2958a4a846dbacbe2a2abe16830059109c436776d7be98144f14af9d328ebd107dbebafe55e00a9032a905aef45aadff988b54bf +"@esbuild/darwin-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-arm64@npm:0.25.9" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@hapi/topo@npm:3.x.x": - version: 3.1.6 - resolution: "@hapi/topo@npm:3.1.6" - dependencies: - "@hapi/hoek": ^8.3.0 - checksum: 34278bc13b4023d6d0d7c913605a254b2d728dc6489cd465269eebaa7d8d2d81cda3f2157398dca87d3cb9e1a8aa8a1158ce2564c71a8e289b807c144e3b4c1e +"@esbuild/darwin-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/darwin-x64@npm:0.17.19" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@hookform/resolvers@npm:^2.9.7": - version: 2.9.11 - resolution: "@hookform/resolvers@npm:2.9.11" - peerDependencies: - react-hook-form: ^7.0.0 - checksum: 977ea038bb94457ac9f6c7ca65438ce8fcd0cf7643b9925d8bc4d66df6faa0f49ad642bee7362f86a4d3ff7ff53d18b7aea0597085993971cae00e86bf6eda73 +"@esbuild/darwin-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-x64@npm:0.21.5" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.5.0": - version: 0.5.0 - resolution: "@humanwhocodes/config-array@npm:0.5.0" - dependencies: - "@humanwhocodes/object-schema": ^1.2.0 - debug: ^4.1.1 - minimatch: ^3.0.4 - checksum: 44ee6a9f05d93dd9d5935a006b17572328ba9caff8002442f601736cbda79c580cc0f5a49ce9eb88fbacc5c3a6b62098357c2e95326cd17bb9f1a6c61d6e95e7 +"@esbuild/darwin-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/darwin-x64@npm:0.24.2" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^1.2.0": - version: 1.2.1 - resolution: "@humanwhocodes/object-schema@npm:1.2.1" - checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 +"@esbuild/darwin-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-x64@npm:0.25.9" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@isaacs/cliui@npm:^8.0.2": - version: 8.0.2 - resolution: "@isaacs/cliui@npm:8.0.2" - 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" - checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb +"@esbuild/freebsd-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/freebsd-arm64@npm:0.17.19" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@istanbuljs/load-nyc-config@npm:^1.0.0": - version: 1.1.0 - resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" - dependencies: - camelcase: ^5.3.1 - find-up: ^4.1.0 - get-package-type: ^0.1.0 - js-yaml: ^3.13.1 - resolve-from: ^5.0.0 - checksum: d578da5e2e804d5c93228450a1380e1a3c691de4953acc162f387b717258512a3e07b83510a936d9fab03eac90817473917e24f5d16297af3867f59328d58568 +"@esbuild/freebsd-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-arm64@npm:0.21.5" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@istanbuljs/schema@npm:^0.1.2": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 +"@esbuild/freebsd-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/freebsd-arm64@npm:0.24.2" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@jest/console@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/console@npm:26.6.2" - dependencies: - "@jest/types": ^26.6.2 - "@types/node": "*" - chalk: ^4.0.0 - jest-message-util: ^26.6.2 - jest-util: ^26.6.2 - slash: ^3.0.0 - checksum: 69a9ca6ba357d7634fd537e3b87c64369865ffb59f57fe6661223088bd62273d0c1d660fefce3625a427f42a37d32590f6b291e1295ea6d6b7cb31ddae36a737 +"@esbuild/freebsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-arm64@npm:0.25.9" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@jest/core@npm:^26.6.0, @jest/core@npm:^26.6.3": - version: 26.6.3 - resolution: "@jest/core@npm:26.6.3" - dependencies: - "@jest/console": ^26.6.2 - "@jest/reporters": ^26.6.2 - "@jest/test-result": ^26.6.2 - "@jest/transform": ^26.6.2 - "@jest/types": ^26.6.2 - "@types/node": "*" - ansi-escapes: ^4.2.1 - chalk: ^4.0.0 - exit: ^0.1.2 - graceful-fs: ^4.2.4 - jest-changed-files: ^26.6.2 - jest-config: ^26.6.3 - jest-haste-map: ^26.6.2 - jest-message-util: ^26.6.2 - jest-regex-util: ^26.0.0 - jest-resolve: ^26.6.2 - jest-resolve-dependencies: ^26.6.3 - jest-runner: ^26.6.3 - jest-runtime: ^26.6.3 - jest-snapshot: ^26.6.2 - jest-util: ^26.6.2 - jest-validate: ^26.6.2 - jest-watcher: ^26.6.2 - micromatch: ^4.0.2 - p-each-series: ^2.1.0 - rimraf: ^3.0.0 - slash: ^3.0.0 - strip-ansi: ^6.0.0 - checksum: f52b26ffe9b923ed67b3ff30e170b3a434d4263990f78d96cd43acbd0aa8ad36aecad2f1822f376da3a80228714fd6b7f7acd51744133cfcd2780ba0e3da537b +"@esbuild/freebsd-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/freebsd-x64@npm:0.17.19" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@jest/environment@npm:^26.6.0, @jest/environment@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/environment@npm:26.6.2" - dependencies: - "@jest/fake-timers": ^26.6.2 - "@jest/types": ^26.6.2 - "@types/node": "*" - jest-mock: ^26.6.2 - checksum: 7748081b2a758161785aff161780b05084dccaff908c8ed82c04f7da5d5e5439e77b5eb667306d5c4e1422653c7a67ed2955f26704f48c65c404195e1e21780a +"@esbuild/freebsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-x64@npm:0.21.5" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@jest/expect-utils@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/expect-utils@npm:28.1.3" - dependencies: - jest-get-type: ^28.0.2 - checksum: 808ea3a68292a7e0b95490fdd55605c430b4cf209ea76b5b61bfb2a1badcb41bc046810fe4e364bd5fe04663978aa2bd73d8f8465a761dd7c655aeb44cf22987 +"@esbuild/freebsd-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/freebsd-x64@npm:0.24.2" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@jest/expect-utils@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/expect-utils@npm:29.7.0" - dependencies: - jest-get-type: ^29.6.3 - checksum: 75eb177f3d00b6331bcaa057e07c0ccb0733a1d0a1943e1d8db346779039cb7f103789f16e502f888a3096fb58c2300c38d1f3748b36a7fa762eb6f6d1b160ed +"@esbuild/freebsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-x64@npm:0.25.9" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@jest/fake-timers@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/fake-timers@npm:26.6.2" - dependencies: - "@jest/types": ^26.6.2 - "@sinonjs/fake-timers": ^6.0.1 - "@types/node": "*" - jest-message-util: ^26.6.2 - jest-mock: ^26.6.2 - jest-util: ^26.6.2 - checksum: c732658fac4014a424e6629495296c3b2e8697787518df34c74539ec139625e7141ad792b8a4d3c8392b47954ad01be9846b7c57cc8c631490969e7cafa84e6a +"@esbuild/linux-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-arm64@npm:0.17.19" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@jest/globals@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/globals@npm:26.6.2" - dependencies: - "@jest/environment": ^26.6.2 - "@jest/types": ^26.6.2 - expect: ^26.6.2 - checksum: 49b28d0cc7e99898eeaf23e6899e3c9ee25a2a4831caa3eb930ec1722de2e92a0e8a6a6f649438fdd20ff0c0d5e522dd78cb719466a57f011a88d60419b903c5 +"@esbuild/linux-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm64@npm:0.21.5" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@jest/reporters@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/reporters@npm:26.6.2" - dependencies: - "@bcoe/v8-coverage": ^0.2.3 - "@jest/console": ^26.6.2 - "@jest/test-result": ^26.6.2 - "@jest/transform": ^26.6.2 - "@jest/types": ^26.6.2 - chalk: ^4.0.0 - collect-v8-coverage: ^1.0.0 - exit: ^0.1.2 - glob: ^7.1.2 - graceful-fs: ^4.2.4 - istanbul-lib-coverage: ^3.0.0 - istanbul-lib-instrument: ^4.0.3 - istanbul-lib-report: ^3.0.0 - istanbul-lib-source-maps: ^4.0.0 - istanbul-reports: ^3.0.2 - jest-haste-map: ^26.6.2 - jest-resolve: ^26.6.2 - jest-util: ^26.6.2 - jest-worker: ^26.6.2 - node-notifier: ^8.0.0 - slash: ^3.0.0 - source-map: ^0.6.0 - string-length: ^4.0.1 - terminal-link: ^2.0.0 - v8-to-istanbul: ^7.0.0 - dependenciesMeta: - node-notifier: - optional: true - checksum: 53c7a697c562becb7682a9a6248ea553013bf7048c08ddce5bf9fb53b975fc9f799ca163f7494e0be6c4d3cf181c8bc392976268da52b7de8ce4470b971ed84e +"@esbuild/linux-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-arm64@npm:0.24.2" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@jest/schemas@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/schemas@npm:28.1.3" - dependencies: - "@sinclair/typebox": ^0.24.1 - checksum: 3cf1d4b66c9c4ffda58b246de1ddcba8e6ad085af63dccdf07922511f13b68c0cc480a7bc620cb4f3099a6f134801c747e1df7bfc7a4ef4dceefbdea3e31e1de +"@esbuild/linux-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm64@npm:0.25.9" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@jest/schemas@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/schemas@npm:29.6.3" - dependencies: - "@sinclair/typebox": ^0.27.8 - checksum: 910040425f0fc93cd13e68c750b7885590b8839066dfa0cd78e7def07bbb708ad869381f725945d66f2284de5663bbecf63e8fdd856e2ae6e261ba30b1687e93 +"@esbuild/linux-arm@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-arm@npm:0.17.19" + conditions: os=linux & cpu=arm languageName: node linkType: hard -"@jest/source-map@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/source-map@npm:26.6.2" - dependencies: - callsites: ^3.0.0 - graceful-fs: ^4.2.4 - source-map: ^0.6.0 - checksum: b171cef442738887dda85527ab78229996db5946c6435ddb56d442c2851889ba493729a9de73100f1a31b9a31a91207b55bc75656ae7df9843d65078b925385e +"@esbuild/linux-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm@npm:0.21.5" + conditions: os=linux & cpu=arm languageName: node linkType: hard -"@jest/test-result@npm:^26.6.0, @jest/test-result@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/test-result@npm:26.6.2" - dependencies: - "@jest/console": ^26.6.2 - "@jest/types": ^26.6.2 - "@types/istanbul-lib-coverage": ^2.0.0 - collect-v8-coverage: ^1.0.0 - checksum: dcb6175825231e9377e43546aed4edd6acc22f1788d5f099bbba36bb55b9115a92f760e88426c076bcdeff5a50d8f697327a920db0cd1fb339781fc3713fa8c7 +"@esbuild/linux-arm@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-arm@npm:0.24.2" + conditions: os=linux & cpu=arm languageName: node linkType: hard -"@jest/test-sequencer@npm:^26.6.3": - version: 26.6.3 - resolution: "@jest/test-sequencer@npm:26.6.3" - dependencies: - "@jest/test-result": ^26.6.2 - graceful-fs: ^4.2.4 - jest-haste-map: ^26.6.2 - jest-runner: ^26.6.3 - jest-runtime: ^26.6.3 - checksum: a3450b3d7057f74da1828bb7b3658f228a7c049dc4082c5c49b8bafbd8f69d102a8a99007b7ed5d43464712f7823f53fe3564fda17787f178c219cccf329a461 +"@esbuild/linux-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm@npm:0.25.9" + conditions: os=linux & cpu=arm languageName: node linkType: hard -"@jest/transform@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/transform@npm:26.6.2" - dependencies: - "@babel/core": ^7.1.0 - "@jest/types": ^26.6.2 - babel-plugin-istanbul: ^6.0.0 - chalk: ^4.0.0 - convert-source-map: ^1.4.0 - fast-json-stable-stringify: ^2.0.0 - graceful-fs: ^4.2.4 - jest-haste-map: ^26.6.2 - jest-regex-util: ^26.0.0 - jest-util: ^26.6.2 - micromatch: ^4.0.2 - pirates: ^4.0.1 - slash: ^3.0.0 - source-map: ^0.6.1 - write-file-atomic: ^3.0.0 - checksum: 31667b925a2f3b310d854495da0ab67be8f5da24df76ecfc51162e75f1140aed5d18069ba190cb5e0c7e492b04272c8c79076ddf5bbcff530ee80a16a02c4545 +"@esbuild/linux-ia32@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-ia32@npm:0.17.19" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@jest/types@npm:^26.6.0, @jest/types@npm:^26.6.2": - version: 26.6.2 - resolution: "@jest/types@npm:26.6.2" - dependencies: - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^15.0.0 - chalk: ^4.0.0 - checksum: a0bd3d2f22f26ddb23f41fddf6e6a30bf4fab2ce79ec1cb6ce6fdfaf90a72e00f4c71da91ec61e13db3b10c41de22cf49d07c57ff2b59171d64b29f909c1d8d6 +"@esbuild/linux-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ia32@npm:0.21.5" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@jest/types@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/types@npm:28.1.3" - dependencies: +"@esbuild/linux-ia32@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-ia32@npm:0.24.2" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ia32@npm:0.25.9" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-loong64@npm:0.17.19" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-loong64@npm:0.21.5" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-loong64@npm:0.24.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-loong64@npm:0.25.9" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-mips64el@npm:0.17.19" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-mips64el@npm:0.21.5" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-mips64el@npm:0.24.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-mips64el@npm:0.25.9" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-ppc64@npm:0.17.19" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ppc64@npm:0.21.5" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-ppc64@npm:0.24.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ppc64@npm:0.25.9" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-riscv64@npm:0.17.19" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-riscv64@npm:0.21.5" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-riscv64@npm:0.24.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-riscv64@npm:0.25.9" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-s390x@npm:0.17.19" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-s390x@npm:0.21.5" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-s390x@npm:0.24.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-s390x@npm:0.25.9" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/linux-x64@npm:0.17.19" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-x64@npm:0.21.5" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-x64@npm:0.24.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-x64@npm:0.25.9" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/netbsd-arm64@npm:0.24.2" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-arm64@npm:0.25.9" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/netbsd-x64@npm:0.17.19" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/netbsd-x64@npm:0.21.5" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/netbsd-x64@npm:0.24.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-x64@npm:0.25.9" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/openbsd-arm64@npm:0.24.2" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-arm64@npm:0.25.9" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/openbsd-x64@npm:0.17.19" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/openbsd-x64@npm:0.21.5" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/openbsd-x64@npm:0.24.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-x64@npm:0.25.9" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openharmony-arm64@npm:0.25.9" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/sunos-x64@npm:0.17.19" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/sunos-x64@npm:0.21.5" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/sunos-x64@npm:0.24.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/sunos-x64@npm:0.25.9" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/win32-arm64@npm:0.17.19" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-arm64@npm:0.21.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/win32-arm64@npm:0.24.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-arm64@npm:0.25.9" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/win32-ia32@npm:0.17.19" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-ia32@npm:0.21.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/win32-ia32@npm:0.24.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-ia32@npm:0.25.9" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.17.19": + version: 0.17.19 + resolution: "@esbuild/win32-x64@npm:0.17.19" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-x64@npm:0.21.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/win32-x64@npm:0.24.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-x64@npm:0.25.9" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": + version: 4.9.0 + resolution: "@eslint-community/eslint-utils@npm:4.9.0" + dependencies: + eslint-visitor-keys: ^3.4.3 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: ae9b98eea006d1354368804b0116b8b45017a4e47b486d1b9cfa048a8ed3dc69b9b074eb2b2acb14034e6897c24048fd42b6a6816d9dc8bb9daad79db7d478d2 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.6.1": + version: 4.12.1 + resolution: "@eslint-community/regexpp@npm:4.12.1" + checksum: 0d628680e204bc316d545b4993d3658427ca404ae646ce541fcc65306b8c712c340e5e573e30fb9f85f4855c0c5f6dca9868931f2fcced06417fbe1a0c6cd2d6 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^0.4.3": + version: 0.4.3 + resolution: "@eslint/eslintrc@npm:0.4.3" + dependencies: + ajv: ^6.12.4 + debug: ^4.1.1 + espree: ^7.3.0 + globals: ^13.9.0 + ignore: ^4.0.6 + import-fresh: ^3.2.1 + js-yaml: ^3.13.1 + minimatch: ^3.0.4 + strip-json-comments: ^3.1.1 + checksum: 03a7704150b868c318aab6a94d87a33d30dc2ec579d27374575014f06237ba1370ae11178db772f985ef680d469dc237e7b16a1c5d8edaaeb8c3733e7a95a6d3 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/eslintrc@npm:2.1.4" + dependencies: + ajv: ^6.12.4 + debug: ^4.3.2 + espree: ^9.6.0 + globals: ^13.19.0 + ignore: ^5.2.0 + import-fresh: ^3.2.1 + js-yaml: ^4.1.0 + minimatch: ^3.1.2 + strip-json-comments: ^3.1.1 + checksum: 10957c7592b20ca0089262d8c2a8accbad14b4f6507e35416c32ee6b4dbf9cad67dfb77096bbd405405e9ada2b107f3797fe94362e1c55e0b09d6e90dd149127 + languageName: node + linkType: hard + +"@eslint/js@npm:8.57.1": + version: 8.57.1 + resolution: "@eslint/js@npm:8.57.1" + checksum: 2afb77454c06e8316793d2e8e79a0154854d35e6782a1217da274ca60b5044d2c69d6091155234ed0551a1e408f86f09dd4ece02752c59568fa403e60611e880 + languageName: node + linkType: hard + +"@floating-ui/core@npm:^1.7.3": + version: 1.7.3 + resolution: "@floating-ui/core@npm:1.7.3" + dependencies: + "@floating-ui/utils": ^0.2.10 + checksum: 5adfb28ddfa1776ec83516439256b9026e5d62b5413f62ae51e50a870cf0df4bea9abf72aacc0610ee84bc00e85883d0d32f2a0976ee7fa89728a717a7494f27 + languageName: node + linkType: hard + +"@floating-ui/dom@npm:^1.7.4": + version: 1.7.4 + resolution: "@floating-ui/dom@npm:1.7.4" + dependencies: + "@floating-ui/core": ^1.7.3 + "@floating-ui/utils": ^0.2.10 + checksum: 806923e6f5b09e024c366070f2115a4db6e8ad28462bac29cd075170a6f7d900497da3ee542439bd0770b8e2fff12b636cc30873d1c82e9ec4a487870b080643 + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^2.1.1": + version: 2.1.6 + resolution: "@floating-ui/react-dom@npm:2.1.6" + dependencies: + "@floating-ui/dom": ^1.7.4 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 24ff266806cd4cba6ad066f0eda7b99583f68af877f41df0b2a8d10a392692e3a1c1d666ebb75571a060818ede940bae59d833aa517ed538f7dba9dddd9991ae + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.10": + version: 0.2.10 + resolution: "@floating-ui/utils@npm:0.2.10" + checksum: ffc4c24a46a665cfd0337e9aaf7de8415b572f8a0f323af39175e4b575582aed13d172e7f049eedeece9eaf022bad019c140a2d192580451984ae529bdf1285c + languageName: node + linkType: hard + +"@hello-pangea/dnd@npm:^17.0.0": + version: 17.0.0 + resolution: "@hello-pangea/dnd@npm:17.0.0" + dependencies: + "@babel/runtime": ^7.25.6 + css-box-model: ^1.2.1 + memoize-one: ^6.0.0 + raf-schd: ^4.0.3 + react-redux: ^9.1.2 + redux: ^5.0.1 + use-memo-one: ^1.1.3 + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + checksum: a0da6a41b741b8c77ca6e2d6f54c3ce5a0daf92c0fd3b4ad1a63d40fd166a7d7aec0993c1d4f29e9c7f9c43a00cf74393fcb33afb7422450a974eb63f50a89da + languageName: node + linkType: hard + +"@hookform/resolvers@npm:^3.10.0": + version: 3.10.0 + resolution: "@hookform/resolvers@npm:3.10.0" + peerDependencies: + react-hook-form: ^7.0.0 + checksum: e062f10bebff696a669fe37388f64f6b7c322eb524e99008c0e157e7adf68d2cee4d86fce1a7304a80d7f6fdd6d92facc37320a539cb195235a31a680415760c + languageName: node + linkType: hard + +"@humanwhocodes/config-array@npm:^0.13.0": + version: 0.13.0 + resolution: "@humanwhocodes/config-array@npm:0.13.0" + dependencies: + "@humanwhocodes/object-schema": ^2.0.3 + debug: ^4.3.1 + minimatch: ^3.0.5 + checksum: eae69ff9134025dd2924f0b430eb324981494be26f0fddd267a33c28711c4db643242cf9fddf7dadb9d16c96b54b2d2c073e60a56477df86e0173149313bd5d6 + languageName: node + linkType: hard + +"@humanwhocodes/config-array@npm:^0.5.0": + version: 0.5.0 + resolution: "@humanwhocodes/config-array@npm:0.5.0" + dependencies: + "@humanwhocodes/object-schema": ^1.2.0 + debug: ^4.1.1 + minimatch: ^3.0.4 + checksum: 44ee6a9f05d93dd9d5935a006b17572328ba9caff8002442f601736cbda79c580cc0f5a49ce9eb88fbacc5c3a6b62098357c2e95326cd17bb9f1a6c61d6e95e7 + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 0fd22007db8034a2cdf2c764b140d37d9020bbfce8a49d3ec5c05290e77d4b0263b1b972b752df8c89e5eaa94073408f2b7d977aed131faf6cf396ebb5d7fb61 + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^1.2.0": + version: 1.2.1 + resolution: "@humanwhocodes/object-schema@npm:1.2.1" + checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^2.0.3": + version: 2.0.3 + resolution: "@humanwhocodes/object-schema@npm:2.0.3" + checksum: d3b78f6c5831888c6ecc899df0d03bcc25d46f3ad26a11d7ea52944dc36a35ef543fad965322174238d677a43d5c694434f6607532cff7077062513ad7022631 + languageName: node + linkType: hard + +"@inquirer/ansi@npm:^1.0.0": + version: 1.0.0 + resolution: "@inquirer/ansi@npm:1.0.0" + checksum: 153b619c1178ece3e28a66ab41b7827b9ee64c84180f779bcc1c38c8c3e87979130bba109dd7e648ccdd3786da75c4a3a0945e816dc6afec9219f54ac7fbbb69 + languageName: node + linkType: hard + +"@inquirer/confirm@npm:^5.0.0": + version: 5.1.18 + resolution: "@inquirer/confirm@npm:5.1.18" + dependencies: + "@inquirer/core": ^10.2.2 + "@inquirer/type": ^3.0.8 + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 59a27eedf9b8e5ff1ca5eb738121caf56c94d9ec80f0ff02021300a7894c608e9c32e06b79ba21714f6977a277c84025e62b141c50c580be2a30697f52ef4941 + languageName: node + linkType: hard + +"@inquirer/core@npm:^10.2.2": + version: 10.2.2 + resolution: "@inquirer/core@npm:10.2.2" + dependencies: + "@inquirer/ansi": ^1.0.0 + "@inquirer/figures": ^1.0.13 + "@inquirer/type": ^3.0.8 + cli-width: ^4.1.0 + mute-stream: ^2.0.0 + signal-exit: ^4.1.0 + wrap-ansi: ^6.2.0 + yoctocolors-cjs: ^2.1.2 + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 79d528ecb5f485a0f63bd5e48273a2ffba9457240e2a1971da8ea97a97c8398b932260691b8d5e5134f306ba8b08ce7a4800dfa7bd8cc9143a86760714215927 + languageName: node + linkType: hard + +"@inquirer/figures@npm:^1.0.13": + version: 1.0.13 + resolution: "@inquirer/figures@npm:1.0.13" + checksum: 1042cbefad8c69b004396ce6be2d0b135c303317d870ddd0cee75bac429fc7c7f577bac9e3c1ec1cd3668a709f49a591edb2f714193778e7d7b140a622f2a1ef + languageName: node + linkType: hard + +"@inquirer/type@npm:^3.0.8": + version: 3.0.8 + resolution: "@inquirer/type@npm:3.0.8" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 361fa75c98f274462aaa3f2baf40ee43f284daaa64e3689a92863ed4ff63236ca3d40c6e715b3ff80c45feb6ab679792a6162e2d4521daff3929c490b0dddfcf + languageName: node + linkType: hard + +"@isaacs/balanced-match@npm:^4.0.1": + version: 4.0.1 + resolution: "@isaacs/balanced-match@npm:4.0.1" + checksum: 102fbc6d2c0d5edf8f6dbf2b3feb21695a21bc850f11bc47c4f06aa83bd8884fde3fe9d6d797d619901d96865fdcb4569ac2a54c937992c48885c5e3d9967fe8 + languageName: node + linkType: hard + +"@isaacs/brace-expansion@npm:^5.0.0": + version: 5.0.0 + resolution: "@isaacs/brace-expansion@npm:5.0.0" + dependencies: + "@isaacs/balanced-match": ^4.0.1 + checksum: d7a3b8b0ddbf0ccd8eeb1300e29dd0a0c02147e823d8138f248375a365682360620895c66d113e05ee02389318c654379b0e538b996345b83c914941786705b1 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + 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" + checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb + languageName: node + linkType: hard + +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: ^7.0.4 + checksum: 5d36d289960e886484362d9eb6a51d1ea28baed5f5d0140bbe62b99bac52eaf06cc01c2bc0d3575977962f84f6b2c4387b043ee632216643d4787b0999465bf2 + languageName: node + linkType: hard + +"@istanbuljs/load-nyc-config@npm:^1.0.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" + dependencies: + camelcase: ^5.3.1 + find-up: ^4.1.0 + get-package-type: ^0.1.0 + js-yaml: ^3.13.1 + resolve-from: ^5.0.0 + checksum: d578da5e2e804d5c93228450a1380e1a3c691de4953acc162f387b717258512a3e07b83510a936d9fab03eac90817473917e24f5d16297af3867f59328d58568 + languageName: node + linkType: hard + +"@istanbuljs/schema@npm:^0.1.2": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 + languageName: node + linkType: hard + +"@jest/console@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/console@npm:27.5.1" + dependencies: + "@jest/types": ^27.5.1 + "@types/node": "*" + chalk: ^4.0.0 + jest-message-util: ^27.5.1 + jest-util: ^27.5.1 + slash: ^3.0.0 + checksum: 7cb20f06a34b09734c0342685ec53aa4c401fe3757c13a9c58fce76b971a322eb884f6de1068ef96f746e5398e067371b89515a07c268d4440a867c87748a706 + languageName: node + linkType: hard + +"@jest/console@npm:^28.1.3": + version: 28.1.3 + resolution: "@jest/console@npm:28.1.3" + dependencies: + "@jest/types": ^28.1.3 + "@types/node": "*" + chalk: ^4.0.0 + jest-message-util: ^28.1.3 + jest-util: ^28.1.3 + slash: ^3.0.0 + checksum: fe50d98d26d02ce2901c76dff4bd5429a33c13affb692c9ebf8a578ca2f38a5dd854363d40d6c394f215150791fd1f692afd8e730a4178dda24107c8dfd9750a + languageName: node + linkType: hard + +"@jest/core@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/core@npm:27.5.1" + dependencies: + "@jest/console": ^27.5.1 + "@jest/reporters": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 + "@types/node": "*" + ansi-escapes: ^4.2.1 + chalk: ^4.0.0 + emittery: ^0.8.1 + exit: ^0.1.2 + graceful-fs: ^4.2.9 + jest-changed-files: ^27.5.1 + jest-config: ^27.5.1 + jest-haste-map: ^27.5.1 + jest-message-util: ^27.5.1 + jest-regex-util: ^27.5.1 + jest-resolve: ^27.5.1 + jest-resolve-dependencies: ^27.5.1 + jest-runner: ^27.5.1 + jest-runtime: ^27.5.1 + jest-snapshot: ^27.5.1 + jest-util: ^27.5.1 + jest-validate: ^27.5.1 + jest-watcher: ^27.5.1 + micromatch: ^4.0.4 + rimraf: ^3.0.0 + slash: ^3.0.0 + strip-ansi: ^6.0.0 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: 904a94ad8f1b43cd6b48de3b0226659bff3696150ff8cf7680fc2faffdc8a115203bb9ab6e817c1f79f9d6a81f67953053cbc64d8a4604f2e0c42a04c28cf126 + languageName: node + linkType: hard + +"@jest/environment@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/environment@npm:27.5.1" + dependencies: + "@jest/fake-timers": ^27.5.1 + "@jest/types": ^27.5.1 + "@types/node": "*" + jest-mock: ^27.5.1 + checksum: 2a9e18c35a015508dbec5b90b21c150230fa6c1c8cb8fabe029d46ee2ca4c40eb832fb636157da14c66590d0a4c8a2c053226b041f54a44507d6f6a89abefd66 + languageName: node + linkType: hard + +"@jest/expect-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect-utils@npm:29.7.0" + dependencies: + jest-get-type: ^29.6.3 + checksum: 75eb177f3d00b6331bcaa057e07c0ccb0733a1d0a1943e1d8db346779039cb7f103789f16e502f888a3096fb58c2300c38d1f3748b36a7fa762eb6f6d1b160ed + languageName: node + linkType: hard + +"@jest/fake-timers@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/fake-timers@npm:27.5.1" + dependencies: + "@jest/types": ^27.5.1 + "@sinonjs/fake-timers": ^8.0.1 + "@types/node": "*" + jest-message-util: ^27.5.1 + jest-mock: ^27.5.1 + jest-util: ^27.5.1 + checksum: 02a0561ed2f4586093facd4ae500b74694f187ac24d4a00e949a39a1c5325bca8932b4fcb0388a2c5ed0656506fc1cf51fd3e32cdd48cea7497ad9c6e028aba8 + languageName: node + linkType: hard + +"@jest/globals@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/globals@npm:27.5.1" + dependencies: + "@jest/environment": ^27.5.1 + "@jest/types": ^27.5.1 + expect: ^27.5.1 + checksum: 087f97047e9dcf555f76fe2ce54aee681e005eaa837a0c0c2d251df6b6412c892c9df54cb871b180342114389a5ff895a4e52e6e6d3d0015bf83c02a54f64c3c + languageName: node + linkType: hard + +"@jest/reporters@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/reporters@npm:27.5.1" + dependencies: + "@bcoe/v8-coverage": ^0.2.3 + "@jest/console": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 + "@types/node": "*" + chalk: ^4.0.0 + collect-v8-coverage: ^1.0.0 + exit: ^0.1.2 + glob: ^7.1.2 + graceful-fs: ^4.2.9 + istanbul-lib-coverage: ^3.0.0 + istanbul-lib-instrument: ^5.1.0 + istanbul-lib-report: ^3.0.0 + istanbul-lib-source-maps: ^4.0.0 + istanbul-reports: ^3.1.3 + jest-haste-map: ^27.5.1 + jest-resolve: ^27.5.1 + jest-util: ^27.5.1 + jest-worker: ^27.5.1 + slash: ^3.0.0 + source-map: ^0.6.0 + string-length: ^4.0.1 + terminal-link: ^2.0.0 + v8-to-istanbul: ^8.1.0 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: faba5eafb86e62b62e152cafc8812d56308f9d1e8b77f3a7dcae4a8803a20a60a0909cc43ed73363ef649bf558e4fb181c7a336d144c89f7998279d1882bb69e + languageName: node + linkType: hard + +"@jest/schemas@npm:^28.1.3": + version: 28.1.3 + resolution: "@jest/schemas@npm:28.1.3" + dependencies: + "@sinclair/typebox": ^0.24.1 + checksum: 3cf1d4b66c9c4ffda58b246de1ddcba8e6ad085af63dccdf07922511f13b68c0cc480a7bc620cb4f3099a6f134801c747e1df7bfc7a4ef4dceefbdea3e31e1de + languageName: node + linkType: hard + +"@jest/schemas@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/schemas@npm:29.6.3" + dependencies: + "@sinclair/typebox": ^0.27.8 + checksum: 910040425f0fc93cd13e68c750b7885590b8839066dfa0cd78e7def07bbb708ad869381f725945d66f2284de5663bbecf63e8fdd856e2ae6e261ba30b1687e93 + languageName: node + linkType: hard + +"@jest/source-map@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/source-map@npm:27.5.1" + dependencies: + callsites: ^3.0.0 + graceful-fs: ^4.2.9 + source-map: ^0.6.0 + checksum: 4fb1e743b602841babf7e22bd84eca34676cb05d4eb3b604cae57fc59e406099f5ac759ac1a0d04d901237d143f0f4f234417306e823bde732a1d19982230862 + languageName: node + linkType: hard + +"@jest/test-result@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/test-result@npm:27.5.1" + dependencies: + "@jest/console": ^27.5.1 + "@jest/types": ^27.5.1 + "@types/istanbul-lib-coverage": ^2.0.0 + collect-v8-coverage: ^1.0.0 + checksum: 338f7c509d6a3bc6d7dd7388c8f6f548b87638e171dc1fddfedcacb4e8950583288832223ba688058cbcf874b937d22bdc0fa88f79f5fc666f77957e465c06a5 + languageName: node + linkType: hard + +"@jest/test-result@npm:^28.1.3": + version: 28.1.3 + resolution: "@jest/test-result@npm:28.1.3" + dependencies: + "@jest/console": ^28.1.3 + "@jest/types": ^28.1.3 + "@types/istanbul-lib-coverage": ^2.0.0 + collect-v8-coverage: ^1.0.0 + checksum: 957a5dd2fd2e84aabe86698f93c0825e96128ccaa23abf548b159a9b08ac74e4bde7acf4bec48479243dbdb27e4ea1b68c171846d21fb64855c6b55cead9ef27 + languageName: node + linkType: hard + +"@jest/test-sequencer@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/test-sequencer@npm:27.5.1" + dependencies: + "@jest/test-result": ^27.5.1 + graceful-fs: ^4.2.9 + jest-haste-map: ^27.5.1 + jest-runtime: ^27.5.1 + checksum: f21f9c8bb746847f7f89accfd29d6046eec1446f0b54e4694444feaa4df379791f76ef0f5a4360aafcbc73b50bc979f68b8a7620de404019d3de166be6720cb0 + languageName: node + linkType: hard + +"@jest/transform@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/transform@npm:27.5.1" + dependencies: + "@babel/core": ^7.1.0 + "@jest/types": ^27.5.1 + babel-plugin-istanbul: ^6.1.1 + chalk: ^4.0.0 + convert-source-map: ^1.4.0 + fast-json-stable-stringify: ^2.0.0 + graceful-fs: ^4.2.9 + jest-haste-map: ^27.5.1 + jest-regex-util: ^27.5.1 + jest-util: ^27.5.1 + micromatch: ^4.0.4 + pirates: ^4.0.4 + slash: ^3.0.0 + source-map: ^0.6.1 + write-file-atomic: ^3.0.0 + checksum: a22079121aedea0f20a03a9c026be971f7b92adbfb4d5fd1fb67be315741deac4f056936d7c72a53b24aa5a1071bc942c003925fd453bf3f6a0ae5da6384e137 + languageName: node + linkType: hard + +"@jest/types@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/types@npm:27.5.1" + dependencies: + "@types/istanbul-lib-coverage": ^2.0.0 + "@types/istanbul-reports": ^3.0.0 + "@types/node": "*" + "@types/yargs": ^16.0.0 + chalk: ^4.0.0 + checksum: d1f43cc946d87543ddd79d49547aab2399481d34025d5c5f2025d3d99c573e1d9832fa83cef25e9d9b07a8583500229d15bbb07b8e233d127d911d133e2f14b1 + languageName: node + linkType: hard + +"@jest/types@npm:^28.1.3": + version: 28.1.3 + resolution: "@jest/types@npm:28.1.3" + dependencies: "@jest/schemas": ^28.1.3 "@types/istanbul-lib-coverage": ^2.0.0 "@types/istanbul-reports": ^3.0.0 @@ -2466,674 +3690,1683 @@ __metadata: languageName: node linkType: hard -"@jest/types@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/types@npm:29.6.3" +"@jest/types@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/types@npm:29.6.3" + dependencies: + "@jest/schemas": ^29.6.3 + "@types/istanbul-lib-coverage": ^2.0.0 + "@types/istanbul-reports": ^3.0.0 + "@types/node": "*" + "@types/yargs": ^17.0.8 + chalk: ^4.0.0 + checksum: a0bcf15dbb0eca6bdd8ce61a3fb055349d40268622a7670a3b2eb3c3dbafe9eb26af59938366d520b86907b9505b0f9b29b85cec11579a9e580694b87cd90fcc + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" + dependencies: + "@jridgewell/sourcemap-codec": ^1.5.0 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: f2105acefc433337145caa3c84bba286de954f61c0bc46279bbd85a9e6a02871089717fa060413cfb6a9d44189fe8313b2d1cabf3a2eb3284d208fd5f75c54ff + languageName: node + linkType: hard + +"@jridgewell/remapping@npm:^2.3.5": + version: 2.3.5 + resolution: "@jridgewell/remapping@npm:2.3.5" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: 4a66a7397c3dc9c6b5c14a0024b1f98c5e1d90a0dbc1e5955b5038f2db339904df2a0ee8a66559fafb4fc23ff33700a2639fd40bbdd2e9e82b58b3bdf83738e3 + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 + languageName: node + linkType: hard + +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.11 + resolution: "@jridgewell/source-map@npm:0.3.11" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + checksum: c8a0011cc67e701f270fa042e32b312f382c413bcc70ca9c03684687cbf5b64d5eed87d4afa36dddaabe60ab3da6db4935f878febd9cfc7f82724ea1a114d344 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: c2e36e67971f719a8a3a85ef5a5f580622437cc723c35d03ebd0c9c0b06418700ef006f58af742791f71f6a4fc68fcfaf1f6a74ec2f9a3332860e9373459dae7 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" + dependencies: + "@jridgewell/resolve-uri": ^3.0.3 + "@jridgewell/sourcemap-codec": ^1.4.10 + checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: af8fda2431348ad507fbddf8e25f5d08c79ecc94594061ce402cf41bc5aba1a7b3e59bf0fd70a619b35f33983a3f488ceeba8faf56bff784f98bb5394a8b7d47 + languageName: node + linkType: hard + +"@kurkle/color@npm:^0.3.0": + version: 0.3.4 + resolution: "@kurkle/color@npm:0.3.4" + checksum: b95c6abe0241ba1745b3c84de3b464296b95ce577110b54f46e6c6dcc9a0966491533df43812bd6c66f92cf818e385d1390b280cd5851d4afb52fc37f8a6c0b9 + languageName: node + linkType: hard + +"@leichtgewicht/ip-codec@npm:^2.0.1": + version: 2.0.5 + resolution: "@leichtgewicht/ip-codec@npm:2.0.5" + checksum: 4fcd025d0a923cb6b87b631a83436a693b255779c583158bbeacde6b4dd75b94cc1eba1c9c188de5fc36c218d160524ea08bfe4ef03a056b00ff14126d66f881 + languageName: node + linkType: hard + +"@mswjs/interceptors@npm:^0.39.1": + version: 0.39.6 + resolution: "@mswjs/interceptors@npm:0.39.6" + dependencies: + "@open-draft/deferred-promise": ^2.2.0 + "@open-draft/logger": ^0.3.0 + "@open-draft/until": ^2.0.0 + is-node-process: ^1.2.0 + outvariant: ^1.4.3 + strict-event-emitter: ^0.5.1 + checksum: 4960ad247aeabdb6465754ab4646b6441032bdc26cef8c38696240cd3968e99533363f7e71f5d3f8f170b49456c2f1294920c28031327ea7d721320e3863b546 + languageName: node + linkType: hard + +"@mui/base@npm:5.0.0-beta.58": + version: 5.0.0-beta.58 + resolution: "@mui/base@npm:5.0.0-beta.58" + dependencies: + "@babel/runtime": ^7.25.0 + "@floating-ui/react-dom": ^2.1.1 + "@mui/types": ^7.2.15 + "@mui/utils": 6.0.0-rc.0 + "@popperjs/core": ^2.11.8 + clsx: ^2.1.1 + prop-types: ^15.8.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 3603b505aee55aace9be3f4f8fd9c0fde85dfa5d33434bde7651ccd309df3d6872e56603f7739871545bff1cbfdbae0e821a9c60895fbafb049ff5072a77d768 + languageName: node + linkType: hard + +"@mui/core-downloads-tracker@npm:^6.5.0": + version: 6.5.0 + resolution: "@mui/core-downloads-tracker@npm:6.5.0" + checksum: 4354158b8a5f92dea633bb2713bcc0d04493be4038808c44329d3143a0c928914f01e67cb607d0c610bde1f541515c422f69456e50ff919546d1b1f2d349b908 + languageName: node + linkType: hard + +"@mui/icons-material@npm:^6.4.0": + version: 6.5.0 + resolution: "@mui/icons-material@npm:6.5.0" + dependencies: + "@babel/runtime": ^7.26.0 + peerDependencies: + "@mui/material": ^6.5.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 2c1311684cf5bc15faf7b47adc64adbeb02bc1e1b25bb7c2440df10a9ad66c1bd4f8d87e71b75d67f70a32905bdb63e90fd2567a8142f0fa7100c96bbeb127b8 + languageName: node + linkType: hard + +"@mui/lab@npm:6.0.0-beta.10": + version: 6.0.0-beta.10 + resolution: "@mui/lab@npm:6.0.0-beta.10" + dependencies: + "@babel/runtime": ^7.25.6 + "@mui/base": 5.0.0-beta.58 + "@mui/system": ^6.1.1 + "@mui/types": ^7.2.17 + "@mui/utils": ^6.1.1 + clsx: ^2.1.1 + prop-types: ^15.8.1 + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@mui/material": ^6.1.1 + "@mui/material-pigment-css": ^6.1.1 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@mui/material-pigment-css": + optional: true + "@types/react": + optional: true + checksum: 45f2fba7528b84cfd56b6eb1d4ed541069c962dc8ae15c86842a19ba809f6a84e8aeb47e1e33fd07ac32c722cee684cfbe43ba1a91c7b68e7b51a508ed9c2ad8 + languageName: node + linkType: hard + +"@mui/material@npm:^6.4.0": + version: 6.5.0 + resolution: "@mui/material@npm:6.5.0" + dependencies: + "@babel/runtime": ^7.26.0 + "@mui/core-downloads-tracker": ^6.5.0 + "@mui/system": ^6.5.0 + "@mui/types": ~7.2.24 + "@mui/utils": ^6.4.9 + "@popperjs/core": ^2.11.8 + "@types/react-transition-group": ^4.4.12 + clsx: ^2.1.1 + csstype: ^3.1.3 + prop-types: ^15.8.1 + react-is: ^19.0.0 + react-transition-group: ^4.4.5 + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@mui/material-pigment-css": ^6.5.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@mui/material-pigment-css": + optional: true + "@types/react": + optional: true + checksum: a92876ddde82e7569d1e07baefaf84655c00b8323fbe99d1b6a18eb655ff1716fa57660a2f70cfe9381842eabcd71be203fa3efd28be5511c3bf962406217222 + languageName: node + linkType: hard + +"@mui/private-theming@npm:^6.4.9": + version: 6.4.9 + resolution: "@mui/private-theming@npm:6.4.9" + dependencies: + "@babel/runtime": ^7.26.0 + "@mui/utils": ^6.4.9 + prop-types: ^15.8.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 13ffb0b657517fc7c33eab6a19f7b63b7b23fb45fa871ccad5f3c320a49b1cc8a812a7ad03184b38b38082907196c427fcb936fda0952637f809c9ecb16925a1 + languageName: node + linkType: hard + +"@mui/styled-engine@npm:^6.5.0": + version: 6.5.0 + resolution: "@mui/styled-engine@npm:6.5.0" + dependencies: + "@babel/runtime": ^7.26.0 + "@emotion/cache": ^11.13.5 + "@emotion/serialize": ^1.3.3 + "@emotion/sheet": ^1.4.0 + csstype: ^3.1.3 + prop-types: ^15.8.1 + peerDependencies: + "@emotion/react": ^11.4.1 + "@emotion/styled": ^11.3.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + checksum: 6b1d896a694fc96099985330fb75669bb272b242583b5d8f6ae0c048649145d3cfdb0e110dc71d85e37eb480f7fd6e319f17c5a5c6484a85e149cade21789f52 + languageName: node + linkType: hard + +"@mui/system@npm:^6.1.1, @mui/system@npm:^6.4.0, @mui/system@npm:^6.5.0": + version: 6.5.0 + resolution: "@mui/system@npm:6.5.0" + dependencies: + "@babel/runtime": ^7.26.0 + "@mui/private-theming": ^6.4.9 + "@mui/styled-engine": ^6.5.0 + "@mui/types": ~7.2.24 + "@mui/utils": ^6.4.9 + clsx: ^2.1.1 + csstype: ^3.1.3 + prop-types: ^15.8.1 + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: d20d717d53551861f2656a367fe796c2e8b07e131ce5a84fadab6d9bd436a5cb4516ed3c0e6e9dd55e40ada8d0c1ef8d4d29a40562b628cf6bb877942aeaa7c6 + languageName: node + linkType: hard + +"@mui/types@npm:^7.2.15, @mui/types@npm:^7.2.17, @mui/types@npm:^7.4.6": + version: 7.4.6 + resolution: "@mui/types@npm:7.4.6" + dependencies: + "@babel/runtime": ^7.28.3 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 7e4b4ae06066468e8a8211376d0a08250325f4b92f6d2ea24576df37dfcd0f683602567debdf15889e0e4510eb48d677aa0d71a2ed9423c16dbd4b4ecfbccbb9 + languageName: node + linkType: hard + +"@mui/types@npm:~7.2.15, @mui/types@npm:~7.2.24": + version: 7.2.24 + resolution: "@mui/types@npm:7.2.24" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 3a7367f9503e90fc3cce78885b57b54a00f7a04108be8af957fdc882c1bc0af68390920ea3d6aef855e704651ffd4a530e36ccbec4d0f421a176a2c3c432bb95 + languageName: node + linkType: hard + +"@mui/utils@npm:6.0.0-rc.0": + version: 6.0.0-rc.0 + resolution: "@mui/utils@npm:6.0.0-rc.0" + dependencies: + "@babel/runtime": ^7.25.0 + "@mui/types": ^7.2.15 + "@types/prop-types": ^15.7.12 + clsx: ^2.1.1 + prop-types: ^15.8.1 + react-is: ^18.3.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: c2efc89be9f4f0e13d18fd2bdd46c69ef4d7c70b22f5e2026a4a23e443be90f3314599d30f5458e0c7fc48d6c4bac975be278a14f09592315811d59c7ce74825 + languageName: node + linkType: hard + +"@mui/utils@npm:^5.10.3": + version: 5.17.1 + resolution: "@mui/utils@npm:5.17.1" + dependencies: + "@babel/runtime": ^7.23.9 + "@mui/types": ~7.2.15 + "@types/prop-types": ^15.7.12 + clsx: ^2.1.1 + prop-types: ^15.8.1 + react-is: ^19.0.0 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 06f9da7025b9291f1052c0af012fd0f00ff1539bc99880e15f483a85c27bff0e9c3d047511dc5c3177d546c21978227ece2e6f7a7bd91903c72b48b89c45a677 + languageName: node + linkType: hard + +"@mui/utils@npm:^5.16.6 || ^6.0.0 || ^7.0.0": + version: 7.3.2 + resolution: "@mui/utils@npm:7.3.2" + dependencies: + "@babel/runtime": ^7.28.3 + "@mui/types": ^7.4.6 + "@types/prop-types": ^15.7.15 + clsx: ^2.1.1 + prop-types: ^15.8.1 + react-is: ^19.1.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 201fb1f49434c3ee12de3a177660af04cb6411a68f8c13dc62ea828c522758b53040046daf2341b38da3b0a8a455ef4454a49cca4fa4e7b4d345d05e3ca61ecc + languageName: node + linkType: hard + +"@mui/utils@npm:^6.1.1, @mui/utils@npm:^6.4.9": + version: 6.4.9 + resolution: "@mui/utils@npm:6.4.9" + dependencies: + "@babel/runtime": ^7.26.0 + "@mui/types": ~7.2.24 + "@types/prop-types": ^15.7.14 + clsx: ^2.1.1 + prop-types: ^15.8.1 + react-is: ^19.0.0 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: b11d8f76d1c3a6c256a0b832b19b7640ade2d1cda52bb1d04f98ef14b1416461d98af0131399d01f3e327f32c255821e277b175d07723bfc4817eaea249419b1 + languageName: node + linkType: hard + +"@mui/x-data-grid@npm:^5.16.0": + version: 5.17.26 + resolution: "@mui/x-data-grid@npm:5.17.26" + dependencies: + "@babel/runtime": ^7.18.9 + "@mui/utils": ^5.10.3 + clsx: ^1.2.1 + prop-types: ^15.8.1 + reselect: ^4.1.6 + peerDependencies: + "@mui/material": ^5.4.1 + "@mui/system": ^5.4.1 + react: ^17.0.2 || ^18.0.0 + react-dom: ^17.0.2 || ^18.0.0 + checksum: 521d9c76c7275836dda0b7ace197553142a33de702cb172cfdfbaf505379faa7566da5340eb9bdf7980909e8034b1fe0eae2b7aca6a499667ecb76f4442dc9e7 + languageName: node + linkType: hard + +"@mui/x-date-pickers@npm:^7.24.0": + version: 7.29.4 + resolution: "@mui/x-date-pickers@npm:7.29.4" + dependencies: + "@babel/runtime": ^7.25.7 + "@mui/utils": ^5.16.6 || ^6.0.0 || ^7.0.0 + "@mui/x-internals": 7.29.0 + "@types/react-transition-group": ^4.4.11 + clsx: ^2.1.1 + prop-types: ^15.8.1 + react-transition-group: ^4.4.5 + peerDependencies: + "@emotion/react": ^11.9.0 + "@emotion/styled": ^11.8.1 + "@mui/material": ^5.15.14 || ^6.0.0 || ^7.0.0 + "@mui/system": ^5.15.14 || ^6.0.0 || ^7.0.0 + date-fns: ^2.25.0 || ^3.2.0 || ^4.0.0 + date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0 + dayjs: ^1.10.7 + luxon: ^3.0.2 + moment: ^2.29.4 + moment-hijri: ^2.1.2 || ^3.0.0 + moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + date-fns: + optional: true + date-fns-jalali: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + moment-hijri: + optional: true + moment-jalaali: + optional: true + checksum: 00424e91e91e5ae74b0dd66c56121353a625961666a8854c91326f0a85865dfd4b812bd3575b83ccfa06760f149aa94e3bef4be2eb8af708fef1275f95859585 + languageName: node + linkType: hard + +"@mui/x-internals@npm:7.29.0": + version: 7.29.0 + resolution: "@mui/x-internals@npm:7.29.0" + dependencies: + "@babel/runtime": ^7.25.7 + "@mui/utils": ^5.16.6 || ^6.0.0 || ^7.0.0 + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 3e246226bddc03bafe2be7128ea22f9c4a44a5e94bc44f67e630e1c2288f601be3514dec034ab1f2b3bef6937715671cbcc65818338b218f50b89b34d9948290 + languageName: node + linkType: hard + +"@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1": + version: 5.1.1-v1 + resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1" + dependencies: + eslint-scope: 5.1.1 + checksum: f2e3b2d6a6e2d9f163ca22105910c9f850dc4897af0aea3ef0a5886b63d8e1ba6505b71c99cb78a3bba24a09557d601eb21c8dede3f3213753fcfef364eb0e57 + languageName: node + linkType: hard + +"@noble/hashes@npm:^1.1.5": + version: 1.8.0 + resolution: "@noble/hashes@npm:1.8.0" + checksum: c94e98b941963676feaba62475b1ccfa8341e3f572adbb3b684ee38b658df44100187fa0ef4220da580b13f8d27e87d5492623c8a02ecc61f23fb9960c7918f5 + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": 2.0.5 + run-parallel: ^1.1.9 + checksum: a970d595bd23c66c880e0ef1817791432dbb7acbb8d44b7e7d0e7a22f4521260d4a83f7f9fd61d44fda4610105577f8f58a60718105fb38352baed612fd79e59 + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": 2.1.5 + fastq: ^1.6.0 + checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^3.0.0": + version: 3.0.0 + resolution: "@npmcli/agent@npm:3.0.0" + 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 + checksum: e8fc25d536250ed3e669813b36e8c6d805628b472353c57afd8c4fde0fcfcf3dda4ffe22f7af8c9070812ec2e7a03fb41d7151547cef3508efe661a5a3add20f + languageName: node + linkType: hard + +"@npmcli/fs@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/fs@npm:4.0.0" + dependencies: + semver: ^7.3.5 + checksum: 68951c589e9a4328698a35fd82fe71909a257d6f2ede0434d236fa55634f0fbcad9bb8755553ce5849bd25ee6f019f4d435921ac715c853582c4a7f5983c8d4a + languageName: node + linkType: hard + +"@open-draft/deferred-promise@npm:^2.2.0": + version: 2.2.0 + resolution: "@open-draft/deferred-promise@npm:2.2.0" + checksum: 7f29d39725bb8ab5b62f89d88a4202ce2439ac740860979f9e3d0015dfe4bc3daddcfa5727fa4eed482fdbee770aa591b1136b98b0a0f0569a65294f35bdf56a + languageName: node + linkType: hard + +"@open-draft/logger@npm:^0.3.0": + version: 0.3.0 + resolution: "@open-draft/logger@npm:0.3.0" + dependencies: + is-node-process: ^1.2.0 + outvariant: ^1.4.0 + checksum: 7adfe3d0ed8ca32333ce2a77f9a93d561ebc89c989eaa9722f1dc8a2d2854f5de1bef6fa6894cdf58e16fa4dd9cfa99444ea1f5cac6eb1518e9247911ed042d5 + languageName: node + linkType: hard + +"@open-draft/until@npm:^2.0.0, @open-draft/until@npm:^2.1.0": + version: 2.1.0 + resolution: "@open-draft/until@npm:2.1.0" + checksum: 140ea3b16f4a3a6a729c1256050e20a93d408d7aa1e125648ce2665b3c526ed452510c6e4a6f4b15d95fb5e41203fb51510eb8fbc8812d5e5a91880293d66471 + languageName: node + linkType: hard + +"@paralleldrive/cuid2@npm:^2.2.2": + version: 2.2.2 + resolution: "@paralleldrive/cuid2@npm:2.2.2" + dependencies: + "@noble/hashes": ^1.1.5 + checksum: f7f6ac70e0268ec2c72e555719240d5c2c9a859ce541ac1c637eed3f3ee971b42881d299dedafbded53e7365b9e98176c5a31c442c1112f7e9e7306f2fd0ecbb + languageName: node + linkType: hard + +"@parcel/watcher-android-arm64@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-android-arm64@npm:2.5.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-darwin-arm64@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-darwin-arm64@npm:2.5.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-darwin-x64@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-darwin-x64@npm:2.5.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher-freebsd-x64@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-freebsd-x64@npm:2.5.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm-glibc@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-linux-arm-glibc@npm:2.5.1" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm-musl@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-linux-arm-musl@npm:2.5.1" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm64-glibc@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-linux-arm64-glibc@npm:2.5.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm64-musl@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-linux-arm64-musl@npm:2.5.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-linux-x64-glibc@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-linux-x64-glibc@npm:2.5.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-x64-musl@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-linux-x64-musl@npm:2.5.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-win32-arm64@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-win32-arm64@npm:2.5.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-win32-ia32@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-win32-ia32@npm:2.5.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@parcel/watcher-win32-x64@npm:2.5.1": + version: 2.5.1 + resolution: "@parcel/watcher-win32-x64@npm:2.5.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher@npm:^2.4.1": + version: 2.5.1 + resolution: "@parcel/watcher@npm:2.5.1" + dependencies: + "@parcel/watcher-android-arm64": 2.5.1 + "@parcel/watcher-darwin-arm64": 2.5.1 + "@parcel/watcher-darwin-x64": 2.5.1 + "@parcel/watcher-freebsd-x64": 2.5.1 + "@parcel/watcher-linux-arm-glibc": 2.5.1 + "@parcel/watcher-linux-arm-musl": 2.5.1 + "@parcel/watcher-linux-arm64-glibc": 2.5.1 + "@parcel/watcher-linux-arm64-musl": 2.5.1 + "@parcel/watcher-linux-x64-glibc": 2.5.1 + "@parcel/watcher-linux-x64-musl": 2.5.1 + "@parcel/watcher-win32-arm64": 2.5.1 + "@parcel/watcher-win32-ia32": 2.5.1 + "@parcel/watcher-win32-x64": 2.5.1 + detect-libc: ^1.0.3 + is-glob: ^4.0.3 + micromatch: ^4.0.5 + node-addon-api: ^7.0.0 + node-gyp: latest + dependenciesMeta: + "@parcel/watcher-android-arm64": + optional: true + "@parcel/watcher-darwin-arm64": + optional: true + "@parcel/watcher-darwin-x64": + optional: true + "@parcel/watcher-freebsd-x64": + optional: true + "@parcel/watcher-linux-arm-glibc": + optional: true + "@parcel/watcher-linux-arm-musl": + optional: true + "@parcel/watcher-linux-arm64-glibc": + optional: true + "@parcel/watcher-linux-arm64-musl": + optional: true + "@parcel/watcher-linux-x64-glibc": + optional: true + "@parcel/watcher-linux-x64-musl": + optional: true + "@parcel/watcher-win32-arm64": + optional: true + "@parcel/watcher-win32-ia32": + optional: true + "@parcel/watcher-win32-x64": + optional: true + checksum: c6444cd20212929ef2296d5620c0d41343a1719232cb0c947ced51155b8afc1e470c09d238b92f6c3a589e0320048badf5b73cb41790229521be224cbf89e0f4 + languageName: node + linkType: hard + +"@pdf-lib/standard-fonts@npm:^1.0.0": + version: 1.0.0 + resolution: "@pdf-lib/standard-fonts@npm:1.0.0" + dependencies: + pako: ^1.0.6 + checksum: 7dc629b83862424a64b10c7ae34d789e0045a1a589f34a66a7f8e197f177cdb410969424e5d90f67b35c848db8b045cfa0a664941bdfb2d9b5413dbf44232981 + languageName: node + linkType: hard + +"@pdf-lib/upng@npm:^1.0.1": + version: 1.0.1 + resolution: "@pdf-lib/upng@npm:1.0.1" dependencies: - "@jest/schemas": ^29.6.3 - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^17.0.8 - chalk: ^4.0.0 - checksum: a0bcf15dbb0eca6bdd8ce61a3fb055349d40268622a7670a3b2eb3c3dbafe9eb26af59938366d520b86907b9505b0f9b29b85cec11579a9e580694b87cd90fcc + pako: ^1.0.10 + checksum: acd8ac0974a3c2ed12c4e21d6340c4f77f8dde6727a74075b2faf69fb9dc4051b9e576479caf8e870f67d1bb37b953dfe50c4784892b466f01a29b55272d5e1f languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.5 - resolution: "@jridgewell/gen-mapping@npm:0.3.5" +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f + languageName: node + linkType: hard + +"@pkgr/core@npm:^0.2.9": + version: 0.2.9 + resolution: "@pkgr/core@npm:0.2.9" + checksum: bb2fb86977d63f836f8f5b09015d74e6af6488f7a411dcd2bfdca79d76b5a681a9112f41c45bdf88a9069f049718efc6f3900d7f1de66a2ec966068308ae517f + languageName: node + linkType: hard + +"@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.3": + version: 0.5.17 + resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.17" dependencies: - "@jridgewell/set-array": ^1.2.1 - "@jridgewell/sourcemap-codec": ^1.4.10 - "@jridgewell/trace-mapping": ^0.3.24 - checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 + ansi-html: ^0.0.9 + core-js-pure: ^3.23.3 + error-stack-parser: ^2.0.6 + html-entities: ^2.1.0 + loader-utils: ^2.0.4 + schema-utils: ^4.2.0 + source-map: ^0.7.3 + peerDependencies: + "@types/webpack": 4.x || 5.x + react-refresh: ">=0.10.0 <1.0.0" + sockjs-client: ^1.4.0 + type-fest: ">=0.17.0 <5.0.0" + webpack: ">=4.43.0 <6.0.0" + webpack-dev-server: 3.x || 4.x || 5.x + webpack-hot-middleware: 2.x + webpack-plugin-serve: 0.x || 1.x + peerDependenciesMeta: + "@types/webpack": + optional: true + sockjs-client: + optional: true + type-fest: + optional: true + webpack-dev-server: + optional: true + webpack-hot-middleware: + optional: true + webpack-plugin-serve: + optional: true + checksum: ff80b5064f6acba52f18e240dc0a402c5f0980402fd4e5a212a69b9ad6ad76294b4e0f4a78f356cab17b53b88995c6e4dd0b54e6f07c28c2a307cb8bf61fa88f languageName: node linkType: hard -"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": - version: 3.1.2 - resolution: "@jridgewell/resolve-uri@npm:3.1.2" - checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 +"@popperjs/core@npm:^2.11.8": + version: 2.11.8 + resolution: "@popperjs/core@npm:2.11.8" + checksum: e5c69fdebf52a4012f6a1f14817ca8e9599cb1be73dd1387e1785e2ed5e5f0862ff817f420a87c7fc532add1f88a12e25aeb010ffcbdc98eace3d55ce2139cf0 languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.2.1": - version: 1.2.1 - resolution: "@jridgewell/set-array@npm:1.2.1" - checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 +"@prisma/client@npm:6.2.1": + version: 6.2.1 + resolution: "@prisma/client@npm:6.2.1" + peerDependencies: + prisma: "*" + peerDependenciesMeta: + prisma: + optional: true + checksum: ef2e0989a2a1a66881da3e4284e4e0e9af2aa46961db1a8214456c3b7307afb545ac89e100948f82cb1f7957b61bb692752a777d5f7eae5b1f46528ff33a73da languageName: node linkType: hard -"@jridgewell/source-map@npm:^0.3.3": - version: 0.3.6 - resolution: "@jridgewell/source-map@npm:0.3.6" +"@prisma/debug@npm:6.2.1": + version: 6.2.1 + resolution: "@prisma/debug@npm:6.2.1" + checksum: d77a4a8db6b319d7b1a97995cb1346232315e78f05d8c92d371df8cfa24ce7ace9298224b5bd70b57b1b552133dccdec01f60f5cf4aad05a2b26b88af3e04323 + languageName: node + linkType: hard + +"@prisma/engines-version@npm:6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69": + version: 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69 + resolution: "@prisma/engines-version@npm:6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69" + checksum: 813905c757a11c2e4112e63f1b5cd3750e4cf74302bf1d6a3f981ed866eead9e1d0086a61a7fde25e684ef516ad17c052089ee62b538a5bd6142cb7955ec7005 + languageName: node + linkType: hard + +"@prisma/engines@npm:6.2.1": + version: 6.2.1 + resolution: "@prisma/engines@npm:6.2.1" dependencies: - "@jridgewell/gen-mapping": ^0.3.5 - "@jridgewell/trace-mapping": ^0.3.25 - checksum: c9dc7d899397df95e3c9ec287b93c0b56f8e4453cd20743e2b9c8e779b1949bc3cccf6c01bb302779e46560eb45f62ea38d19fedd25370d814734268450a9f30 + "@prisma/debug": 6.2.1 + "@prisma/engines-version": 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69 + "@prisma/fetch-engine": 6.2.1 + "@prisma/get-platform": 6.2.1 + checksum: 33d6d7d9565055f89de1629f03bf8e2b1c3b69cc1a162d852b0809568971fa9264a2b6356026e1d7c64a7a16043056766a76eec75cb79dd3745e63320f8a9125 + languageName: node + linkType: hard + +"@prisma/fetch-engine@npm:6.2.1": + version: 6.2.1 + resolution: "@prisma/fetch-engine@npm:6.2.1" + dependencies: + "@prisma/debug": 6.2.1 + "@prisma/engines-version": 6.2.0-14.4123509d24aa4dede1e864b46351bf2790323b69 + "@prisma/get-platform": 6.2.1 + checksum: 5960e95518eb003171f9870d3bcb87a8402979983c478558b3343a6ad5519f506417418fe91aa017e7a253769fc284df9c9d7c91815500eb92cd9ac8bfbd0d70 + languageName: node + linkType: hard + +"@prisma/get-platform@npm:6.2.1": + version: 6.2.1 + resolution: "@prisma/get-platform@npm:6.2.1" + dependencies: + "@prisma/debug": 6.2.1 + checksum: cb9b5f144d4266bde5990c2c4540a527761033083d64ae9d05980ab88ee8a777f54cc1ea54b707734fc9bf3892dfd194aae896238444a519a3bc0a2a97e32469 + languageName: node + linkType: hard + +"@react-oauth/google@npm:^0.12.1": + version: 0.12.2 + resolution: "@react-oauth/google@npm:0.12.2" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 0ee3394fcf2acc68c75c64a3abfb71f15fe52a1d7a446b1bed6197101ee5d63025c2e4334d8525abebe3da1f69ba808b660bf27e13ba08a646fb193f968d53d6 + languageName: node + linkType: hard + +"@rolldown/pluginutils@npm:1.0.0-beta.27": + version: 1.0.0-beta.27 + resolution: "@rolldown/pluginutils@npm:1.0.0-beta.27" + checksum: b57d8de44534bdbb92e9dda70a29c5b3cb7a13cc3a2efaaf9d27923ca23e2526e9470939fe1d7c6a96623da20aaf96a1517502e1d9a6d4f98fbb544cf502600a + languageName: node + linkType: hard + +"@rollup/plugin-babel@npm:^5.2.0": + version: 5.3.1 + resolution: "@rollup/plugin-babel@npm:5.3.1" + dependencies: + "@babel/helper-module-imports": ^7.10.4 + "@rollup/pluginutils": ^3.1.0 + peerDependencies: + "@babel/core": ^7.0.0 + "@types/babel__core": ^7.1.9 + rollup: ^1.20.0||^2.0.0 + peerDependenciesMeta: + "@types/babel__core": + optional: true + checksum: 220d71e4647330f252ef33d5f29700aef2e8284a0b61acfcceb47617a7f96208aa1ed16eae75619424bf08811ede5241e271a6d031f07026dee6b3a2bdcdc638 + languageName: node + linkType: hard + +"@rollup/plugin-node-resolve@npm:^11.2.1": + version: 11.2.1 + resolution: "@rollup/plugin-node-resolve@npm:11.2.1" + dependencies: + "@rollup/pluginutils": ^3.1.0 + "@types/resolve": 1.17.1 + builtin-modules: ^3.1.0 + deepmerge: ^4.2.2 + is-module: ^1.0.0 + resolve: ^1.19.0 + peerDependencies: + rollup: ^1.20.0||^2.0.0 + checksum: 6f3b3ecf9a0596a5db4212984bdeb13bb7612693602407e9457ada075dea5a5f2e4e124c592352cf27066a88b194de9b9a95390149b52cf335d5b5e17b4e265b + languageName: node + linkType: hard + +"@rollup/plugin-replace@npm:^2.4.1": + version: 2.4.2 + resolution: "@rollup/plugin-replace@npm:2.4.2" + dependencies: + "@rollup/pluginutils": ^3.1.0 + magic-string: ^0.25.7 + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + checksum: b2f1618ee5526d288e2f8ae328dcb326e20e8dc8bd1f60d3e14d6708a5832e4aa44811f7d493f4aed2deeadca86e3b6b0503cd39bf50cfb4b595bb9da027fad0 + languageName: node + linkType: hard + +"@rollup/pluginutils@npm:^3.1.0": + version: 3.1.0 + resolution: "@rollup/pluginutils@npm:3.1.0" + dependencies: + "@types/estree": 0.0.39 + estree-walker: ^1.0.1 + picomatch: ^2.2.2 + peerDependencies: + rollup: ^1.20.0||^2.0.0 + checksum: 8be16e27863c219edbb25a4e6ec2fe0e1e451d9e917b6a43cf2ae5bc025a6b8faaa40f82a6e53b66d0de37b58ff472c6c3d57a83037ae635041f8df959d6d9aa + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.50.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-android-arm64@npm:4.50.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.50.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.50.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.50.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-freebsd-x64@npm:4.50.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.2" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.50.2" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.50.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.50.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loong64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.50.2" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.50.2" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.50.2" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-musl@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.50.2" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.50.2" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.50.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.50.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-openharmony-arm64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.50.2" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.50.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.50.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.50.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 + languageName: node + linkType: hard + +"@rushstack/eslint-patch@npm:^1.1.0": + version: 1.12.0 + resolution: "@rushstack/eslint-patch@npm:1.12.0" + checksum: 186788a93e2f141f622696091a593727fe7964d4925236a308e29754e29dcb182377f8d292ae954d227fb0574433863af055c0156593a40fd525e88b76e891ec + languageName: node + linkType: hard + +"@sinclair/typebox@npm:^0.24.1": + version: 0.24.51 + resolution: "@sinclair/typebox@npm:0.24.51" + checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0 + languageName: node + linkType: hard + +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 + languageName: node + linkType: hard + +"@sinonjs/commons@npm:^1.7.0": + version: 1.8.6 + resolution: "@sinonjs/commons@npm:1.8.6" + dependencies: + type-detect: 4.0.8 + checksum: 7d3f8c1e85f30cd4e83594fc19b7a657f14d49eb8d95a30095631ce15e906c869e0eff96c5b93dffea7490c00418b07f54582ba49c6560feb2a8c34c0b16832d + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^8.0.1": + version: 8.1.0 + resolution: "@sinonjs/fake-timers@npm:8.1.0" + dependencies: + "@sinonjs/commons": ^1.7.0 + checksum: 09b5a158ce013a6c37613258bad79ca4efeb99b1f59c41c73cca36cac00b258aefcf46eeea970fccf06b989414d86fe9f54c1102272c0c3bdd51a313cea80949 + languageName: node + linkType: hard + +"@slack/events-api@npm:^3.0.1": + version: 3.0.1 + resolution: "@slack/events-api@npm:3.0.1" + dependencies: + "@types/debug": ^4.1.4 + "@types/express": ^4.17.0 + "@types/lodash.isstring": ^4.0.6 + "@types/node": ">=12.13.0 < 13" + "@types/yargs": ^15.0.4 + debug: ^2.6.1 + express: ^4.0.0 + lodash.isstring: ^4.0.1 + raw-body: ^2.3.3 + tsscmp: ^1.0.6 + yargs: ^15.3.1 + dependenciesMeta: + express: + optional: true + bin: + slack-verify: dist/verify.js + checksum: ce62dc2ee9dd93b88820e18f88f543228740243dc390caf49b3a7e1ad351b298e3961898bd78f5eb43e9f6acac067458257cd34c9661089f684bb5cf4af468c3 languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.15": - version: 1.4.15 - resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" - checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8 +"@slack/logger@npm:^4.0.0": + version: 4.0.0 + resolution: "@slack/logger@npm:4.0.0" + dependencies: + "@types/node": ">=18.0.0" + checksum: dc79e9d2032c4bf9ce01d96cc72882f003dd376d036f172d4169662cfc2c9b384a80d5546b06021578dd473e7059f064303f0ba851eeb153387f2081a1e3062e languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:0.3.9": - version: 0.3.9 - resolution: "@jridgewell/trace-mapping@npm:0.3.9" - dependencies: - "@jridgewell/resolve-uri": ^3.0.3 - "@jridgewell/sourcemap-codec": ^1.4.10 - checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef +"@slack/types@npm:^2.9.0": + version: 2.16.0 + resolution: "@slack/types@npm:2.16.0" + checksum: f1db2b8c18af245f78d5c178d98ed57fa5c8c18a1ea2e922bc0d330178a483ee7a29834b42a6710ece005789d91266d62195c93e8e2411ca707f8e438442c7f1 languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": - version: 0.3.25 - resolution: "@jridgewell/trace-mapping@npm:0.3.25" +"@slack/web-api@npm:^7.8.0": + version: 7.10.0 + resolution: "@slack/web-api@npm:7.10.0" dependencies: - "@jridgewell/resolve-uri": ^3.1.0 - "@jridgewell/sourcemap-codec": ^1.4.14 - checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 + "@slack/logger": ^4.0.0 + "@slack/types": ^2.9.0 + "@types/node": ">=18.0.0" + "@types/retry": 0.12.0 + axios: ^1.11.0 + eventemitter3: ^5.0.1 + form-data: ^4.0.4 + is-electron: 2.2.2 + is-stream: ^2 + p-queue: ^6 + p-retry: ^4 + retry: ^0.13.1 + checksum: 6aa3f19892713c1efd5ec4dbca493f28725d185de478226b179cc9e8456c5fb7e38dc6092a5a93a6e4ce49e45a6cf2c287d18969b9563b52941db1e1679ecb96 languageName: node linkType: hard -"@mswjs/cookies@npm:^0.2.2": - version: 0.2.2 - resolution: "@mswjs/cookies@npm:0.2.2" +"@smithy/abort-controller@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/abort-controller@npm:4.1.1" dependencies: - "@types/set-cookie-parser": ^2.4.0 - set-cookie-parser: ^2.4.6 - checksum: 23b1ef56d57efcc1b44600076f531a1fb703855af342a31e01bad4adaf0dab51f6d3b5595a95a7988c3f612ba075835f9a06c52833205284d101eb9a51dd72b0 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: c05ba27366becd5ad6eddaf648e440efd51ac21c3721f3da8d03d977826a139cbe48f2c5f52be2ef3178c8692e899c568e7c1dba3724a92fbf248a65e3eeb15b languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.17.2": - version: 0.17.10 - resolution: "@mswjs/interceptors@npm:0.17.10" +"@smithy/config-resolver@npm:^4.2.1, @smithy/config-resolver@npm:^4.2.2": + version: 4.2.2 + resolution: "@smithy/config-resolver@npm:4.2.2" dependencies: - "@open-draft/until": ^1.0.3 - "@types/debug": ^4.1.7 - "@xmldom/xmldom": ^0.8.3 - debug: ^4.3.3 - headers-polyfill: 3.2.5 - outvariant: ^1.2.1 - strict-event-emitter: ^0.2.4 - web-encoding: ^1.1.5 - checksum: 0e6d32f399144b5cefe6fd7620f2776c83adc9bbbbccf2eb4ea347332be059f585136c44168c09b544c41cd3d686f88e43432e10192227a24fbb0c98a2f52dc8 + "@smithy/node-config-provider": ^4.2.2 + "@smithy/types": ^4.5.0 + "@smithy/util-config-provider": ^4.1.0 + "@smithy/util-middleware": ^4.1.1 + tslib: ^2.6.2 + checksum: 9a725596bdb892f07e3797230d26aaa5794ad0a116624ae355249bb8bd88a909d45ece3c788cc50a99d7e7482e8482b0ca1ac304c3d03dfb836c7b3dcf6f7806 languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.40": - version: 5.0.0-beta.40 - resolution: "@mui/base@npm:5.0.0-beta.40" +"@smithy/core@npm:^3.11.0": + version: 3.11.0 + resolution: "@smithy/core@npm:3.11.0" dependencies: - "@babel/runtime": ^7.23.9 - "@floating-ui/react-dom": ^2.0.8 - "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 - "@popperjs/core": ^2.11.8 - clsx: ^2.1.0 - prop-types: ^15.8.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 9c084ee67de372411a71af5eca9a5367db9f5bce57bb43973629c522760fe64fa2a43d2934dccd24d6dcbcd0ed399c5fc5c461226c86104f5767de1c9b8deba2 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-body-length-browser": ^4.1.0 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-stream": ^4.3.1 + "@smithy/util-utf8": ^4.1.0 + "@types/uuid": ^9.0.1 + tslib: ^2.6.2 + uuid: ^9.0.1 + checksum: 1e6274090961398776fbc5e00b93bc84d5fe2aff6bf0909c84d0a03a3e384db03d52bd9a7c147cc5834b9c9511db80121d09a3c81497405718d8cff20892ab02 languageName: node linkType: hard -"@mui/base@npm:^5.0.0-beta.22": - version: 5.0.0-beta.42 - resolution: "@mui/base@npm:5.0.0-beta.42" +"@smithy/credential-provider-imds@npm:^4.0.7, @smithy/credential-provider-imds@npm:^4.1.2": + version: 4.1.2 + resolution: "@smithy/credential-provider-imds@npm:4.1.2" dependencies: - "@babel/runtime": ^7.24.4 - "@floating-ui/react-dom": ^2.0.8 - "@mui/types": ^7.2.14 - "@mui/utils": ^6.0.0-alpha.1 - "@popperjs/core": ^2.11.8 - clsx: ^2.1.0 - prop-types: ^15.8.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: f7af6e6003a4a8502062607b7861490eb6dc3a1f617532c92521981329ae077535444d65e378718bbf59ce8b7a52fc32275dc794969c73bdb389e5d69155fc69 + "@smithy/node-config-provider": ^4.2.2 + "@smithy/property-provider": ^4.1.1 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + tslib: ^2.6.2 + checksum: b62d2b9362296e3c5dda34144a416e1524283a5c9fc7619fc090ebf41579ca6579e067db50bcd2af55f629680a8019ba2d87348ac870ae02b05cb153c625c6b8 languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/core-downloads-tracker@npm:5.15.15" - checksum: 3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc +"@smithy/fetch-http-handler@npm:^5.2.1": + version: 5.2.1 + resolution: "@smithy/fetch-http-handler@npm:5.2.1" + dependencies: + "@smithy/protocol-http": ^5.2.1 + "@smithy/querystring-builder": ^4.1.1 + "@smithy/types": ^4.5.0 + "@smithy/util-base64": ^4.1.0 + tslib: ^2.6.2 + checksum: 68733a2d4a47002c9059af23078712ebc451dacca9542a3f6a70ba2288a017bb474a15ff6c10816c04296011c833d9ad8f957d22eedb33ea3a0edc12ad62160e languageName: node linkType: hard -"@mui/icons-material@npm:^5.10.3": - version: 5.15.15 - resolution: "@mui/icons-material@npm:5.15.15" +"@smithy/hash-node@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/hash-node@npm:4.1.1" dependencies: - "@babel/runtime": ^7.23.9 - peerDependencies: - "@mui/material": ^5.0.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 42d62fc94be25a361034a8974b1860608e866c155ff2eea7dc18f10a4acc71dbe2f48af3f0309a345ff6fb16be30c6fbc1d8a0a447c828aa1380a49e176a8803 + "@smithy/types": ^4.5.0 + "@smithy/util-buffer-from": ^4.1.0 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: ee0d5ed0355d5551cc8805e55dcca582d75b062c15b5f1cde15a0376b3e0254ef4803a80f16f1c4125a985545e4fa99b4a7021199cc5ffa5457f829056962146 languageName: node linkType: hard -"@mui/material@npm:^5.10.3": - version: 5.15.15 - resolution: "@mui/material@npm:5.15.15" +"@smithy/invalid-dependency@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/invalid-dependency@npm:4.1.1" dependencies: - "@babel/runtime": ^7.23.9 - "@mui/base": 5.0.0-beta.40 - "@mui/core-downloads-tracker": ^5.15.15 - "@mui/system": ^5.15.15 - "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 - "@types/react-transition-group": ^4.4.10 - clsx: ^2.1.0 - csstype: ^3.1.3 - prop-types: ^15.8.1 - react-is: ^18.2.0 - react-transition-group: ^4.4.5 - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@types/react": - optional: true - checksum: ee0dc22fc4d617f7cf69f2451b6d5139978e6c5319e3056e7719159aff786ee3b80abd07691e230371811d9b5b574aef4559d7855bfe2f8493d596d960a91ab7 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 039893fddde6786eb0c50c1a7c33768e9b052c5bc36c5ff1bec517290dab06f9e8ddf07323a3ef594f80b30fc4eaeb35bed1e0ef9b7aa9588aa99f169dd02ada languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/private-theming@npm:5.15.14" +"@smithy/is-array-buffer@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/is-array-buffer@npm:2.2.0" dependencies: - "@babel/runtime": ^7.23.9 - "@mui/utils": ^5.15.14 - prop-types: ^15.8.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 1b1ef54e8281c9b13fcc58f4c39682efc610946a68402283c19fcfbce8a7d7a231d61b536d6df9bf7a59a1426591bd403a453a59eb8efb9689437fb58554dc8c + tslib: ^2.6.2 + checksum: cd12c2e27884fec89ca8966d33c9dc34d3234efe89b33a9b309c61ebcde463e6f15f6a02d31d4fddbfd6e5904743524ca5b95021b517b98fe10957c2da0cd5fc languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/styled-engine@npm:5.15.14" +"@smithy/is-array-buffer@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/is-array-buffer@npm:4.1.0" dependencies: - "@babel/runtime": ^7.23.9 - "@emotion/cache": ^11.11.0 - csstype: ^3.1.3 - prop-types: ^15.8.1 - peerDependencies: - "@emotion/react": ^11.4.1 - "@emotion/styled": ^11.3.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - checksum: 23b45c859a4f0d2b10933d06a6082c0ff093f7b6d8d32a2bfe3a6e515fe46d7a38ca9e7150d45c025a2e98d963bae9a5991d131cf4748b62670075ef0fa321ed + tslib: ^2.6.2 + checksum: 8ab4c920f9f9dc10dadcbc32fef439e9809da8065898ef05007c46c9d4a6494b512240cd25652b8be533f17aee0ce441c412fa0de535128ea7f8e610fda3acbd languageName: node linkType: hard -"@mui/system@npm:^5.10.16, @mui/system@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/system@npm:5.15.15" +"@smithy/middleware-content-length@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-content-length@npm:4.1.1" dependencies: - "@babel/runtime": ^7.23.9 - "@mui/private-theming": ^5.15.14 - "@mui/styled-engine": ^5.15.14 - "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 - clsx: ^2.1.0 - csstype: ^3.1.3 - prop-types: ^15.8.1 - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@types/react": - optional: true - checksum: 9ca96d5f66b2a9d6471909cc98c671eea5ec0a6d58a7ec071073b9e5200b95c3f017f0ca5cc946abc7f83074bd11830ca18f5e30bc98e25cd6ca217bd1b3a26f + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: e136bd0f2a95b6baba0d226289bfa430f2cad9180f952d4b8abda49362adbbe02cfed85726dd54d4be3f7e07196e6dffd1af56616ab922b1485571891dae3633 languageName: node linkType: hard -"@mui/types@npm:^7.2.14": - version: 7.2.14 - resolution: "@mui/types@npm:7.2.14" - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 615c9f9110933157f5d3c4fee69d6e70b98fc0d9ebc3b63079b6a1e23e6b389748687a25ab4ac15b56166fc228885da87c3929503b41fa322cfdee0f6d411206 +"@smithy/middleware-endpoint@npm:^4.2.1, @smithy/middleware-endpoint@npm:^4.2.2": + version: 4.2.2 + resolution: "@smithy/middleware-endpoint@npm:4.2.2" + dependencies: + "@smithy/core": ^3.11.0 + "@smithy/middleware-serde": ^4.1.1 + "@smithy/node-config-provider": ^4.2.2 + "@smithy/shared-ini-file-loader": ^4.2.0 + "@smithy/types": ^4.5.0 + "@smithy/url-parser": ^4.1.1 + "@smithy/util-middleware": ^4.1.1 + tslib: ^2.6.2 + checksum: e058f390f9f3fd5c14c34d1a95afb31a0185611a68dd4888ea9d70c3291a9e4a627788ba33f7563acdc4d054668ce13c8093830a4bb4badb5c3e0bf4d31d412b languageName: node linkType: hard -"@mui/utils@npm:^5.10.3, @mui/utils@npm:^5.14.16, @mui/utils@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/utils@npm:5.15.14" +"@smithy/middleware-retry@npm:^4.2.1": + version: 4.2.2 + resolution: "@smithy/middleware-retry@npm:4.2.2" dependencies: - "@babel/runtime": ^7.23.9 - "@types/prop-types": ^15.7.11 - prop-types: ^15.8.1 - react-is: ^18.2.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 36543ba7e3b65fb3219ed27e8f1455aff15b47a74c9b642c63e60774e22baa6492a196079e72bcfa5a570421dab32160398f892110bd444428bcf8b266b11893 + "@smithy/node-config-provider": ^4.2.2 + "@smithy/protocol-http": ^5.2.1 + "@smithy/service-error-classification": ^4.1.1 + "@smithy/smithy-client": ^4.6.2 + "@smithy/types": ^4.5.0 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-retry": ^4.1.1 + "@types/uuid": ^9.0.1 + tslib: ^2.6.2 + uuid: ^9.0.1 + checksum: 57b44854d595a556fe7b5adcea9089edd85cda1c32e4cc59ac03fb71879bcdb1274e4723dcae1604d83fe2780a9ce63b106d6992d3c0daf37bfb675ee17a5af6 languageName: node linkType: hard -"@mui/utils@npm:^6.0.0-alpha.1": - version: 6.0.0-alpha.3 - resolution: "@mui/utils@npm:6.0.0-alpha.3" +"@smithy/middleware-serde@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-serde@npm:4.1.1" dependencies: - "@babel/runtime": ^7.24.4 - "@types/prop-types": ^15.7.12 - prop-types: ^15.8.1 - react-is: ^18.2.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 4122813e8f10b0c907ab28e062287e234760a532203b47459469411460302e33856b2bd43c4febcc0b8f5b0ad4f8f028f3e6af8e34631e35e5fe9f82b9f0a330 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: e0f6d3895ec83b2e70a8282d058c1862d73ed4d6a2ca878cda6c97b439e52bf3df3f3b4c44e7749262cdf87e5e7c30d10f1fb081ade79689cf0ac17061cf447b languageName: node linkType: hard -"@mui/x-data-grid@npm:^5.16.0": - version: 5.17.26 - resolution: "@mui/x-data-grid@npm:5.17.26" +"@smithy/middleware-stack@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/middleware-stack@npm:4.1.1" dependencies: - "@babel/runtime": ^7.18.9 - "@mui/utils": ^5.10.3 - clsx: ^1.2.1 - prop-types: ^15.8.1 - reselect: ^4.1.6 - peerDependencies: - "@mui/material": ^5.4.1 - "@mui/system": ^5.4.1 - react: ^17.0.2 || ^18.0.0 - react-dom: ^17.0.2 || ^18.0.0 - checksum: 521d9c76c7275836dda0b7ace197553142a33de702cb172cfdfbaf505379faa7566da5340eb9bdf7980909e8034b1fe0eae2b7aca6a499667ecb76f4442dc9e7 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 9046afc321356a8d26d1db41a700a5ac0d9d370d561725c0bb9239db7aaa2ad02b3747998da6497238a3c4bd7169cbbf8bd4936c123f0fc219c4b17611a663ea languageName: node linkType: hard -"@mui/x-date-pickers@npm:^6.19.4": - version: 6.19.9 - resolution: "@mui/x-date-pickers@npm:6.19.9" +"@smithy/node-config-provider@npm:^4.2.1, @smithy/node-config-provider@npm:^4.2.2": + version: 4.2.2 + resolution: "@smithy/node-config-provider@npm:4.2.2" dependencies: - "@babel/runtime": ^7.23.2 - "@mui/base": ^5.0.0-beta.22 - "@mui/utils": ^5.14.16 - "@types/react-transition-group": ^4.4.8 - clsx: ^2.0.0 - prop-types: ^15.8.1 - react-transition-group: ^4.4.5 - peerDependencies: - "@emotion/react": ^11.9.0 - "@emotion/styled": ^11.8.1 - "@mui/material": ^5.8.6 - "@mui/system": ^5.8.0 - date-fns: ^2.25.0 || ^3.2.0 - date-fns-jalali: ^2.13.0-0 - dayjs: ^1.10.7 - luxon: ^3.0.2 - moment: ^2.29.4 - moment-hijri: ^2.1.2 - moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - date-fns: - optional: true - date-fns-jalali: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - moment-hijri: - optional: true - moment-jalaali: - optional: true - checksum: 830d9cb64187613fdb99cdf465ba6b144169dae944e2c850eedb360d4c8e11943f3b602ffa7c141a4ecf6b02e278f56cd58186b1c25b6beb42d047a9dcbddf56 + "@smithy/property-provider": ^4.1.1 + "@smithy/shared-ini-file-loader": ^4.2.0 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 671845a3d00b53ee0fa2c97e4345cfd2ade99945aec6d47c0545e5366d5332aed774b4d84774924dec26a0ed92de1df139619426f9d0e34ac0afdd40cea2fba7 languageName: node linkType: hard -"@nodelib/fs.scandir@npm:2.1.5": - version: 2.1.5 - resolution: "@nodelib/fs.scandir@npm:2.1.5" +"@smithy/node-http-handler@npm:^4.2.1": + version: 4.2.1 + resolution: "@smithy/node-http-handler@npm:4.2.1" dependencies: - "@nodelib/fs.stat": 2.0.5 - run-parallel: ^1.1.9 - checksum: a970d595bd23c66c880e0ef1817791432dbb7acbb8d44b7e7d0e7a22f4521260d4a83f7f9fd61d44fda4610105577f8f58a60718105fb38352baed612fd79e59 + "@smithy/abort-controller": ^4.1.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/querystring-builder": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 93d006a5908b41cf8bb9b4564c4f2274825db44755dd6949490405e859419cba73afd6c34de93a4e2ee4ef7cc2524a91853fbcca16261ab302b1bd08e73694c9 languageName: node linkType: hard -"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": - version: 2.0.5 - resolution: "@nodelib/fs.stat@npm:2.0.5" - checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 +"@smithy/property-provider@npm:^4.0.5, @smithy/property-provider@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/property-provider@npm:4.1.1" + dependencies: + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 0173716227d82d50845121202dc157dd23e75786d3ab994ea91666e2441a66c972c27e71d67992688a10b7ca4e988a7b809668d20c0c35a66a39c824842fd6ee languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3": - version: 1.2.8 - resolution: "@nodelib/fs.walk@npm:1.2.8" +"@smithy/protocol-http@npm:^5.2.1": + version: 5.2.1 + resolution: "@smithy/protocol-http@npm:5.2.1" dependencies: - "@nodelib/fs.scandir": 2.1.5 - fastq: ^1.6.0 - checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 6a8509a7fd38a039e6db10d372f0698ea841fe73c49cb7f03a7718ff2b5e60776f4f3a9d7658020f9ad981917ce46e40d7d38fbd8675330031d6483ef3aafc42 languageName: node linkType: hard -"@npmcli/agent@npm:^2.0.0": - version: 2.2.2 - resolution: "@npmcli/agent@npm:2.2.2" +"@smithy/querystring-builder@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/querystring-builder@npm:4.1.1" 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 - checksum: 67de7b88cc627a79743c88bab35e023e23daf13831a8aa4e15f998b92f5507b644d8ffc3788afc8e64423c612e0785a6a92b74782ce368f49a6746084b50d874 + "@smithy/types": ^4.5.0 + "@smithy/util-uri-escape": ^4.1.0 + tslib: ^2.6.2 + checksum: 01d7ff1a21547a8a7e687ebcb7f2b9c94c8cd62403e1c5e88fab340c7e5bc11162e66b08d1b75876c7221e352272e33dd2066a19e270171f8eb63bbf6a1d92a6 languageName: node linkType: hard -"@npmcli/fs@npm:^1.0.0": - version: 1.1.1 - resolution: "@npmcli/fs@npm:1.1.1" +"@smithy/querystring-parser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/querystring-parser@npm:4.1.1" dependencies: - "@gar/promisify": ^1.0.1 - semver: ^7.3.5 - checksum: f5ad92f157ed222e4e31c352333d0901df02c7c04311e42a81d8eb555d4ec4276ea9c635011757de20cc476755af33e91622838de573b17e52e2e7703f0a9965 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: b70f09e2a778a6037d9ff3e9c67707d4744dba4d0f760b9e79a0d4469ff6f68d493d1c3d4104441de040cf8ab6e15acc06ae5dbba7a30a418306af3771117cba languageName: node linkType: hard -"@npmcli/fs@npm:^3.1.0": - version: 3.1.0 - resolution: "@npmcli/fs@npm:3.1.0" +"@smithy/service-error-classification@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/service-error-classification@npm:4.1.1" dependencies: - semver: ^7.3.5 - checksum: a50a6818de5fc557d0b0e6f50ec780a7a02ab8ad07e5ac8b16bf519e0ad60a144ac64f97d05c443c3367235d337182e1d012bbac0eb8dbae8dc7b40b193efd0e + "@smithy/types": ^4.5.0 + checksum: 7d8bc8fa9faf4047b8386e45e74f033feedd8824483ab8ab9a37046405a6a5c15cf66d1f7e32a179336b415974d1b55b750727c823d55b288618793dfefb0633 languageName: node linkType: hard -"@npmcli/move-file@npm:^1.0.1": - version: 1.1.2 - resolution: "@npmcli/move-file@npm:1.1.2" +"@smithy/shared-ini-file-loader@npm:^4.0.5, @smithy/shared-ini-file-loader@npm:^4.2.0": + version: 4.2.0 + resolution: "@smithy/shared-ini-file-loader@npm:4.2.0" dependencies: - mkdirp: ^1.0.4 - rimraf: ^3.0.2 - checksum: c96381d4a37448ea280951e46233f7e541058cf57a57d4094dd4bdcaae43fa5872b5f2eb6bfb004591a68e29c5877abe3cdc210cb3588cbf20ab2877f31a7de7 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: d89d2b620575f9b8d255c39a28f6b76accba57e79b164e490aab801c61744819e2164c7d26f6c986dc38366e08659896dbba58ea7c179a95fc18398d934cc821 languageName: node linkType: hard -"@open-draft/until@npm:^1.0.3": - version: 1.0.3 - resolution: "@open-draft/until@npm:1.0.3" - checksum: 323e92ebef0150ed0f8caedc7d219b68cdc50784fa4eba0377eef93533d3f46514eb2400ced83dda8c51bddc3d2c7b8e9cf95e5ec85ab7f62dfc015d174f62f2 +"@smithy/signature-v4@npm:^5.1.3": + version: 5.2.1 + resolution: "@smithy/signature-v4@npm:5.2.1" + dependencies: + "@smithy/is-array-buffer": ^4.1.0 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-hex-encoding": ^4.1.0 + "@smithy/util-middleware": ^4.1.1 + "@smithy/util-uri-escape": ^4.1.0 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: d609451fead77465d04b3d2fb614cfd51c5c66020429ecf97c871952e70d0cacb9d4ff8b15271cc7b38fcfa852b3d141e1811804ecab0eb522cadb9d43f3c10c languageName: node linkType: hard -"@pdf-lib/standard-fonts@npm:^1.0.0": - version: 1.0.0 - resolution: "@pdf-lib/standard-fonts@npm:1.0.0" +"@smithy/smithy-client@npm:^4.6.1, @smithy/smithy-client@npm:^4.6.2": + version: 4.6.2 + resolution: "@smithy/smithy-client@npm:4.6.2" dependencies: - pako: ^1.0.6 - checksum: 7dc629b83862424a64b10c7ae34d789e0045a1a589f34a66a7f8e197f177cdb410969424e5d90f67b35c848db8b045cfa0a664941bdfb2d9b5413dbf44232981 + "@smithy/core": ^3.11.0 + "@smithy/middleware-endpoint": ^4.2.2 + "@smithy/middleware-stack": ^4.1.1 + "@smithy/protocol-http": ^5.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-stream": ^4.3.1 + tslib: ^2.6.2 + checksum: a1a6510dcc075c7055852d8ba8c3f69bd3fa93aad45d3659bb63a0d20d043a2628ed6a8ca75034ae69f23ed3a32d6252dd45ef5b396d285245c57ed143138e70 languageName: node linkType: hard -"@pdf-lib/upng@npm:^1.0.1": - version: 1.0.1 - resolution: "@pdf-lib/upng@npm:1.0.1" +"@smithy/types@npm:^4.5.0": + version: 4.5.0 + resolution: "@smithy/types@npm:4.5.0" dependencies: - pako: ^1.0.10 - checksum: acd8ac0974a3c2ed12c4e21d6340c4f77f8dde6727a74075b2faf69fb9dc4051b9e576479caf8e870f67d1bb37b953dfe50c4784892b466f01a29b55272d5e1f + tslib: ^2.6.2 + checksum: 5fb38dcf554e8ecf3654cbcc295fffcf35517f7e792ed158f4119223982f57d4e3ec79ad56e8e9a590c8843990bef217da8a88e02e197ee7f6d4737abcc9c075 languageName: node linkType: hard -"@pkgjs/parseargs@npm:^0.11.0": - version: 0.11.0 - resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f +"@smithy/url-parser@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/url-parser@npm:4.1.1" + dependencies: + "@smithy/querystring-parser": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 189d60c99b3610bb4be2f32474551e4431273891093232f38553a27541ba1379df70a625b83390f259aafbddb3307e531b8210148c854eb39763e2d0e5ec3769 languageName: node linkType: hard - -"@pmmmwh/react-refresh-webpack-plugin@npm:0.4.3": - version: 0.4.3 - resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.4.3" - dependencies: - ansi-html: ^0.0.7 - error-stack-parser: ^2.0.6 - html-entities: ^1.2.1 - native-url: ^0.2.6 - schema-utils: ^2.6.5 - source-map: ^0.7.3 - peerDependencies: - "@types/webpack": 4.x - react-refresh: ">=0.8.3 <0.10.0" - sockjs-client: ^1.4.0 - type-fest: ^0.13.1 - webpack: ">=4.43.0 <6.0.0" - webpack-dev-server: 3.x - webpack-hot-middleware: 2.x - webpack-plugin-serve: 0.x || 1.x - peerDependenciesMeta: - "@types/webpack": - optional: true - sockjs-client: - optional: true - type-fest: - optional: true - webpack-dev-server: - optional: true - webpack-hot-middleware: - optional: true - webpack-plugin-serve: - optional: true - checksum: 36a7b0c63f0aabde856a2b43f3f3bfa7919920afa67b4fbcf7d4980b286c7c11e34ada13654d81bf30c3d3e2c12a5b9eef6c15e21a200003b8030809d3ddd6c6 + +"@smithy/util-base64@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-base64@npm:4.1.0" + dependencies: + "@smithy/util-buffer-from": ^4.1.0 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: 8855de07897631f835fc47b9c17938a5e927291ce6ef08cfd1424431333fc4c4797c18e2094790c5331388f39bd5ed0a76a913e9b7f3c7f61c0e228bf18a3cf9 languageName: node linkType: hard -"@popperjs/core@npm:^2.11.8": - version: 2.11.8 - resolution: "@popperjs/core@npm:2.11.8" - checksum: e5c69fdebf52a4012f6a1f14817ca8e9599cb1be73dd1387e1785e2ed5e5f0862ff817f420a87c7fc532add1f88a12e25aeb010ffcbdc98eace3d55ce2139cf0 +"@smithy/util-body-length-browser@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-body-length-browser@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: 7aa162eb084ffeb7b0b6d504494e248e7da72447f08cda02120d5594ddb146544dcee19b92d6e57dc3115372e2ce018147692e44c7cb1498f634a3fa17d22aa9 languageName: node linkType: hard -"@prisma/client@npm:^4.4.0": - version: 4.16.2 - resolution: "@prisma/client@npm:4.16.2" +"@smithy/util-body-length-node@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-body-length-node@npm:4.1.0" dependencies: - "@prisma/engines-version": 4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81 - peerDependencies: - prisma: "*" - peerDependenciesMeta: - prisma: - optional: true - checksum: 38e1356644a764946c69c8691ea4bbed0ba37739d833a435625bd5435912bed4b9bdd7c384125f3a4ab8128faf566027985c0f0840a42741c338d72e40b5d565 + tslib: ^2.6.2 + checksum: dfaf22fd6fc086544f582dd5c64a4416c01bad8b92f5891add84b9086a9b0a8815659269c91b8adee7ef3b36f21701c6aaab2313bfbe21a2c189eb15943a0c25 languageName: node linkType: hard -"@prisma/engines-version@npm:4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81": - version: 4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81 - resolution: "@prisma/engines-version@npm:4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81" - checksum: b42c6abe7c1928e546f15449e40ffa455701ef2ab1f62973628ecb4e19ff3652e34609a0d83196d1cbd0864adb44c55e082beec852b11929acf1c15fb57ca45a +"@smithy/util-buffer-from@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-buffer-from@npm:2.2.0" + dependencies: + "@smithy/is-array-buffer": ^2.2.0 + tslib: ^2.6.2 + checksum: 424c5b7368ae5880a8f2732e298d17879a19ca925f24ca45e1c6c005f717bb15b76eb28174d308d81631ad457ea0088aab0fd3255dd42f45a535c81944ad64d3 languageName: node linkType: hard -"@prisma/engines@npm:4.16.2": - version: 4.16.2 - resolution: "@prisma/engines@npm:4.16.2" - checksum: f423e6092c3e558cd089a68ae87459fba7fd390c433df087342b3269c3b04163965b50845150dfe47d01f811781bfff89d5ae81c95ca603c59359ab69ebd810f +"@smithy/util-buffer-from@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-buffer-from@npm:4.1.0" + dependencies: + "@smithy/is-array-buffer": ^4.1.0 + tslib: ^2.6.2 + checksum: a8523e142cfa8a5526ada1bb2f4264c7dc6027875a16752995324c294ea6b2bd502303db16ac74eb49fe602f20d847cdb09054d611e3aa9916c09b7a41e379c0 languageName: node linkType: hard -"@rollup/plugin-node-resolve@npm:^7.1.1": - version: 7.1.3 - resolution: "@rollup/plugin-node-resolve@npm:7.1.3" +"@smithy/util-config-provider@npm:^4.0.0, @smithy/util-config-provider@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-config-provider@npm:4.1.0" dependencies: - "@rollup/pluginutils": ^3.0.8 - "@types/resolve": 0.0.8 - builtin-modules: ^3.1.0 - is-module: ^1.0.0 - resolve: ^1.14.2 - peerDependencies: - rollup: ^1.20.0||^2.0.0 - checksum: e787c35f123652762d212b63f8cfaf577307434a935466397021c31b71d0d94357c6fa4e326b49bf44b959e22e41bc21f5648470eabec086566e7c36c5d041b1 + tslib: ^2.6.2 + checksum: 8d13ec9246b05bc3b8af9312ba53d266cb9fff6400957630e3288ed1807c6fb433a7383df385282b84f699f112653069008b9c972e520393a4fed88d19a2e8e3 languageName: node linkType: hard -"@rollup/plugin-replace@npm:^2.3.1": - version: 2.4.2 - resolution: "@rollup/plugin-replace@npm:2.4.2" +"@smithy/util-defaults-mode-browser@npm:^4.1.1": + version: 4.1.2 + resolution: "@smithy/util-defaults-mode-browser@npm:4.1.2" dependencies: - "@rollup/pluginutils": ^3.1.0 - magic-string: ^0.25.7 - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 - checksum: b2f1618ee5526d288e2f8ae328dcb326e20e8dc8bd1f60d3e14d6708a5832e4aa44811f7d493f4aed2deeadca86e3b6b0503cd39bf50cfb4b595bb9da027fad0 + "@smithy/property-provider": ^4.1.1 + "@smithy/smithy-client": ^4.6.2 + "@smithy/types": ^4.5.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 78a4e34c47e8df6ad0363be3eddc2fe47465cfb9c2cc373a17f724f914f402c33811a69ff7d00b8aefb53e91911eb1b404f02c3f0a571fed945bb91f65e907f3 languageName: node linkType: hard -"@rollup/pluginutils@npm:^3.0.8, @rollup/pluginutils@npm:^3.1.0": - version: 3.1.0 - resolution: "@rollup/pluginutils@npm:3.1.0" +"@smithy/util-defaults-mode-node@npm:^4.1.1": + version: 4.1.2 + resolution: "@smithy/util-defaults-mode-node@npm:4.1.2" dependencies: - "@types/estree": 0.0.39 - estree-walker: ^1.0.1 - picomatch: ^2.2.2 - peerDependencies: - rollup: ^1.20.0||^2.0.0 - checksum: 8be16e27863c219edbb25a4e6ec2fe0e1e451d9e917b6a43cf2ae5bc025a6b8faaa40f82a6e53b66d0de37b58ff472c6c3d57a83037ae635041f8df959d6d9aa + "@smithy/config-resolver": ^4.2.2 + "@smithy/credential-provider-imds": ^4.1.2 + "@smithy/node-config-provider": ^4.2.2 + "@smithy/property-provider": ^4.1.1 + "@smithy/smithy-client": ^4.6.2 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 41499f7b5161e38b60888274504cdde86baede02f8000f0ebc63d42013fd945719ffd254bed87205f41ff54f6c489123ea3caee3457efcdeec0bfb734553cd26 languageName: node linkType: hard -"@sinclair/typebox@npm:^0.24.1": - version: 0.24.51 - resolution: "@sinclair/typebox@npm:0.24.51" - checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0 +"@smithy/util-endpoints@npm:^3.1.1": + version: 3.1.2 + resolution: "@smithy/util-endpoints@npm:3.1.2" + dependencies: + "@smithy/node-config-provider": ^4.2.2 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: fc024b99eee4d1157bd6edc5ae45f7ced9dba2e1ee978ed963bad0bef379f15e664e864989e3177c362d55a26b0dee52b32803023e04954206a3e8c22cdb8a2a languageName: node linkType: hard -"@sinclair/typebox@npm:^0.27.8": - version: 0.27.8 - resolution: "@sinclair/typebox@npm:0.27.8" - checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 +"@smithy/util-hex-encoding@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-hex-encoding@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: 0005c0569a18edc9a6fe991acca95c35e1bfecaf7bb4a9ed2a54eed249e7ccc3662c7d5e3c995db5c47dece9841690f56c4cb93b5adc8681c9436dd7cb8ebff5 languageName: node linkType: hard -"@sinonjs/commons@npm:^1.7.0": - version: 1.8.6 - resolution: "@sinonjs/commons@npm:1.8.6" +"@smithy/util-middleware@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-middleware@npm:4.1.1" dependencies: - type-detect: 4.0.8 - checksum: 7d3f8c1e85f30cd4e83594fc19b7a657f14d49eb8d95a30095631ce15e906c869e0eff96c5b93dffea7490c00418b07f54582ba49c6560feb2a8c34c0b16832d + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 9f8dc9f29730f70c0575920f9f88073af0c8359e1e0a4114a60834cf1053f6ee8df687814f8f4f9b87a02a591a2a3592ffa2b0d7b93234309fe1cdc52cd51e3a languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^6.0.1": - version: 6.0.1 - resolution: "@sinonjs/fake-timers@npm:6.0.1" +"@smithy/util-retry@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-retry@npm:4.1.1" dependencies: - "@sinonjs/commons": ^1.7.0 - checksum: 8e331aa1412d905ecc8efd63550f58a6f77dcb510f878172004e53be63eb82650623618763001a918fc5e21257b86c45041e4e97c454ed6a2d187de084abbd11 + "@smithy/service-error-classification": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: 7ed26ae7b9cd810752f692c749bb8ad083c8fd5000cfd00c9c917806156486b84afb7b8fcf968395b84b3552a6bf46562ec479b97ab4f0cb9d4b121958f1cd5f languageName: node linkType: hard -"@slack/logger@npm:^3.0.0": - version: 3.0.0 - resolution: "@slack/logger@npm:3.0.0" +"@smithy/util-stream@npm:^4.3.1": + version: 4.3.1 + resolution: "@smithy/util-stream@npm:4.3.1" dependencies: - "@types/node": ">=12.0.0" - checksum: 6512d0e9e4be47ea465705ab9b6e6901f36fa981da0d4a657fde649d452b567b351002049b5ee0a22569b5119bf6c2f61befd5b8022d878addb7a99c91b03389 + "@smithy/fetch-http-handler": ^5.2.1 + "@smithy/node-http-handler": ^4.2.1 + "@smithy/types": ^4.5.0 + "@smithy/util-base64": ^4.1.0 + "@smithy/util-buffer-from": ^4.1.0 + "@smithy/util-hex-encoding": ^4.1.0 + "@smithy/util-utf8": ^4.1.0 + tslib: ^2.6.2 + checksum: a1b73d9f39811065729bd7304a6deaceea99ddb2f736fb5b95c20d3db53f84e4e53f956c358d95fa747967488b2193b581e96ed75d841164cdb5176fef928eb8 languageName: node linkType: hard -"@slack/types@npm:^2.11.0": - version: 2.11.0 - resolution: "@slack/types@npm:2.11.0" - checksum: b5b7e4be242c9409b247c5be9df480b91a5ad21f367ae96945a7752bd720c65b13623c4a9b37b812107b3a5aa5e5013d7962807230913781ff5f0ad427a79ec2 +"@smithy/util-uri-escape@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-uri-escape@npm:4.1.0" + dependencies: + tslib: ^2.6.2 + checksum: 0c55f4981af8be1a67fdd154497d41b3ea130da2a409b06a5e899d5f86b498fe4e5b9c065ee018379b976d74ae9aaf45180548e0d96bf7e474fb039da667aac6 languageName: node linkType: hard -"@slack/web-api@npm:^6.7.2": - version: 6.12.0 - resolution: "@slack/web-api@npm:6.12.0" +"@smithy/util-utf8@npm:^2.0.0": + version: 2.3.0 + resolution: "@smithy/util-utf8@npm:2.3.0" dependencies: - "@slack/logger": ^3.0.0 - "@slack/types": ^2.11.0 - "@types/is-stream": ^1.1.0 - "@types/node": ">=12.0.0" - axios: ^1.6.5 - eventemitter3: ^3.1.0 - form-data: ^2.5.0 - is-electron: 2.2.2 - is-stream: ^1.1.0 - p-queue: ^6.6.1 - p-retry: ^4.0.0 - checksum: d0cc16a2981167f3780a07542b4c88d31fc836a743de04e52e9f8fe8a82281781103f8821b3db5aa9de55471b6e550f044e767dbf482045865bd713b90fddd65 + "@smithy/util-buffer-from": ^2.2.0 + tslib: ^2.6.2 + checksum: 00e55d4b4e37d48be0eef3599082402b933c52a1407fed7e8e8ad76d94d81a0b30b8bfaf2047c59d9c3af31e5f20e7a8c959cb7ae270f894255e05a2229964f0 languageName: node linkType: hard -"@surma/rollup-plugin-off-main-thread@npm:^1.1.1": - version: 1.4.2 - resolution: "@surma/rollup-plugin-off-main-thread@npm:1.4.2" +"@smithy/util-utf8@npm:^4.1.0": + version: 4.1.0 + resolution: "@smithy/util-utf8@npm:4.1.0" + dependencies: + "@smithy/util-buffer-from": ^4.1.0 + tslib: ^2.6.2 + checksum: 3a5a1420a5f06bfcc1c15935344f245ea5d297c0d021c52589cb7125fe5a3546e69cedf37940fd84962405116d59c81f56d1adb463105715f4b534f0fe3bf9db + languageName: node + linkType: hard + +"@smithy/util-waiter@npm:^4.1.1": + version: 4.1.1 + resolution: "@smithy/util-waiter@npm:4.1.1" + dependencies: + "@smithy/abort-controller": ^4.1.1 + "@smithy/types": ^4.5.0 + tslib: ^2.6.2 + checksum: f4d16ee1cbcc34a2519e835f70b4e3430fe1bbff611e30951ea83ed997ee6a6c01a3189e4e8c8c2bae441520622f03c6324bd4decac77b02f7001637f26cf83a + languageName: node + linkType: hard + +"@surma/rollup-plugin-off-main-thread@npm:^2.2.3": + version: 2.2.3 + resolution: "@surma/rollup-plugin-off-main-thread@npm:2.2.3" dependencies: - ejs: ^2.6.1 + ejs: ^3.1.6 + json5: ^2.2.0 magic-string: ^0.25.0 - checksum: da721792036a0e1253911f9b5280e6cb236024d7d2255bde3b6e87587c0ea8f46404224c8c032a27ee11ab3244eda752587fb37ec78c2e64eb53e10557373102 + string.prototype.matchall: ^4.0.6 + checksum: 2c021349442e2e2cec96bb50fd82ec8bf8514d909bc73594f6cfc89b3b68f2feed909a8161d7d307d9455585c97e6b66853ce334db432626c7596836d4549c0c languageName: node linkType: hard @@ -3252,7 +5485,7 @@ __metadata: languageName: node linkType: hard -"@svgr/webpack@npm:5.5.0": +"@svgr/webpack@npm:^5.5.0": version: 5.5.0 resolution: "@svgr/webpack@npm:5.5.0" dependencies: @@ -3268,52 +5501,33 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^7.28.1": - version: 7.31.2 - resolution: "@testing-library/dom@npm:7.31.2" - dependencies: - "@babel/code-frame": ^7.10.4 - "@babel/runtime": ^7.12.5 - "@types/aria-query": ^4.2.0 - aria-query: ^4.2.2 - chalk: ^4.1.0 - dom-accessibility-api: ^0.5.6 - lz-string: ^1.4.4 - pretty-format: ^26.6.2 - checksum: 54fbedd1ecdfe1d47be2e592b98d18b2ab9d7e731f57231caf9b152593fe7329fe5ebe219e0e5d1e0df5b1ab803121cb8acd8b73bd1fb292bfdc2c55663eb01d - languageName: node - linkType: hard - -"@testing-library/dom@npm:^8.19.0": - version: 8.20.1 - resolution: "@testing-library/dom@npm:8.20.1" +"@testing-library/dom@npm:^10.4.0": + version: 10.4.1 + resolution: "@testing-library/dom@npm:10.4.1" dependencies: "@babel/code-frame": ^7.10.4 "@babel/runtime": ^7.12.5 "@types/aria-query": ^5.0.1 - aria-query: 5.1.3 - chalk: ^4.1.0 + aria-query: 5.3.0 dom-accessibility-api: ^0.5.9 lz-string: ^1.5.0 + picocolors: 1.1.1 pretty-format: ^27.0.2 - checksum: 06fc8dc67849aadb726cbbad0e7546afdf8923bd39acb64c576d706249bd7d0d05f08e08a31913fb621162e3b9c2bd0dce15964437f030f9fa4476326fdd3007 + checksum: 3887fe95594b6d9467a804e2cc82e719c57f4d55d7d9459b72a949b3a8189db40375b89034637326d4be559f115abc6b6bcfcc6fec0591c4a4d4cdde96751a6c languageName: node linkType: hard -"@testing-library/jest-dom@npm:^5.11.9, @testing-library/jest-dom@npm:^5.16.4": - version: 5.17.0 - resolution: "@testing-library/jest-dom@npm:5.17.0" +"@testing-library/jest-dom@npm:^6.6.3": + version: 6.8.0 + resolution: "@testing-library/jest-dom@npm:6.8.0" dependencies: - "@adobe/css-tools": ^4.0.1 - "@babel/runtime": ^7.9.2 - "@types/testing-library__jest-dom": ^5.9.1 + "@adobe/css-tools": ^4.4.0 aria-query: ^5.0.0 - chalk: ^3.0.0 css.escape: ^1.5.1 - dom-accessibility-api: ^0.5.6 - lodash: ^4.17.15 + dom-accessibility-api: ^0.6.3 + picocolors: ^1.1.1 redent: ^3.0.0 - checksum: 9f28dbca8b50d7c306aae40c3aa8e06f0e115f740360004bd87d57f95acf7ab4b4f4122a7399a76dbf2bdaaafb15c99cc137fdcb0ae457a92e2de0f3fbf9b03b + checksum: a3cfb162b6ec6e98277187d9488234ba3e3ee25f24a86facdae092dbe54a015c845bcb81daa6de7afadcac5a5fe25becd7c7e9b67bb01ee4ccf7d67ee907adc9 languageName: node linkType: hard @@ -3339,27 +5553,32 @@ __metadata: languageName: node linkType: hard -"@testing-library/react@npm:^11.2.5": - version: 11.2.7 - resolution: "@testing-library/react@npm:11.2.7" +"@testing-library/react@npm:^16.2.0": + version: 16.3.0 + resolution: "@testing-library/react@npm:16.3.0" dependencies: "@babel/runtime": ^7.12.5 - "@testing-library/dom": ^7.28.1 peerDependencies: - react: "*" - react-dom: "*" - checksum: 64e07cb96e40dbdbd3c46a09c47bed14446b30efafaa65a5d4fed5a7553878990cda108578f2b114422a775f31c635d51fd50b752f6163ddd6b8474e0e5fc2ce + "@testing-library/dom": ^10.0.0 + "@types/react": ^18.0.0 || ^19.0.0 + "@types/react-dom": ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 85728ea8a1bcc9d865782a3d3bcc1db6632cb77907b47fb99c7f338e3ebdfc74dc6d21dfc5526a215a4f4f7b7d8a6392de87f48da3848866ab088f327ebb3e92 languageName: node linkType: hard -"@testing-library/user-event@npm:^12.6.3": - version: 12.8.3 - resolution: "@testing-library/user-event@npm:12.8.3" - dependencies: - "@babel/runtime": ^7.12.5 +"@testing-library/user-event@npm:^14.6.0": + version: 14.6.1 + resolution: "@testing-library/user-event@npm:14.6.1" peerDependencies: "@testing-library/dom": ">=7.21.4" - checksum: c9fb5ee07cbe79ddf32d81e1a353e556d02a1f1619456ccfad6abcdf1b7db400fdc9d7a8e0be3994f456e7135a0dfb7fa10b29fb98a0f5fc417b99fce0ce8166 + checksum: 4cb8a81fea1fea83a42619e9545137b51636bb7a3182c596bb468e5664f1e4699a275c2d0fb8b6dcc3fe2684f9d87b0637ab7cb4f566051539146872c9141fcb languageName: node linkType: hard @@ -3370,6 +5589,13 @@ __metadata: languageName: node linkType: hard +"@trysound/sax@npm:0.2.0": + version: 0.2.0 + resolution: "@trysound/sax@npm:0.2.0" + checksum: 11226c39b52b391719a2a92e10183e4260d9651f86edced166da1d95f39a0a1eaa470e44d14ac685ccd6d3df7e2002433782872c0feeb260d61e80f21250e65c + languageName: node + linkType: hard + "@tsconfig/node10@npm:^1.0.7": version: 1.0.11 resolution: "@tsconfig/node10@npm:1.0.11" @@ -3398,13 +5624,6 @@ __metadata: languageName: node linkType: hard -"@types/aria-query@npm:^4.2.0": - version: 4.2.2 - resolution: "@types/aria-query@npm:4.2.2" - checksum: 6f2ce11d91e2d665f3873258db19da752d91d85d3679eb5efcdf9c711d14492287e1e4eb52613b28e60375841a9e428594e745b68436c963d8bad4bf72188df3 - languageName: node - linkType: hard - "@types/aria-query@npm:^5.0.1": version: 5.0.4 resolution: "@types/aria-query@npm:5.0.4" @@ -3412,7 +5631,7 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.7, @types/babel__core@npm:^7.20.5": +"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.14, @types/babel__core@npm:^7.20.5": version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" dependencies: @@ -3426,11 +5645,11 @@ __metadata: linkType: hard "@types/babel__generator@npm:*": - version: 7.6.8 - resolution: "@types/babel__generator@npm:7.6.8" + version: 7.27.0 + resolution: "@types/babel__generator@npm:7.27.0" dependencies: "@babel/types": ^7.0.0 - checksum: 5b332ea336a2efffbdeedb92b6781949b73498606ddd4205462f7d96dafd45ff3618770b41de04c4881e333dd84388bfb8afbdf6f2764cbd98be550d85c6bb48 + checksum: e6739cacfa276c1ad38e1d8a6b4b1f816c2c11564e27f558b68151728489aaf0f4366992107ee4ed7615dfa303f6976dedcdce93df2b247116d1bcd1607ee260 languageName: node linkType: hard @@ -3445,37 +5664,39 @@ __metadata: linkType: hard "@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.4, @types/babel__traverse@npm:^7.0.6": - version: 7.20.5 - resolution: "@types/babel__traverse@npm:7.20.5" + version: 7.28.0 + resolution: "@types/babel__traverse@npm:7.28.0" dependencies: - "@babel/types": ^7.20.7 - checksum: 608e0ab4fc31cd47011d98942e6241b34d461608c0c0e153377c5fd822c436c475f1ded76a56bfa76a1adf8d9266b727bbf9bfac90c4cb152c97f30dadc5b7e8 + "@babel/types": ^7.28.2 + checksum: e3124e6575b2f70de338eab8a9c704d315a86c46a8e395b6ec78a0157ab7b5fd877289556a57dcf28e4ff3543714e359cc1182d4afc4bcb4f3575a0bbafa0dad languageName: node linkType: hard "@types/body-parser@npm:*": - version: 1.19.5 - resolution: "@types/body-parser@npm:1.19.5" + version: 1.19.6 + resolution: "@types/body-parser@npm:1.19.6" dependencies: "@types/connect": "*" "@types/node": "*" - checksum: 1e251118c4b2f61029cc43b0dc028495f2d1957fe8ee49a707fb940f86a9bd2f9754230805598278fe99958b49e9b7e66eec8ef6a50ab5c1f6b93e1ba2aaba82 + checksum: 33041e88eae00af2cfa0827e951e5f1751eafab2a8b6fce06cd89ef368a988907996436b1325180edaeddd1c0c7d0d0d4c20a6c9ff294a91e0039a9db9e9b658 languageName: node linkType: hard -"@types/chai-subset@npm:^1.3.3": - version: 1.3.5 - resolution: "@types/chai-subset@npm:1.3.5" +"@types/bonjour@npm:^3.5.9": + version: 3.5.13 + resolution: "@types/bonjour@npm:3.5.13" dependencies: - "@types/chai": "*" - checksum: 715c46d3e90f87482c2769389d560456bb257b225716ff44c275c231bdb62c8a30629f355f412bac0ecab07ebc036c1806d9ed9dde9792254f8ef4f07f76033b + "@types/node": "*" + checksum: e827570e097bd7d625a673c9c208af2d1a22fa3885c0a1646533cf24394c839c3e5f60ac1bc60c0ddcc69c0615078c9fb2c01b42596c7c582d895d974f2409ee languageName: node linkType: hard -"@types/chai@npm:*, @types/chai@npm:^4.3.5": - version: 4.3.14 - resolution: "@types/chai@npm:4.3.14" - checksum: 962c67d1295005886ced8f87c73614616f6d65ed1ec71818021c9206decbaab1234da878295ba52450883c78a8ee5e1359e5deeadee3b7d058538b0ae8c67b08 +"@types/chai@npm:^5.2.2": + version: 5.2.2 + resolution: "@types/chai@npm:5.2.2" + dependencies: + "@types/deep-eql": "*" + checksum: 386887bd55ba684572cececd833ed91aba6cce2edd8cc1d8cefa78800b3a74db6dbf5c5c41af041d1d1f3ce672ea30b45c9520f948cdc75431eb7df3fbba8405 languageName: node linkType: hard @@ -3488,6 +5709,16 @@ __metadata: languageName: node linkType: hard +"@types/connect-history-api-fallback@npm:^1.3.5": + version: 1.5.4 + resolution: "@types/connect-history-api-fallback@npm:1.5.4" + dependencies: + "@types/express-serve-static-core": "*" + "@types/node": "*" + checksum: e1dee43b8570ffac02d2d47a2b4ba80d3ca0dd1840632dafb221da199e59dbe3778d3d7303c9e23c6b401f37c076935a5bc2aeae1c4e5feaefe1c371fe2073fd + languageName: node + linkType: hard + "@types/connect@npm:*": version: 3.4.38 resolution: "@types/connect@npm:3.4.38" @@ -3498,18 +5729,18 @@ __metadata: linkType: hard "@types/cookie-parser@npm:^1.4.3": - version: 1.4.7 - resolution: "@types/cookie-parser@npm:1.4.7" - dependencies: + version: 1.4.9 + resolution: "@types/cookie-parser@npm:1.4.9" + peerDependencies: "@types/express": "*" - checksum: 7b87c59420598e686a57e240be6e0db53967c3c8814be9326bf86609ee2fc39c4b3b9f2263e1deba43526090121d1df88684b64c19f7b494a80a4437caf3d40b + checksum: 6192a4899b5412a4c3be0f47158321aef73a4cd7e7a4f7b2a37e2e1045f11a21209681cb1bc5335f250ee2a6ce64d8a3fefb851181a98e6415d3716ef9ed1f62 languageName: node linkType: hard -"@types/cookie@npm:^0.4.1": - version: 0.4.1 - resolution: "@types/cookie@npm:0.4.1" - checksum: 3275534ed69a76c68eb1a77d547d75f99fedc80befb75a3d1d03662fb08d697e6f8b1274e12af1a74c6896071b11510631ba891f64d30c78528d0ec45a9c1a18 +"@types/cookie@npm:^0.6.0": + version: 0.6.0 + resolution: "@types/cookie@npm:0.6.0" + checksum: 5edce7995775b0b196b142883e4d4f71fd93c294eaec973670f1fa2540b70ea7390408ed513ddefef5fcb12a578100c76596e8f2a714b0c2ae9f70ee773f4510 languageName: node linkType: hard @@ -3521,15 +5752,84 @@ __metadata: linkType: hard "@types/cors@npm:^2.8.12": - version: 2.8.17 - resolution: "@types/cors@npm:2.8.17" + version: 2.8.19 + resolution: "@types/cors@npm:2.8.19" dependencies: "@types/node": "*" - checksum: 469bd85e29a35977099a3745c78e489916011169a664e97c4c3d6538143b0a16e4cc72b05b407dc008df3892ed7bf595f9b7c0f1f4680e169565ee9d64966bde + checksum: 9545cc532c9218754443f48a0c98c1a9ba4af1fe54a3425c95de75ff3158147bb39e666cb7c6bf98cc56a9c6dc7b4ce5b2cbdae6b55d5942e50c81b76ed6b825 + languageName: node + linkType: hard + +"@types/d3-array@npm:^3.0.3": + version: 3.2.2 + resolution: "@types/d3-array@npm:3.2.2" + checksum: 72e8e2abe0911cb431d6f3fe0a1f71b915356b679d4d9c826f52941bb30210c0fe8299dde066b08d9986754c620f031b13b13ab6dfc60d404eceab66a075dd5d + languageName: node + linkType: hard + +"@types/d3-color@npm:*": + version: 3.1.3 + resolution: "@types/d3-color@npm:3.1.3" + checksum: 8a0e79a709929502ec4effcee2c786465b9aec51b653ba0b5d05dbfec3e84f418270dd603002d94021885061ff592f614979193bd7a02ad76317f5608560e357 languageName: node linkType: hard -"@types/debug@npm:^4.1.7": +"@types/d3-ease@npm:^3.0.0": + version: 3.0.2 + resolution: "@types/d3-ease@npm:3.0.2" + checksum: 0885219966294bfc99548f37297e1c75e75da812a5f3ec941977ebb57dcab0a25acec5b2bbd82d09a49d387daafca08521ca269b7e4c27ddca7768189e987b54 + languageName: node + linkType: hard + +"@types/d3-interpolate@npm:^3.0.1": + version: 3.0.4 + resolution: "@types/d3-interpolate@npm:3.0.4" + dependencies: + "@types/d3-color": "*" + checksum: efd2770e174e84fc7316fdafe03cf3688451f767dde1fa6211610137f495be7f3923db7e1723a6961a0e0e9ae0ed969f4f47c038189fa0beb1d556b447922622 + languageName: node + linkType: hard + +"@types/d3-path@npm:*": + version: 3.1.1 + resolution: "@types/d3-path@npm:3.1.1" + checksum: fee8f6b0d3b28a3611c7d7fda3bf2f79392ded266f54b03a220f205c42117644bdcd33dcbf4853da3cca02229f1c669d2a60d5d297a24ce459ba8271ccb26c03 + languageName: node + linkType: hard + +"@types/d3-scale@npm:^4.0.2": + version: 4.0.9 + resolution: "@types/d3-scale@npm:4.0.9" + dependencies: + "@types/d3-time": "*" + checksum: c44265a38e538983686b1b8d159abfb4e81c09b33316f3a68f0f372d38400fa950ad531644d25230cc7b48ea5adb50270fc54823f088979ade62dcd0225f7aa3 + languageName: node + linkType: hard + +"@types/d3-shape@npm:^3.1.0": + version: 3.1.7 + resolution: "@types/d3-shape@npm:3.1.7" + dependencies: + "@types/d3-path": "*" + checksum: 776b982e2c4fc04763782af5100993c02bca338632ff2c76d2423ace398300ba7c48cd745f95b5f51edefabbfd026c45829a146c411f8facde09ef92580b20ce + languageName: node + linkType: hard + +"@types/d3-time@npm:*, @types/d3-time@npm:^3.0.0": + version: 3.0.4 + resolution: "@types/d3-time@npm:3.0.4" + checksum: 0c296884571ce70c4bbd4ea9cd1c93c0c8aee602c6c806b056187dd4ee49daf70c2f41da94b25ba0d796edf8ca83cbb87fe6d1cdda7ca669ab800170ece1c12b + languageName: node + linkType: hard + +"@types/d3-timer@npm:^3.0.0": + version: 3.0.2 + resolution: "@types/d3-timer@npm:3.0.2" + checksum: 1643eebfa5f4ae3eb00b556bbc509444d88078208ec2589ddd8e4a24f230dd4cf2301e9365947e70b1bee33f63aaefab84cd907822aae812b9bc4871b98ab0e1 + languageName: node + linkType: hard + +"@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.4": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" dependencies: @@ -3538,20 +5838,56 @@ __metadata: languageName: node linkType: hard -"@types/eslint@npm:^7.29.0": - version: 7.29.0 - resolution: "@types/eslint@npm:7.29.0" +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 249a27b0bb22f6aa28461db56afa21ec044fa0e303221a62dff81831b20c8530502175f1a49060f7099e7be06181078548ac47c668de79ff9880241968d43d0c + languageName: node + linkType: hard + +"@types/eslint-scope@npm:^3.7.7": + version: 3.7.7 + resolution: "@types/eslint-scope@npm:3.7.7" + dependencies: + "@types/eslint": "*" + "@types/estree": "*" + checksum: e2889a124aaab0b89af1bab5959847c5bec09809209255de0e63b9f54c629a94781daa04adb66bffcdd742f5e25a17614fb933965093c0eea64aacda4309380e + languageName: node + linkType: hard + +"@types/eslint@npm:*": + version: 9.6.1 + resolution: "@types/eslint@npm:9.6.1" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: df13991c554954353ce8f3bb03e19da6cc71916889443d68d178d4f858b561ba4cc4a4f291c6eb9eebb7f864b12b9b9313051b3a8dfea3e513dadf3188a77bdf + checksum: c286e79707ab604b577cf8ce51d9bbb9780e3d6a68b38a83febe13fa05b8012c92de17c28532fac2b03d3c460123f5055d603a579685325246ca1c86828223e0 languageName: node linkType: hard -"@types/estree@npm:*": +"@types/eslint@npm:^7.29.0 || ^8.4.1": + version: 8.56.12 + resolution: "@types/eslint@npm:8.56.12" + dependencies: + "@types/estree": "*" + "@types/json-schema": "*" + checksum: 0f7710ee02a256c499514251f527f84de964bb29487db840408e4cde79283124a38935597636d2265756c34dd1d902e1b00ae78930d4a0b55111909cb7b80d84 + languageName: node + linkType: hard + +"@types/estree-jsx@npm:^1.0.0": version: 1.0.5 - resolution: "@types/estree@npm:1.0.5" - checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a + resolution: "@types/estree-jsx@npm:1.0.5" + dependencies: + "@types/estree": "*" + checksum: a028ab0cd7b2950168a05c6a86026eb3a36a54a4adfae57f13911d7b49dffe573d9c2b28421b2d029b49b3d02fcd686611be2622dc3dad6d9791166c083f6008 + languageName: node + linkType: hard + +"@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.8": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: bd93e2e415b6f182ec4da1074e1f36c480f1d26add3e696d54fb30c09bc470897e41361c8fd957bf0985024f8fbf1e6e2aff977d79352ef7eb93a5c6dcff6c11 languageName: node linkType: hard @@ -3572,15 +5908,27 @@ __metadata: languageName: node linkType: hard +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^5.0.0": + version: 5.0.7 + resolution: "@types/express-serve-static-core@npm:5.0.7" + dependencies: + "@types/node": "*" + "@types/qs": "*" + "@types/range-parser": "*" + "@types/send": "*" + checksum: 3539f5866720c081053daeb97d6786614791b382ec2f30b46f05c09076c99ae14c87755b00d8367f7d456535191594d67336dbaa764e8fbbba9ca3dfb15dae00 + languageName: node + linkType: hard + "@types/express-serve-static-core@npm:^4.17.33": - version: 4.19.0 - resolution: "@types/express-serve-static-core@npm:4.19.0" + version: 4.19.6 + resolution: "@types/express-serve-static-core@npm:4.19.6" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: 39c09fcb3f61de96ed56d97273874cafe50e6675ac254af4d77014e569e4fdc29d1d0d1dd12e11f008cb9a52785b07c2801c6ba91397965392b20c75ee01fb4e + checksum: b0576eddc2d25ccdf10e68ba09598b87a4d7b2ad04a81dc847cb39fe56beb0b6a5cc017b1e00aa0060cb3b38e700384ce96d291a116a0f1e54895564a104aae9 languageName: node linkType: hard @@ -3593,15 +5941,26 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.6": - version: 4.17.21 - resolution: "@types/express@npm:4.17.21" +"@types/express@npm:*, @types/express@npm:^5.0.0": + version: 5.0.3 + resolution: "@types/express@npm:5.0.3" + dependencies: + "@types/body-parser": "*" + "@types/express-serve-static-core": ^5.0.0 + "@types/serve-static": "*" + checksum: bb6f10c14c8e3cce07f79ee172688aa9592852abd7577b663cd0c2054307f172c2b2b36468c918fed0d4ac359b99695807b384b3da6157dfa79acbac2226b59b + languageName: node + linkType: hard + +"@types/express@npm:^4.17.0, @types/express@npm:^4.17.13": + version: 4.17.23 + resolution: "@types/express@npm:4.17.23" dependencies: "@types/body-parser": "*" "@types/express-serve-static-core": ^4.17.33 "@types/qs": "*" "@types/serve-static": "*" - checksum: fb238298630370a7392c7abdc80f495ae6c716723e114705d7e3fb67e3850b3859bbfd29391463a3fb8c0b32051847935933d99e719c0478710f8098ee7091c5 + checksum: f1a020c6ad6dc0169a3277199605d60649d463a72c920673e0f230ab1e76f2d3aa23daabd25ef8e62eda314e26b879306c58ec806e669e1e40ca37a4b73a44b0 languageName: node linkType: hard @@ -3612,16 +5971,6 @@ __metadata: languageName: node linkType: hard -"@types/glob@npm:^7.1.1": - version: 7.2.0 - resolution: "@types/glob@npm:7.2.0" - dependencies: - "@types/minimatch": "*" - "@types/node": "*" - checksum: 6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19 - languageName: node - linkType: hard - "@types/graceful-fs@npm:^4.1.2": version: 4.1.9 resolution: "@types/graceful-fs@npm:4.1.9" @@ -3631,12 +5980,12 @@ __metadata: languageName: node linkType: hard -"@types/hast@npm:^2.0.0": - version: 2.3.10 - resolution: "@types/hast@npm:2.3.10" +"@types/hast@npm:^3.0.0": + version: 3.0.4 + resolution: "@types/hast@npm:3.0.4" dependencies: - "@types/unist": ^2 - checksum: 41531b7fbf590b02452996fc63272479c20a07269e370bd6514982cbcd1819b4b84d3ea620f2410d1b9541a23d08ce2eeb0a592145d05e00e249c3d56700d460 + "@types/unist": "*" + checksum: 7a973e8d16fcdf3936090fa2280f408fb2b6a4f13b42edeb5fbd614efe042b82eac68e298e556d50f6b4ad585a3a93c353e9c826feccdc77af59de8dd400d044 languageName: node linkType: hard @@ -3647,26 +5996,26 @@ __metadata: languageName: node linkType: hard -"@types/html-minifier-terser@npm:^5.0.0": - version: 5.1.2 - resolution: "@types/html-minifier-terser@npm:5.1.2" - checksum: 4bca779c44d2aebe4cc4036c5db370abe7466249038e9c5996cb3c192debeff1c75b7a2ab78e5fd2a014ad24ebf0f357f9a174a4298540dc1e1317d43aa69cfa +"@types/html-minifier-terser@npm:^6.0.0": + version: 6.1.0 + resolution: "@types/html-minifier-terser@npm:6.1.0" + checksum: eb843f6a8d662d44fb18ec61041117734c6aae77aa38df1be3b4712e8e50ffaa35f1e1c92fdd0fde14a5675fecf457abcd0d15a01fae7506c91926176967f452 languageName: node linkType: hard "@types/http-errors@npm:*": - version: 2.0.4 - resolution: "@types/http-errors@npm:2.0.4" - checksum: 1f3d7c3b32c7524811a45690881736b3ef741bf9849ae03d32ad1ab7062608454b150a4e7f1351f83d26a418b2d65af9bdc06198f1c079d75578282884c4e8e3 + version: 2.0.5 + resolution: "@types/http-errors@npm:2.0.5" + checksum: a88da669366bc483e8f3b3eb3d34ada5f8d13eeeef851b1204d77e2ba6fc42aba4566d877cca5c095204a3f4349b87fe397e3e21288837bdd945dd514120755b languageName: node linkType: hard -"@types/is-stream@npm:^1.1.0": - version: 1.1.0 - resolution: "@types/is-stream@npm:1.1.0" +"@types/http-proxy@npm:^1.17.8": + version: 1.17.16 + resolution: "@types/http-proxy@npm:1.17.16" dependencies: "@types/node": "*" - checksum: 23fcb06cd8adc0124d4c44071bd4b447c41f5e4c2eccb6166789c7fc0992b566e2e8b628a3800ff4472b686d9085adbec203925068bf72e350e085650e83adec + checksum: f5ab4afe7e3feba9d87bdddbf44e03d9a836bd2cdab679a794badbff7c4bfb6bebf46bfe22d9964eb1820e1349f2ff7807cccb20fd27cb17f03db849289e5892 languageName: node linkType: hard @@ -3695,34 +6044,17 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:*": - version: 29.5.12 - resolution: "@types/jest@npm:29.5.12" +"@types/jest@npm:^29.5.14": + version: 29.5.14 + resolution: "@types/jest@npm:29.5.14" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: 19b1efdeed9d9a60a81edc8226cdeae5af7479e493eaed273e01243891c9651f7b8b4c08fc633a7d0d1d379b091c4179bbaa0807af62542325fd72f2dd17ce1c + checksum: 18dba4623f26661641d757c63da2db45e9524c9be96a29ef713c703a9a53792df9ecee9f7365a0858ddbd6440d98fe6b65ca67895ca5884b73cbc7ffc11f3838 languageName: node linkType: hard -"@types/jest@npm:^28.1.6": - version: 28.1.8 - resolution: "@types/jest@npm:28.1.8" - dependencies: - expect: ^28.0.0 - pretty-format: ^28.0.0 - checksum: d4cd36158a3ae1d4b42cc48a77c95de74bc56b84cf81e09af3ee0399c34f4a7da8ab9e787570f10004bd642f9e781b0033c37327fbbf4a8e4b6e37e8ee3693a7 - languageName: node - linkType: hard - -"@types/js-levenshtein@npm:^1.1.1": - version: 1.1.3 - resolution: "@types/js-levenshtein@npm:1.1.3" - checksum: eb338696da976925ea8448a42d775d7615a14323dceeb08909f187d0b3d3b4c1f67a1c36ef586b1c2318b70ab141bba8fc58311ba1c816711704605aec09db8b - languageName: node - linkType: hard - -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.3, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 @@ -3745,19 +6077,28 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:^4.14.175": - version: 4.17.0 - resolution: "@types/lodash@npm:4.17.0" - checksum: 3f98c0b67a93994cbc3403d4fa9dbaf52b0b6bb7f07a764d73875c2dcd5ef91222621bd5bcf8eee7b417a74d175c2f7191b9f595f8603956fd06f0674c0cba93 +"@types/lodash.isstring@npm:^4.0.6": + version: 4.0.9 + resolution: "@types/lodash.isstring@npm:4.0.9" + dependencies: + "@types/lodash": "*" + checksum: ef381be69b459caa42d7c5dc4ff5b3653e6b3c9b2393f6e92848efeafe7690438e058b26f036b11b4e535fc7645ff12d1203847b9a82e9ae0593bdd3b25a971b + languageName: node + linkType: hard + +"@types/lodash@npm:*": + version: 4.17.20 + resolution: "@types/lodash@npm:4.17.20" + checksum: dc7bb4653514dd91117a4c4cec2c37e2b5a163d7643445e4757d76a360fabe064422ec7a42dde7450c5e7e0e7e678d5e6eae6d2a919abcddf581d81e63e63839 languageName: node linkType: hard -"@types/mdast@npm:^3.0.0": - version: 3.0.15 - resolution: "@types/mdast@npm:3.0.15" +"@types/mdast@npm:^4.0.0": + version: 4.0.4 + resolution: "@types/mdast@npm:4.0.4" dependencies: - "@types/unist": ^2 - checksum: af85042a4e3af3f879bde4059fa9e76c71cb552dffc896cdcc6cf9dc1fd38e37035c2dbd6245cfa6535b433f1f0478f5549696234ccace47a64055a10c656530 + "@types/unist": "*" + checksum: 20c4e9574cc409db662a35cba52b068b91eb696b3049e94321219d47d34c8ccc99a142be5c76c80a538b612457b03586bc2f6b727a3e9e7530f4c8568f6282ee languageName: node linkType: hard @@ -3775,35 +6116,37 @@ __metadata: languageName: node linkType: hard -"@types/minimatch@npm:*": - version: 5.1.2 - resolution: "@types/minimatch@npm:5.1.2" - checksum: 0391a282860c7cb6fe262c12b99564732401bdaa5e395bee9ca323c312c1a0f45efbf34dce974682036e857db59a5c9b1da522f3d6055aeead7097264c8705a8 +"@types/ms@npm:*": + version: 2.1.0 + resolution: "@types/ms@npm:2.1.0" + checksum: 532d2ebb91937ccc4a89389715e5b47d4c66e708d15942fe6cc25add6dc37b2be058230a327dd50f43f89b8b6d5d52b74685a9e8f70516edfc9bdd6be910eff4 languageName: node linkType: hard -"@types/ms@npm:*": - version: 0.7.34 - resolution: "@types/ms@npm:0.7.34" - checksum: f38d36e7b6edecd9badc9cf50474159e9da5fa6965a75186cceaf883278611b9df6669dc3a3cc122b7938d317b68a9e3d573d316fcb35d1be47ec9e468c6bd8a +"@types/multer@npm:^1.4.12, @types/multer@npm:^1.4.7": + version: 1.4.13 + resolution: "@types/multer@npm:1.4.13" + dependencies: + "@types/express": "*" + checksum: 9692a1ad5b185c86b15e852be8d6c2ba8fd85c22beffdb52cc5770bd6c0710bc904c134011949547dbd3e113899d0136a3c63fa5fc8c300be182cfdb8670de42 languageName: node linkType: hard -"@types/multer@npm:^1.4.7": - version: 1.4.11 - resolution: "@types/multer@npm:1.4.11" +"@types/node-forge@npm:^1.3.0": + version: 1.3.14 + resolution: "@types/node-forge@npm:1.3.14" dependencies: - "@types/express": "*" - checksum: 3d80b2acdfbc9f3e9027d4467e948925810b67e5622a3017f42f58a3598d34b25376890801e55d0c03973ccc34573abf5218af334e8292ec455832f4ade3e5f5 + "@types/node": "*" + checksum: ff621803390e723e56b289a89fca3a06f9f8b438add1b843203a0f64bcbc7ac03d457136b3c15010b5bc89d81f57b35f62964e6e980f6290597bb21b4463c009 languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=12.0.0": - version: 20.12.7 - resolution: "@types/node@npm:20.12.7" +"@types/node@npm:*, @types/node@npm:>=18.0.0": + version: 24.5.0 + resolution: "@types/node@npm:24.5.0" dependencies: - undici-types: ~5.26.4 - checksum: 7cc979f7e2ca9a339ec71318c3901b9978555257929ef3666987f3e447123bc6dc92afcc89f6347e09e07d602fde7d51bcddea626c23aa2bb74aeaacfd1e1686 + undici-types: ~7.12.0 + checksum: ae97c80b1edce278b3e0b5d8ad432b545b850b4b21a43b1202fae66b5d35f0a38c5e1b8eb2006225929c600f458daec6c1654f72a02bab6fe6414e3b35140d99 languageName: node linkType: hard @@ -3814,19 +6157,36 @@ __metadata: languageName: node linkType: hard -"@types/nodemailer@npm:^6.4.7": - version: 6.4.14 - resolution: "@types/nodemailer@npm:6.4.14" +"@types/node@npm:20.0.0": + version: 20.0.0 + resolution: "@types/node@npm:20.0.0" + checksum: 7dadc41081eee634fd0b19e46dfb0a74f8296ee562533118f7c2f2b54dcaba7124961d506db425fff74d8e8288610b93939cd06fa723f053c72b1a7e87aa4ddc + languageName: node + linkType: hard + +"@types/node@npm:>=12.13.0 < 13": + version: 12.20.55 + resolution: "@types/node@npm:12.20.55" + checksum: e4f86785f4092706e0d3b0edff8dca5a13b45627e4b36700acd8dfe6ad53db71928c8dee914d4276c7fd3b6ccd829aa919811c9eb708a2c8e4c6eb3701178c37 + languageName: node + linkType: hard + +"@types/node@npm:^20.0.0": + version: 20.19.15 + resolution: "@types/node@npm:20.19.15" dependencies: - "@types/node": "*" - checksum: 5f61f01dd736b17f431d1e8b320322f86460604b45df947fc4bc8999d7c7719405e349f7abba86e4fb100a464a30b52615d00dac03d9cb37562ff04487ebd310 + undici-types: ~6.21.0 + checksum: 02d7327b6bd3778247e5882c4a236364103b30f883b7f03243e83c882ff257e14d15c2b4dab8b4862548d45541b4f708e3aa565520a042dd242ab7d0d2b63968 languageName: node linkType: hard -"@types/normalize-package-data@npm:^2.4.0": - version: 2.4.4 - resolution: "@types/normalize-package-data@npm:2.4.4" - checksum: 65dff72b543997b7be8b0265eca7ace0e34b75c3e5fee31de11179d08fa7124a7a5587265d53d0409532ecb7f7fba662c2012807963e1f9b059653ec2c83ee05 +"@types/nodemailer@npm:^6.4.0": + version: 6.4.19 + resolution: "@types/nodemailer@npm:6.4.19" + dependencies: + "@aws-sdk/client-ses": ^3.731.1 + "@types/node": "*" + checksum: 7f449db31d8c0b150da554158e04d9fd631832ff2c01cc7c906ec9619a5295d7f525db959bfd3fc0eb451f386dd052ddbcbe1a337e3f776a3d9d554701a9df53 languageName: node linkType: hard @@ -3837,17 +6197,17 @@ __metadata: languageName: node linkType: hard -"@types/prettier@npm:^2.0.0": +"@types/prettier@npm:^2.1.5": version: 2.7.3 resolution: "@types/prettier@npm:2.7.3" checksum: 705384209cea6d1433ff6c187c80dcc0b95d99d5c5ce21a46a9a58060c527973506822e428789d842761e0280d25e3359300f017fbe77b9755bc772ab3dc2f83 languageName: node linkType: hard -"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.11, @types/prop-types@npm:^15.7.12": - version: 15.7.12 - resolution: "@types/prop-types@npm:15.7.12" - checksum: ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe +"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.12, @types/prop-types@npm:^15.7.14, @types/prop-types@npm:^15.7.15": + version: 15.7.15 + resolution: "@types/prop-types@npm:15.7.15" + checksum: 31aa2f59b28f24da6fb4f1d70807dae2aedfce090ec63eaf9ea01727a9533ef6eaf017de5bff99fbccad7d1c9e644f52c6c2ba30869465dd22b1a7221c29f356 languageName: node linkType: hard @@ -3859,9 +6219,9 @@ __metadata: linkType: hard "@types/qs@npm:*": - version: 6.9.15 - resolution: "@types/qs@npm:6.9.15" - checksum: 97d8208c2b82013b618e7a9fc14df6bd40a73e1385ac479b6896bafc7949a46201c15f42afd06e86a05e914f146f495f606b6fb65610cc60cf2e0ff743ec38a2 + version: 6.14.0 + resolution: "@types/qs@npm:6.14.0" + checksum: 1909205514d22b3cbc7c2314e2bd8056d5f05dfb21cf4377f0730ee5e338ea19957c41735d5e4806c746176563f50005bbab602d8358432e25d900bdf4970826 languageName: node linkType: hard @@ -3920,12 +6280,12 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:^4.4.10, @types/react-transition-group@npm:^4.4.8": - version: 4.4.10 - resolution: "@types/react-transition-group@npm:4.4.10" - dependencies: +"@types/react-transition-group@npm:^4.4.11, @types/react-transition-group@npm:^4.4.12": + version: 4.4.12 + resolution: "@types/react-transition-group@npm:4.4.12" + peerDependencies: "@types/react": "*" - checksum: fe2ea11f70251e9f79f368e198c18fd469b1d4f1e1d44e4365845b44e15974b0ec925100036f449b023b0ca3480a82725c5f0a73040e282ad32ec7b0def9b57c + checksum: 13d36396cae4d3c316b03d4a0ba299f0d039c59368ba65e04b0c3dc06fd0a16f59d2c669c3e32d6d525a95423f156b84e550d26bff0bdd8df285f305f8f3a0ed languageName: node linkType: hard @@ -3939,12 +6299,12 @@ __metadata: languageName: node linkType: hard -"@types/resolve@npm:0.0.8": - version: 0.0.8 - resolution: "@types/resolve@npm:0.0.8" +"@types/resolve@npm:1.17.1": + version: 1.17.1 + resolution: "@types/resolve@npm:1.17.1" dependencies: "@types/node": "*" - checksum: f241bb773ab14b14500623ac3b57c52006ce32b20426b6d8bf2fe5fdc0344f42c77ac0f94ff57b443ae1d320a1a86c62b4e47239f0321699404402fbeb24bad6 + checksum: dc6a6df507656004e242dcb02c784479deca516d5f4b58a1707e708022b269ae147e1da0521f3e8ad0d63638869d87e0adc023f0bd5454aa6f72ac66c7525cf5 languageName: node linkType: hard @@ -3955,40 +6315,49 @@ __metadata: languageName: node linkType: hard +"@types/semver@npm:^7.3.12": + version: 7.7.1 + resolution: "@types/semver@npm:7.7.1" + checksum: 76d218e414482a398148d5c28f2bfa017108869f3fc18cda379c9d8d062348f8b9653ae2fa8642d3b5b52e211928fe8be34f22da4e1f08245c84e0e51e040673 + languageName: node + linkType: hard + "@types/send@npm:*": - version: 0.17.4 - resolution: "@types/send@npm:0.17.4" + version: 0.17.5 + resolution: "@types/send@npm:0.17.5" dependencies: "@types/mime": ^1 "@types/node": "*" - checksum: cf4db48251bbb03cd6452b4de6e8e09e2d75390a92fd798eca4a803df06444adc94ed050246c94c7ed46fb97be1f63607f0e1f13c3ce83d71788b3e08640e5e0 + checksum: bff5add75eb178c3b80bebc422db483c76eeb2cb5016508c952e4fc67d968794f9c709b978d086bf60e4d6fbfe8c0b77e99a7603a615c671c1f97f808458d4a8 languageName: node linkType: hard -"@types/serve-static@npm:*": - version: 1.15.7 - resolution: "@types/serve-static@npm:1.15.7" +"@types/serve-index@npm:^1.9.1": + version: 1.9.4 + resolution: "@types/serve-index@npm:1.9.4" dependencies: - "@types/http-errors": "*" - "@types/node": "*" - "@types/send": "*" - checksum: bbbf00dbd84719da2250a462270dc68964006e8d62f41fe3741abd94504ba3688f420a49afb2b7478921a1544d3793183ffa097c5724167da777f4e0c7f1a7d6 + "@types/express": "*" + checksum: 72727c88d54da5b13275ebfb75dcdc4aa12417bbe9da1939e017c4c5f0c906fae843aa4e0fbfe360e7ee9df2f3d388c21abfc488f77ce58693fb57809f8ded92 languageName: node linkType: hard -"@types/set-cookie-parser@npm:^2.4.0": - version: 2.4.7 - resolution: "@types/set-cookie-parser@npm:2.4.7" +"@types/serve-static@npm:*, @types/serve-static@npm:^1.13.10": + version: 1.15.8 + resolution: "@types/serve-static@npm:1.15.8" dependencies: + "@types/http-errors": "*" "@types/node": "*" - checksum: 01ef803e24b8cd33e49fe7463f32a562da45ce3f960381b90cccf67ea71b1830d2273df044255b040069c0a92ea25b4bf21c39ac2f85b50c01818ded5e918554 + "@types/send": "*" + checksum: 41e0fb40bfdf3b5c2ac997c5dd5d58af9229e6a325dab1cf5f73b488b09635d933c1aa6f0e3265d6df8b45be0d09af36a9ffe90175088726f1db6bf104bf9ecf languageName: node linkType: hard -"@types/source-list-map@npm:*": - version: 0.1.6 - resolution: "@types/source-list-map@npm:0.1.6" - checksum: 9cd294c121f1562062de5d241fe4d10780b1131b01c57434845fe50968e9dcf67ede444591c2b1ad6d3f9b6bc646ac02cc8f51a3577c795f9c64cf4573dcc6b1 +"@types/sockjs@npm:^0.3.33": + version: 0.3.36 + resolution: "@types/sockjs@npm:0.3.36" + dependencies: + "@types/node": "*" + checksum: b4b5381122465d80ea8b158537c00bc82317222d3fb31fd7229ff25b31fa89134abfbab969118da55622236bf3d8fee75759f3959908b5688991f492008f29bc languageName: node linkType: hard @@ -3999,14 +6368,22 @@ __metadata: languageName: node linkType: hard +"@types/statuses@npm:^2.0.4": + version: 2.0.6 + resolution: "@types/statuses@npm:2.0.6" + checksum: dadfbb4f32a16d3106a8e2a957dab17b1ae99fc4788e1fd96aeaf82355e3b2b069d5ea0f5fb887efa830def033828955a5bbdfd35454ba2088822537aed9e5db + languageName: node + linkType: hard + "@types/superagent@npm:*": - version: 8.1.6 - resolution: "@types/superagent@npm:8.1.6" + version: 8.1.9 + resolution: "@types/superagent@npm:8.1.9" dependencies: "@types/cookiejar": ^2.1.5 "@types/methods": ^1.1.4 "@types/node": "*" - checksum: 240ea5a58bb3c9e53f0dbe1ccd1bfe046e084fffdb4eaf44f0bf846fb98dad98ce03d057fdfb555bfa06afbb76a0e5877fe639750b798edac594bc7e19833934 + form-data: ^4.0.0 + checksum: 530d8c2e87706315c82c8c9696500c40621de3353bc54ea9b104947f3530243abf54d0a49a6ae219d4947606a102ceb94bedfc43b9cc49f74069a18cbb3be8e2 languageName: node linkType: hard @@ -4019,60 +6396,54 @@ __metadata: languageName: node linkType: hard -"@types/tapable@npm:^1, @types/tapable@npm:^1.0.5": - version: 1.0.12 - resolution: "@types/tapable@npm:1.0.12" - checksum: 5312fbc01e0135bd11b44cfea2bf29943807cd9675c10bbed13873ad0e73f656993fb88bb6ceaf05b12a55c570e6acc0267faf59e9c4d2f032fc833bafcf0597 +"@types/trusted-types@npm:^2.0.2": + version: 2.0.7 + resolution: "@types/trusted-types@npm:2.0.7" + checksum: 8e4202766a65877efcf5d5a41b7dd458480b36195e580a3b1085ad21e948bc417d55d6f8af1fd2a7ad008015d4117d5fdfe432731157da3c68678487174e4ba3 languageName: node linkType: hard -"@types/testing-library__jest-dom@npm:^5.9.1": - version: 5.14.9 - resolution: "@types/testing-library__jest-dom@npm:5.14.9" - dependencies: - "@types/jest": "*" - checksum: d364494fc2545316292e88861146146af1e3818792ca63b62a63758b2f737669b687f4aaddfcfbcb7d0e1ed7890a9bd05de23ff97f277d5e68de574497a9ee72 +"@types/unist@npm:*, @types/unist@npm:^3.0.0": + version: 3.0.3 + resolution: "@types/unist@npm:3.0.3" + checksum: 96e6453da9e075aaef1dc22482463898198acdc1eeb99b465e65e34303e2ec1e3b1ed4469a9118275ec284dc98019f63c3f5d49422f0e4ac707e5ab90fb3b71a languageName: node linkType: hard -"@types/uglify-js@npm:*": - version: 3.17.5 - resolution: "@types/uglify-js@npm:3.17.5" - dependencies: - source-map: ^0.6.1 - checksum: ffed5d63637c6ea5c155469121ee40d9b652e677e6d9eb07b72ff72bb4029ffad19049a0af6e91a5021bad6c481cff2572fbf6367e319c6885cf1537c20d861d +"@types/unist@npm:^2.0.0": + version: 2.0.11 + resolution: "@types/unist@npm:2.0.11" + checksum: 6d436e832bc35c6dde9f056ac515ebf2b3384a1d7f63679d12358766f9b313368077402e9c1126a14d827f10370a5485e628bf61aa91117cf4fc882423191a4e languageName: node linkType: hard -"@types/unist@npm:^2, @types/unist@npm:^2.0.0, @types/unist@npm:^2.0.2, @types/unist@npm:^2.0.3": - version: 2.0.10 - resolution: "@types/unist@npm:2.0.10" - checksum: e2924e18dedf45f68a5c6ccd6015cd62f1643b1b43baac1854efa21ae9e70505db94290434a23da1137d9e31eb58e54ca175982005698ac37300a1c889f6c4aa +"@types/use-sync-external-store@npm:^0.0.6": + version: 0.0.6 + resolution: "@types/use-sync-external-store@npm:0.0.6" + checksum: a95ce330668501ad9b1c5b7f2b14872ad201e552a0e567787b8f1588b22c7040c7c3d80f142cbb9f92d13c4ea41c46af57a20f2af4edf27f224d352abcfe4049 languageName: node linkType: hard -"@types/webpack-sources@npm:*": - version: 3.2.3 - resolution: "@types/webpack-sources@npm:3.2.3" - dependencies: - "@types/node": "*" - "@types/source-list-map": "*" - source-map: ^0.7.3 - checksum: 7b557f242efaa10e4e3e18cc4171a0c98e22898570caefdd4f7b076fe8534b5abfac92c953c6604658dcb7218507f970230352511840fe9fdea31a9af3b9a906 +"@types/uuid@npm:^10.0.0": + version: 10.0.0 + resolution: "@types/uuid@npm:10.0.0" + checksum: e3958f8b0fe551c86c14431f5940c3470127293280830684154b91dc7eb3514aeb79fe3216968833cf79d4d1c67f580f054b5be2cd562bebf4f728913e73e944 + languageName: node + linkType: hard + +"@types/uuid@npm:^9.0.1": + version: 9.0.8 + resolution: "@types/uuid@npm:9.0.8" + checksum: b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 languageName: node linkType: hard -"@types/webpack@npm:^4.41.8": - version: 4.41.38 - resolution: "@types/webpack@npm:4.41.38" +"@types/ws@npm:^8.5.5": + version: 8.18.1 + resolution: "@types/ws@npm:8.18.1" dependencies: "@types/node": "*" - "@types/tapable": ^1 - "@types/uglify-js": "*" - "@types/webpack-sources": "*" - anymatch: ^3.0.0 - source-map: ^0.6.0 - checksum: d3de65993ef3a7621f75548c2f6f509e8f87f586032238e999743d6067030655c67e38ec5f8b32e04fa5276c83bdfb7a761773bce0e6f28605da87e3fc388e3e + checksum: 0331b14cde388e2805af66cad3e3f51857db8e68ed91e5b99750915e96fe7572e58296dc99999331bbcf08f0ff00a227a0bb214e991f53c2a5aca7b0e71173fa languageName: node linkType: hard @@ -4083,7 +6454,7 @@ __metadata: languageName: node linkType: hard -"@types/yargs@npm:^15.0.0": +"@types/yargs@npm:^15.0.4": version: 15.0.19 resolution: "@types/yargs@npm:15.0.19" dependencies: @@ -4092,418 +6463,603 @@ __metadata: languageName: node linkType: hard +"@types/yargs@npm:^16.0.0": + version: 16.0.9 + resolution: "@types/yargs@npm:16.0.9" + dependencies: + "@types/yargs-parser": "*" + checksum: 00d9276ed4e0f17a78c1ed57f644a8c14061959bd5bfab113d57f082ea4b663ba97f71b89371304a34a2dba5061e9ae4523e357e577ba61834d661f82c223bf8 + languageName: node + linkType: hard + "@types/yargs@npm:^17.0.8": - version: 17.0.32 - resolution: "@types/yargs@npm:17.0.32" + version: 17.0.33 + resolution: "@types/yargs@npm:17.0.33" dependencies: "@types/yargs-parser": "*" - checksum: 4505bdebe8716ff383640c6e928f855b5d337cb3c68c81f7249fc6b983d0aa48de3eee26062b84f37e0d75a5797bc745e0c6e76f42f81771252a758c638f36ba + checksum: ee013f257472ab643cb0584cf3e1ff9b0c44bca1c9ba662395300a7f1a6c55fa9d41bd40ddff42d99f5d95febb3907c9ff600fbcb92dadbec22c6a76de7e1236 languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^4.18.0, @typescript-eslint/eslint-plugin@npm:^4.5.0": - version: 4.33.0 - resolution: "@typescript-eslint/eslint-plugin@npm:4.33.0" +"@typescript-eslint/eslint-plugin@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.20.0" dependencies: - "@typescript-eslint/experimental-utils": 4.33.0 - "@typescript-eslint/scope-manager": 4.33.0 - debug: ^4.3.1 - functional-red-black-tree: ^1.0.1 - ignore: ^5.1.8 - regexpp: ^3.1.0 - semver: ^7.3.5 + "@eslint-community/regexpp": ^4.10.0 + "@typescript-eslint/scope-manager": 8.20.0 + "@typescript-eslint/type-utils": 8.20.0 + "@typescript-eslint/utils": 8.20.0 + "@typescript-eslint/visitor-keys": 8.20.0 + graphemer: ^1.4.0 + ignore: ^5.3.1 + natural-compare: ^1.4.0 + ts-api-utils: ^2.0.0 + peerDependencies: + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + checksum: f029bfcce3dc12d7b539f86142857d680e06d798eca213d9fb564685d12b479205b7f40b4996e30e3f7301c7bb6d15484741352f54ddd00d74a07ea2aca53cf6 + languageName: node + linkType: hard + +"@typescript-eslint/eslint-plugin@npm:^5.5.0": + version: 5.62.0 + resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" + dependencies: + "@eslint-community/regexpp": ^4.4.0 + "@typescript-eslint/scope-manager": 5.62.0 + "@typescript-eslint/type-utils": 5.62.0 + "@typescript-eslint/utils": 5.62.0 + debug: ^4.3.4 + graphemer: ^1.4.0 + ignore: ^5.2.0 + natural-compare-lite: ^1.4.0 + semver: ^7.3.7 tsutils: ^3.21.0 peerDependencies: - "@typescript-eslint/parser": ^4.0.0 - eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + "@typescript-eslint/parser": ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: d74855d0a5ffe0b2f362ec02fcd9301d39a53fb4155b9bd0cb15a0a31d065143129ebf98df9d86af4b6f74de1d423a4c0d8c0095520844068117453afda5bc4f + checksum: fc104b389c768f9fa7d45a48c86d5c1ad522c1d0512943e782a56b1e3096b2cbcc1eea3fcc590647bf0658eef61aac35120a9c6daf979bf629ad2956deb516a1 languageName: node linkType: hard -"@typescript-eslint/experimental-utils@npm:4.33.0, @typescript-eslint/experimental-utils@npm:^4.0.1": - version: 4.33.0 - resolution: "@typescript-eslint/experimental-utils@npm:4.33.0" +"@typescript-eslint/experimental-utils@npm:^5.0.0": + version: 5.62.0 + resolution: "@typescript-eslint/experimental-utils@npm:5.62.0" dependencies: - "@types/json-schema": ^7.0.7 - "@typescript-eslint/scope-manager": 4.33.0 - "@typescript-eslint/types": 4.33.0 - "@typescript-eslint/typescript-estree": 4.33.0 - eslint-scope: ^5.1.1 - eslint-utils: ^3.0.0 + "@typescript-eslint/utils": 5.62.0 peerDependencies: - eslint: "*" - checksum: f859800ada0884f92db6856f24efcb1d073ac9883ddc2b1aa9339f392215487895bed8447ebce3741e8141bb32e545244abef62b73193ba9a8a0527c523aabae + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: ce55d9f74eac5cb94d66d5db9ead9a5d734f4301519fb5956a57f4b405a5318a115b0316195a3c039e0111489138680411709cb769085d71e1e1db1376ea0949 languageName: node linkType: hard -"@typescript-eslint/experimental-utils@npm:^3.10.1": - version: 3.10.1 - resolution: "@typescript-eslint/experimental-utils@npm:3.10.1" +"@typescript-eslint/parser@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/parser@npm:8.20.0" dependencies: - "@types/json-schema": ^7.0.3 - "@typescript-eslint/types": 3.10.1 - "@typescript-eslint/typescript-estree": 3.10.1 - eslint-scope: ^5.0.0 - eslint-utils: ^2.0.0 + "@typescript-eslint/scope-manager": 8.20.0 + "@typescript-eslint/types": 8.20.0 + "@typescript-eslint/typescript-estree": 8.20.0 + "@typescript-eslint/visitor-keys": 8.20.0 + debug: ^4.3.4 peerDependencies: - eslint: "*" - checksum: 635cc1afe466088b04901c2bce0e4c3e48bb74668e61e39aa74a485f856c6f9683482350d4b16b3f4c0112ce40cad2c2c427d4fe5e11a3329b3bb93286d4ab26 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + checksum: 00b265ed42ee1d8eb715f9978d701be0958baf7a5be9de74a1b58c09c78e3558e1e6352c4476ec8ea376c28f1437de0b58b3e1e2a9975c489f2ecd369a9050eb languageName: node linkType: hard -"@typescript-eslint/parser@npm:^4.18.0, @typescript-eslint/parser@npm:^4.5.0": - version: 4.33.0 - resolution: "@typescript-eslint/parser@npm:4.33.0" +"@typescript-eslint/parser@npm:^5.5.0": + version: 5.62.0 + resolution: "@typescript-eslint/parser@npm:5.62.0" dependencies: - "@typescript-eslint/scope-manager": 4.33.0 - "@typescript-eslint/types": 4.33.0 - "@typescript-eslint/typescript-estree": 4.33.0 - debug: ^4.3.1 + "@typescript-eslint/scope-manager": 5.62.0 + "@typescript-eslint/types": 5.62.0 + "@typescript-eslint/typescript-estree": 5.62.0 + debug: ^4.3.4 peerDependencies: - eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 102457eae1acd516211098fea081c8a2ed728522bbda7f5a557b6ef23d88970514f9a0f6285d53fca134d3d4d7d17822b5d5e12438d5918df4d1f89cc9e67d57 + checksum: d168f4c7f21a7a63f47002e2d319bcbb6173597af5c60c1cf2de046b46c76b4930a093619e69faf2d30214c29ab27b54dcf1efc7046a6a6bd6f37f59a990e752 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:4.33.0": - version: 4.33.0 - resolution: "@typescript-eslint/scope-manager@npm:4.33.0" +"@typescript-eslint/scope-manager@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/scope-manager@npm:5.62.0" dependencies: - "@typescript-eslint/types": 4.33.0 - "@typescript-eslint/visitor-keys": 4.33.0 - checksum: 9a25fb7ba7c725ea7227a24d315b0f6aacbad002e2549a049edf723c1d3615c22f5c301f0d7d615b377f2cdf2f3519d97e79af0c459de6ef8d2aaf0906dff13e - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:3.10.1": - version: 3.10.1 - resolution: "@typescript-eslint/types@npm:3.10.1" - checksum: 3ea820d37c2595d457acd6091ffda8b531e5d916e1cce708336bf958aa8869126f95cca3268a724f453ce13be11c5388a0a4143bf09bca51be1020ec46635d92 + "@typescript-eslint/types": 5.62.0 + "@typescript-eslint/visitor-keys": 5.62.0 + checksum: 6062d6b797fe1ce4d275bb0d17204c827494af59b5eaf09d8a78cdd39dadddb31074dded4297aaf5d0f839016d601032857698b0e4516c86a41207de606e9573 languageName: node linkType: hard -"@typescript-eslint/types@npm:4.33.0": - version: 4.33.0 - resolution: "@typescript-eslint/types@npm:4.33.0" - checksum: 3baae1ca35872421b4eb60f5d3f3f32dc1d513f2ae0a67dee28c7d159fd7a43ed0d11a8a5a0f0c2d38507ffa036fc7c511cb0f18a5e8ac524b3ebde77390ec53 +"@typescript-eslint/scope-manager@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/scope-manager@npm:8.20.0" + dependencies: + "@typescript-eslint/types": 8.20.0 + "@typescript-eslint/visitor-keys": 8.20.0 + checksum: d90d89f3dc8394e44652526b88c81a977b251702a9dc5be89ac0bf7412d79d18879e03c2d6018980a09bc7c50d28dbf91ba06e056e081e6000783d69bd280761 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:3.10.1": - version: 3.10.1 - resolution: "@typescript-eslint/typescript-estree@npm:3.10.1" +"@typescript-eslint/type-utils@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/type-utils@npm:5.62.0" dependencies: - "@typescript-eslint/types": 3.10.1 - "@typescript-eslint/visitor-keys": 3.10.1 - debug: ^4.1.1 - glob: ^7.1.6 - is-glob: ^4.0.1 - lodash: ^4.17.15 - semver: ^7.3.2 - tsutils: ^3.17.1 + "@typescript-eslint/typescript-estree": 5.62.0 + "@typescript-eslint/utils": 5.62.0 + debug: ^4.3.4 + tsutils: ^3.21.0 + peerDependencies: + eslint: "*" peerDependenciesMeta: typescript: optional: true - checksum: 911680da9d26220944f4f8f26f88349917609844fafcff566147cecae37ff0211d66c626eb62a2b24d17fd50d10715f5b0f32b2e7f5d9a88efc46709266d5053 + checksum: fc41eece5f315dfda14320be0da78d3a971d650ea41300be7196934b9715f3fe1120a80207551eb71d39568275dbbcf359bde540d1ca1439d8be15e9885d2739 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:4.33.0": - version: 4.33.0 - resolution: "@typescript-eslint/typescript-estree@npm:4.33.0" +"@typescript-eslint/type-utils@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/type-utils@npm:8.20.0" dependencies: - "@typescript-eslint/types": 4.33.0 - "@typescript-eslint/visitor-keys": 4.33.0 - debug: ^4.3.1 - globby: ^11.0.3 - is-glob: ^4.0.1 - semver: ^7.3.5 + "@typescript-eslint/typescript-estree": 8.20.0 + "@typescript-eslint/utils": 8.20.0 + debug: ^4.3.4 + ts-api-utils: ^2.0.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + checksum: 705a166dc2846f7fe79a123ee623da213a20289fba9c0cbbcc894fe7caaa1d4ddc81bf54db9dc918c29a34294a05768c38a4f00762ba3745e0e94e2e2963f104 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/types@npm:5.62.0" + checksum: 48c87117383d1864766486f24de34086155532b070f6264e09d0e6139449270f8a9559cfef3c56d16e3bcfb52d83d42105d61b36743626399c7c2b5e0ac3b670 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/types@npm:8.20.0" + checksum: 4cb0af48411f282db33e7110e2f97de874c637e7b90ded91b77304e96f49663ca4b7308afc569bdd93766fe5f2c194686e32078d5513b5ba4e7d56191998190c + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" + dependencies: + "@typescript-eslint/types": 5.62.0 + "@typescript-eslint/visitor-keys": 5.62.0 + debug: ^4.3.4 + globby: ^11.1.0 + is-glob: ^4.0.3 + semver: ^7.3.7 tsutils: ^3.21.0 peerDependenciesMeta: typescript: optional: true - checksum: 2566984390c76bd95f43240057215c068c69769e406e27aba41e9f21fd300074d6772e4983fa58fe61e80eb5550af1548d2e31e80550d92ba1d051bb00fe6f5c + checksum: 3624520abb5807ed8f57b1197e61c7b1ed770c56dfcaca66372d584ff50175225798bccb701f7ef129d62c5989070e1ee3a0aa2d84e56d9524dcf011a2bb1a52 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:3.10.1": - version: 3.10.1 - resolution: "@typescript-eslint/visitor-keys@npm:3.10.1" +"@typescript-eslint/typescript-estree@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.20.0" dependencies: - eslint-visitor-keys: ^1.1.0 - checksum: 0c4825b9829b1c11258a73aaee70d64834ba6d9b24157e7624e80f27f6537f468861d4dd33ad233c13ad2c6520afb9008c0675da6d792f26e82d75d6bfe9b0c6 + "@typescript-eslint/types": 8.20.0 + "@typescript-eslint/visitor-keys": 8.20.0 + debug: ^4.3.4 + fast-glob: ^3.3.2 + is-glob: ^4.0.3 + minimatch: ^9.0.4 + semver: ^7.6.0 + ts-api-utils: ^2.0.0 + peerDependencies: + typescript: ">=4.8.4 <5.8.0" + checksum: 9690df2d4ec90966b8d5752ad0f1658a951fe76ea3cae8e6935e698715a25c1eb0b118fa8e044065f04ea9f6bef41d991de5298590ef2a4aa98d435bf1df6e15 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:4.33.0": - version: 4.33.0 - resolution: "@typescript-eslint/visitor-keys@npm:4.33.0" +"@typescript-eslint/utils@npm:5.62.0, @typescript-eslint/utils@npm:^5.58.0": + version: 5.62.0 + resolution: "@typescript-eslint/utils@npm:5.62.0" dependencies: - "@typescript-eslint/types": 4.33.0 - eslint-visitor-keys: ^2.0.0 - checksum: 59953e474ad4610c1aa23b2b1a964445e2c6201521da6367752f37939d854352bbfced5c04ea539274065e012b1337ba3ffa49c2647a240a4e87155378ba9873 + "@eslint-community/eslint-utils": ^4.2.0 + "@types/json-schema": ^7.0.9 + "@types/semver": ^7.3.12 + "@typescript-eslint/scope-manager": 5.62.0 + "@typescript-eslint/types": 5.62.0 + "@typescript-eslint/typescript-estree": 5.62.0 + eslint-scope: ^5.1.1 + semver: ^7.3.7 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: ee9398c8c5db6d1da09463ca7bf36ed134361e20131ea354b2da16a5fdb6df9ba70c62a388d19f6eebb421af1786dbbd79ba95ddd6ab287324fc171c3e28d931 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/utils@npm:8.20.0" + dependencies: + "@eslint-community/eslint-utils": ^4.4.0 + "@typescript-eslint/scope-manager": 8.20.0 + "@typescript-eslint/types": 8.20.0 + "@typescript-eslint/typescript-estree": 8.20.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + checksum: 5c9d72eb0d4014e41de1faa4597371f19362ce47a491359be408bfba899277f8d5660f014651f7bd41435158ae4655ade205e92f175e2355ca51a07af35a53ed + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" + dependencies: + "@typescript-eslint/types": 5.62.0 + eslint-visitor-keys: ^3.3.0 + checksum: 976b05d103fe8335bef5c93ad3f76d781e3ce50329c0243ee0f00c0fcfb186c81df50e64bfdd34970148113f8ade90887f53e3c4938183afba830b4ba8e30a35 + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.20.0" + dependencies: + "@typescript-eslint/types": 8.20.0 + eslint-visitor-keys: ^4.2.0 + checksum: d0bf89e431a686197c517fbb7d63ce4c8ef31e6629a545fd08198c67810ddd68c047c01fcfed8ffc3fe438654a2647b3dedf28f04beac23a65614b2e788d929a + languageName: node + linkType: hard + +"@ungap/structured-clone@npm:^1.0.0, @ungap/structured-clone@npm:^1.2.0": + version: 1.3.0 + resolution: "@ungap/structured-clone@npm:1.3.0" + checksum: 64ed518f49c2b31f5b50f8570a1e37bde3b62f2460042c50f132430b2d869c4a6586f13aa33a58a4722715b8158c68cae2827389d6752ac54da2893c83e480fc languageName: node linkType: hard "@vitejs/plugin-react@npm:^4.0.0": - version: 4.2.1 - resolution: "@vitejs/plugin-react@npm:4.2.1" + version: 4.7.0 + resolution: "@vitejs/plugin-react@npm:4.7.0" dependencies: - "@babel/core": ^7.23.5 - "@babel/plugin-transform-react-jsx-self": ^7.23.3 - "@babel/plugin-transform-react-jsx-source": ^7.23.3 + "@babel/core": ^7.28.0 + "@babel/plugin-transform-react-jsx-self": ^7.27.1 + "@babel/plugin-transform-react-jsx-source": ^7.27.1 + "@rolldown/pluginutils": 1.0.0-beta.27 "@types/babel__core": ^7.20.5 - react-refresh: ^0.14.0 + react-refresh: ^0.17.0 peerDependencies: - vite: ^4.2.0 || ^5.0.0 - checksum: 08d227d27ff2304e395e746bd2d4b5fee40587f69d7e2fcd6beb7d91163c1f1dc26d843bc48e2ffb8f38c6b8a1b9445fb07840e3dcc841f97b56bbb8205346aa + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + checksum: 3e3c4c58f65e8041c4891736613732d572f232bc6b039e74ea00554b94b8010ac246e2f6e099e8b6c474d9c1741e2b166b48fa47fe0093312beefa99a1b13d00 languageName: node linkType: hard -"@vitest/expect@npm:0.32.4": - version: 0.32.4 - resolution: "@vitest/expect@npm:0.32.4" +"@vitest/expect@npm:2.1.9": + version: 2.1.9 + resolution: "@vitest/expect@npm:2.1.9" dependencies: - "@vitest/spy": 0.32.4 - "@vitest/utils": 0.32.4 - chai: ^4.3.7 - checksum: fb44ae0507c3a0298e472e64f4d298f60b159c7ce05201987cbd60ba6b11069a97bed5f689f911ac66096ee573c64ed0c17a2511661ad7823ce31a86244b8cd8 + "@vitest/spy": 2.1.9 + "@vitest/utils": 2.1.9 + chai: ^5.1.2 + tinyrainbow: ^1.2.0 + checksum: a234f96dd42c76e20af68b2ad2f00b80a3873501d5daa524bf1405b344e86123716b925f976d8104fd242bfbd0d9cf7084d0eb4a690097e6e5db456d220ed67a languageName: node linkType: hard -"@vitest/runner@npm:0.32.4": - version: 0.32.4 - resolution: "@vitest/runner@npm:0.32.4" +"@vitest/expect@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/expect@npm:3.2.4" dependencies: - "@vitest/utils": 0.32.4 - p-limit: ^4.0.0 - pathe: ^1.1.1 - checksum: 06f2b4003963a7f18954bcd690ebd3b917e1d45d998a8c9a23458569a8ae9b50a18fcf511ac100343eeddf1df1e47f8eba870e193afa895ccb348a679e5295de + "@types/chai": ^5.2.2 + "@vitest/spy": 3.2.4 + "@vitest/utils": 3.2.4 + chai: ^5.2.0 + tinyrainbow: ^2.0.0 + checksum: 57627ee2b47555f47a15843fda05267816e9767e5a769179acac224b8682844e662fa77fbeeb04adcb0874779f3aca861f54e9fc630c1d256d5ea8211c223120 languageName: node linkType: hard -"@vitest/snapshot@npm:0.32.4": - version: 0.32.4 - resolution: "@vitest/snapshot@npm:0.32.4" +"@vitest/mocker@npm:2.1.9": + version: 2.1.9 + resolution: "@vitest/mocker@npm:2.1.9" dependencies: - magic-string: ^0.30.0 - pathe: ^1.1.1 - pretty-format: ^29.5.0 - checksum: d8907fc0504acfb59df88aaf43a210161f7e2f22eaaa96c6562b7a1c9e28b12d2b572afcd49ae224a8a9947fabf473e956c7ea7c7d25f794d5521d7d45f24b78 + "@vitest/spy": 2.1.9 + estree-walker: ^3.0.3 + magic-string: ^0.30.12 + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 17de391acc4d899f15356b45cde8202e5d5ca4517c32c0c9dcf32ce0660501773fdc29675b4f7d48c1579a560ac41f8f5181ebe41a7daf675f561d611e8e30dc languageName: node linkType: hard -"@vitest/spy@npm:0.32.4": - version: 0.32.4 - resolution: "@vitest/spy@npm:0.32.4" +"@vitest/mocker@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/mocker@npm:3.2.4" dependencies: - tinyspy: ^2.1.1 - checksum: 742870e7554dd8d478de85bc265c3af051e1f3420093fdc9978fe9871472db37da6da69c66d80ad604029d1dfdc303f1159613d9ccf08dba1c3991eb4e7616a7 + "@vitest/spy": 3.2.4 + estree-walker: ^3.0.3 + magic-string: ^0.30.17 + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 2c8ba286fc714036b645a7a72bfbbd6b243baa65320dd71009f5ed1115f70f69c0209e2e213a05202c172e09a408821a33f9df5bc7979900e91cde5d302976e0 languageName: node linkType: hard -"@vitest/utils@npm:0.32.4": - version: 0.32.4 - resolution: "@vitest/utils@npm:0.32.4" +"@vitest/pretty-format@npm:2.1.9, @vitest/pretty-format@npm:^2.1.9": + version: 2.1.9 + resolution: "@vitest/pretty-format@npm:2.1.9" dependencies: - diff-sequences: ^29.4.3 - loupe: ^2.3.6 - pretty-format: ^29.5.0 - checksum: 7d81162c3afaa638d30c47a28b7eced62abb8d7a8c891b10fa2f9756b2b6609d767142162044fe976c2cb8c17911d135fb3950f83e6d2bbd90150a042237bd25 + tinyrainbow: ^1.2.0 + checksum: 33f7ff0a9d356ddd6534390a0aea260dc04a3022a94901c87d141bacf71d2b3fff2e3bf08a55dd424c5355fd3b41656cb7871c76372fef45ffac1ea89d0dc508 languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/ast@npm:1.9.0" +"@vitest/pretty-format@npm:3.2.4, @vitest/pretty-format@npm:^3.2.4": + version: 3.2.4 + resolution: "@vitest/pretty-format@npm:3.2.4" dependencies: - "@webassemblyjs/helper-module-context": 1.9.0 - "@webassemblyjs/helper-wasm-bytecode": 1.9.0 - "@webassemblyjs/wast-parser": 1.9.0 - checksum: 8a9838dc7fdac358aee8daa75eefa35934ab18dafb594092ff7be79c467ebe9dabb2543e58313c905fd802bdcc3cb8320e4e19af7444e49853a7a24e25138f75 + tinyrainbow: ^2.0.0 + checksum: 68a196e4bdfce6fd03c3958b76cddb71bec65a62ab5aff05ba743a44853b03a95c2809b4e5733d21abff25c4d070dd64f60c81ac973a9fd21a840ff8f8a8d184 languageName: node linkType: hard -"@webassemblyjs/floating-point-hex-parser@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.9.0" - checksum: d3aeb19bc30da26f639698daa28e44e0c18d5aa135359ef3c54148e194eec46451a912d0506099d479a71a94bc3eef6ef52d6ec234799528a25a9744789852de +"@vitest/runner@npm:2.1.9": + version: 2.1.9 + resolution: "@vitest/runner@npm:2.1.9" + dependencies: + "@vitest/utils": 2.1.9 + pathe: ^1.1.2 + checksum: d8aaadc98bcbe1ee7c832a7d619d3c77d3c67536f10b80a3106d9d6e03ecc0f5467ef7bd4a65a07fe924cc166fe7415d637b2b08ef71e1a208a250543f9f3545 languageName: node linkType: hard -"@webassemblyjs/helper-api-error@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/helper-api-error@npm:1.9.0" - checksum: 9179d3148639cc202e89a118145b485cf834613260679a99af6ec487bbc15f238566ca713207394b336160a41bf8c1b75cf2e853b3e96f0cc73c1e5c735b3f64 +"@vitest/runner@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/runner@npm:3.2.4" + dependencies: + "@vitest/utils": 3.2.4 + pathe: ^2.0.3 + strip-literal: ^3.0.0 + checksum: c8b08365818f408eec2fe3acbffa0cc7279939a43c02074cd03b853fa37bc68aa181c8f8c2175513a4c5aa4dd3e52a0573d5897a16846d55b2ff4f3577e6c7c8 languageName: node linkType: hard -"@webassemblyjs/helper-buffer@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/helper-buffer@npm:1.9.0" - checksum: dcb85f630f8a2e22b7346ad4dd58c3237a2cad1457699423e8fd19592a0bd3eacbc2639178a1b9a873c3ac217bfc7a23a134ff440a099496b590e82c7a4968d5 +"@vitest/snapshot@npm:2.1.9": + version: 2.1.9 + resolution: "@vitest/snapshot@npm:2.1.9" + dependencies: + "@vitest/pretty-format": 2.1.9 + magic-string: ^0.30.12 + pathe: ^1.1.2 + checksum: fb693dea59709c9df8660e5948c7971d2c3ce74212eafa7d542a578bbb8aed203dc03129dd5e476251e1946b50432e79a4fd59069fd4f950283e188167b9496d languageName: node linkType: hard -"@webassemblyjs/helper-code-frame@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/helper-code-frame@npm:1.9.0" +"@vitest/snapshot@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/snapshot@npm:3.2.4" dependencies: - "@webassemblyjs/wast-printer": 1.9.0 - checksum: a28fa057f7beff0fd14bff716561520f8edb8c9c56c7a5559451e6765acfb70aaeb8af718ea2bd2262e7baeba597545af407e28eb2eff8329235afe8605f20d1 + "@vitest/pretty-format": 3.2.4 + magic-string: ^0.30.17 + pathe: ^2.0.3 + checksum: 2f00fb83d5c9ed1f2a79323db3993403bd34265314846cb1bcf1cb9b68f56dfde5ee5a4a8dcb6d95317835bc203662e333da6841e50800c6707e0d22e48ebe6e languageName: node linkType: hard -"@webassemblyjs/helper-fsm@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/helper-fsm@npm:1.9.0" - checksum: 374cc510c8f5a7a07d4fe9eb7036cc475a96a670b5d25c31f16757ac8295be8d03a2f29657ff53eaefa9e8315670a48824d430ed910e7c1835788ac79f93124e +"@vitest/spy@npm:2.1.9": + version: 2.1.9 + resolution: "@vitest/spy@npm:2.1.9" + dependencies: + tinyspy: ^3.0.2 + checksum: f9279488b5d2a27800e33e8fe51cc685b2a0db49d30b80b2b0cc924f8b1736eb520459c6e8bd09fa4457f5bb86ff073e7bdcf60d36452c11a8a8f9cbc8030237 languageName: node linkType: hard -"@webassemblyjs/helper-module-context@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/helper-module-context@npm:1.9.0" +"@vitest/spy@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/spy@npm:3.2.4" dependencies: - "@webassemblyjs/ast": 1.9.0 - checksum: 55e8f89c7ea1beaa78fad88403f3753b8413b0f3b6bb32d898ce95078b3e1d1b48ade0919c00b82fc2e3813c0ab6901e415f7a4d4fa9be50944e2431adde75a5 + tinyspy: ^4.0.3 + checksum: 0e3b591e0c67275b747c5aa67946d6496cd6759dd9b8e05c524426207ca9631fe2cae8ac85a8ba22acec4a593393cd97d825f88a42597fc65441f0b633986f49 languageName: node linkType: hard -"@webassemblyjs/helper-wasm-bytecode@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.9.0" - checksum: 280da4df3c556f73a1a02053277f8a4be481de32df4aa21050b015c8f4d27c46af89f0417eb88e486df117e5df4bccffae593f78cb1e79f212d3b3d4f3ed0f04 +"@vitest/utils@npm:2.1.9": + version: 2.1.9 + resolution: "@vitest/utils@npm:2.1.9" + dependencies: + "@vitest/pretty-format": 2.1.9 + loupe: ^3.1.2 + tinyrainbow: ^1.2.0 + checksum: b24fb9c6765801f2e0578ad5c32fadf9541a833301eaed2877a427096cf05214244b361f94eda80be2b9c841f58ae3c67d37dedc5a902b2cb44041979bae4d8f languageName: node linkType: hard -"@webassemblyjs/helper-wasm-section@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.9.0" +"@vitest/utils@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/utils@npm:3.2.4" dependencies: - "@webassemblyjs/ast": 1.9.0 - "@webassemblyjs/helper-buffer": 1.9.0 - "@webassemblyjs/helper-wasm-bytecode": 1.9.0 - "@webassemblyjs/wasm-gen": 1.9.0 - checksum: b8f7bb45d4194074c82210211a5d3e402a5b5fa63ecae26d2c356ae3978af5a530e91192fb260f32f9d561b18e2828b3da2e2f41c59efadb5f3c6d72446807f0 + "@vitest/pretty-format": 3.2.4 + loupe: ^3.1.4 + tinyrainbow: ^2.0.0 + checksum: 6b0fd0075c23b8e3f17ecf315adc1e565e5a9e7d1b8ad78bbccf2505e399855d176254d974587c00bc4396a0e348bae1380e780a1e7f6b97ea6399a9ab665ba7 languageName: node linkType: hard -"@webassemblyjs/ieee754@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/ieee754@npm:1.9.0" +"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/ast@npm:1.14.1" dependencies: - "@xtuc/ieee754": ^1.2.0 - checksum: 7fe4a217ba0f7051e2cfef92919d4a64fac1a63c65411763779bd50907820f33f440255231a474fe3ba03bd1d9ee0328662d1eae3fce4c59b91549d6b62b839b + "@webassemblyjs/helper-numbers": 1.13.2 + "@webassemblyjs/helper-wasm-bytecode": 1.13.2 + checksum: f9154ad9ea14f6f2374ebe918c221fd69a4d4514126a1acc6fa4966e8d27ab28cb550a5e6880032cf620e19640578658a7e5a55bd2aad1e3db4e9d598b8f2099 languageName: node linkType: hard -"@webassemblyjs/leb128@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/leb128@npm:1.9.0" +"@webassemblyjs/floating-point-hex-parser@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2" + checksum: e866ec8433f4a70baa511df5e8f2ebcd6c24f4e2cc6274c7c5aabe2bcce3459ea4680e0f35d450e1f3602acf3913b6b8e4f15069c8cfd34ae8609fb9a7d01795 + languageName: node + linkType: hard + +"@webassemblyjs/helper-api-error@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-api-error@npm:1.13.2" + checksum: 48b5df7fd3095bb252f59a139fe2cbd999a62ac9b488123e9a0da3906ad8a2f2da7b2eb21d328c01a90da987380928706395c2897d1f3ed9e2125b6d75a920d0 + languageName: node + linkType: hard + +"@webassemblyjs/helper-buffer@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/helper-buffer@npm:1.14.1" + checksum: b611e981dfd6a797c3d8fc3a772de29a6e55033737c2c09c31bb66c613bdbb2d25f915df1dee62a602c6acc057ca71128432fa8c3e22a893e1219dc454f14ede + languageName: node + linkType: hard + +"@webassemblyjs/helper-numbers@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-numbers@npm:1.13.2" dependencies: + "@webassemblyjs/floating-point-hex-parser": 1.13.2 + "@webassemblyjs/helper-api-error": 1.13.2 "@xtuc/long": 4.2.2 - checksum: 4ca7cbb869530d78d42a414f34ae53249364cb1ecebbfb6ed5d562c2f209fce857502f088822ee82a23876f653a262ddc34ab64e45a7962510a263d39bb3f51a + checksum: 49e2c9bf9b66997e480f6b44d80f895b3cde4de52ac135921d28e144565edca6903a519f627f4089b5509de1d7f9e5023f0e1a94ff78a36c9e2eb30e7c18ffd2 languageName: node linkType: hard -"@webassemblyjs/utf8@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/utf8@npm:1.9.0" - checksum: e328a30ac8a503bbd015d32e75176e0dedcb45a21d4be051c25dfe89a00035ca7a6dbd8937b442dd5b4b334de3959d4f5fe0b330037bd226a28b9814cd49e84f +"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2" + checksum: 8e059e1c1f0294f4fc3df8e4eaff3c5ef6e2e1358f34ebc118eaf5070ed59e56ed7fc92b28be734ebde17c8d662d5d27e06ade686c282445135da083ae11c128 languageName: node linkType: hard -"@webassemblyjs/wasm-edit@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/wasm-edit@npm:1.9.0" +"@webassemblyjs/helper-wasm-section@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1" dependencies: - "@webassemblyjs/ast": 1.9.0 - "@webassemblyjs/helper-buffer": 1.9.0 - "@webassemblyjs/helper-wasm-bytecode": 1.9.0 - "@webassemblyjs/helper-wasm-section": 1.9.0 - "@webassemblyjs/wasm-gen": 1.9.0 - "@webassemblyjs/wasm-opt": 1.9.0 - "@webassemblyjs/wasm-parser": 1.9.0 - "@webassemblyjs/wast-printer": 1.9.0 - checksum: 1997e0c2f4051c33239587fb143242919320bc861a0af03a873c7150a27d6404bd2e063c658193288b0aa88c35aadbe0c4fde601fe642bae0743a8c8eda52717 + "@webassemblyjs/ast": 1.14.1 + "@webassemblyjs/helper-buffer": 1.14.1 + "@webassemblyjs/helper-wasm-bytecode": 1.13.2 + "@webassemblyjs/wasm-gen": 1.14.1 + checksum: 0a08d454a63192cd66abf91b6f060ac4b466cef341262246e9dcc828dd4c8536195dea9b46a1244b1eac65b59b8b502164a771a190052a92ff0a0a2ded0f8f53 languageName: node linkType: hard -"@webassemblyjs/wasm-gen@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/wasm-gen@npm:1.9.0" +"@webassemblyjs/ieee754@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/ieee754@npm:1.13.2" dependencies: - "@webassemblyjs/ast": 1.9.0 - "@webassemblyjs/helper-wasm-bytecode": 1.9.0 - "@webassemblyjs/ieee754": 1.9.0 - "@webassemblyjs/leb128": 1.9.0 - "@webassemblyjs/utf8": 1.9.0 - checksum: 2456e84e8e6bedb7ab47f6333a0ee170f7ef62842c90862ca787c08528ca8041061f3f8bc257fc2a01bf6e8d1a76fddaddd43418c738f681066e5b50f88fe7df + "@xtuc/ieee754": ^1.2.0 + checksum: d7e3520baa37a7309fa7db4d73d69fb869878853b1ebd4b168821bd03fcc4c0e1669c06231315b0039035d9a7a462e53de3ad982da4a426a4b0743b5888e8673 languageName: node linkType: hard -"@webassemblyjs/wasm-opt@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/wasm-opt@npm:1.9.0" +"@webassemblyjs/leb128@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/leb128@npm:1.13.2" dependencies: - "@webassemblyjs/ast": 1.9.0 - "@webassemblyjs/helper-buffer": 1.9.0 - "@webassemblyjs/wasm-gen": 1.9.0 - "@webassemblyjs/wasm-parser": 1.9.0 - checksum: 91242205bdbd1aa8045364a5338bfb34880cb2c65f56db8dd19382894209673699fb31a0e5279f25c7e5bcd8f3097d6c9ca84d8969d9613ef2cf166450cc3515 + "@xtuc/long": 4.2.2 + checksum: 64083507f7cff477a6d71a9e325d95665cea78ec8df99ca7c050e1cfbe300fbcf0842ca3dcf3b4fa55028350135588a4f879398d3dd2b6a8de9913ce7faf5333 languageName: node linkType: hard -"@webassemblyjs/wasm-parser@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/wasm-parser@npm:1.9.0" +"@webassemblyjs/utf8@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/utf8@npm:1.13.2" + checksum: 95ec6052f30eefa8d50c9b2a3394d08b17d53a4aa52821451d41d774c126fa8f39b988fbf5bff56da86852a87c16d676e576775a4071e5e5ccf020cc85a4b281 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-edit@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-edit@npm:1.14.1" dependencies: - "@webassemblyjs/ast": 1.9.0 - "@webassemblyjs/helper-api-error": 1.9.0 - "@webassemblyjs/helper-wasm-bytecode": 1.9.0 - "@webassemblyjs/ieee754": 1.9.0 - "@webassemblyjs/leb128": 1.9.0 - "@webassemblyjs/utf8": 1.9.0 - checksum: 493f6cfc63a5e16073056c81ff0526a9936f461327379ef3c83cc841000e03623b6352704f6bf9f7cb5b3610f0032020a61f9cca78c91b15b8e995854b29c098 + "@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 + checksum: 9341c3146bb1b7863f03d6050c2a66990f20384ca137388047bbe1feffacb599e94fca7b7c18287d17e2449ffb4005fdc7f41f674a6975af9ad8522756f8ffff languageName: node linkType: hard -"@webassemblyjs/wast-parser@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/wast-parser@npm:1.9.0" +"@webassemblyjs/wasm-gen@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-gen@npm:1.14.1" dependencies: - "@webassemblyjs/ast": 1.9.0 - "@webassemblyjs/floating-point-hex-parser": 1.9.0 - "@webassemblyjs/helper-api-error": 1.9.0 - "@webassemblyjs/helper-code-frame": 1.9.0 - "@webassemblyjs/helper-fsm": 1.9.0 - "@xtuc/long": 4.2.2 - checksum: 705dd48fbbceec7f6bed299b8813631b242fd9312f9594dbb2985dda86c9688048692357d684f6080fc2c5666287cefaa26b263d01abadb6a9049d4c8978b9db + "@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 + checksum: 401b12bec7431c4fc29d9414bbe40d3c6dc5be04d25a116657c42329f5481f0129f3b5834c293f26f0e42681ceac9157bf078ce9bdb6a7f78037c650373f98b2 languageName: node linkType: hard -"@webassemblyjs/wast-printer@npm:1.9.0": - version: 1.9.0 - resolution: "@webassemblyjs/wast-printer@npm:1.9.0" +"@webassemblyjs/wasm-opt@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-opt@npm:1.14.1" dependencies: - "@webassemblyjs/ast": 1.9.0 - "@webassemblyjs/wast-parser": 1.9.0 - "@xtuc/long": 4.2.2 - checksum: 3d1e1b2e84745a963f69acd1c02425b321dd2e608e11dabc467cae0c9a808962bc769ec9afc46fbcea7188cc1e47d72370da762d258f716fb367cb1a7865c54b + "@webassemblyjs/ast": 1.14.1 + "@webassemblyjs/helper-buffer": 1.14.1 + "@webassemblyjs/wasm-gen": 1.14.1 + "@webassemblyjs/wasm-parser": 1.14.1 + checksum: 60c697a9e9129d8d23573856df0791ba33cea4a3bc2339044cae73128c0983802e5e50a42157b990eeafe1237eb8e7653db6de5f02b54a0ae7b81b02dcdf2ae9 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-parser@npm:1.14.1" + 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 + checksum: 93f1fe2676da465b4e824419d9812a3d7218de4c3addd4e916c04bc86055fa134416c1b67e4b7cbde8d728c0dce2721d06cc0bfe7a7db7c093a0898009937405 languageName: node linkType: hard -"@xmldom/xmldom@npm:^0.8.3": - version: 0.8.10 - resolution: "@xmldom/xmldom@npm:0.8.10" - checksum: 4c136aec31fb3b49aaa53b6fcbfe524d02a1dc0d8e17ee35bd3bf35e9ce1344560481cd1efd086ad1a4821541482528672306d5e37cdbd187f33d7fadd3e2cf0 +"@webassemblyjs/wast-printer@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wast-printer@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": 1.14.1 + "@xtuc/long": 4.2.2 + checksum: 517881a0554debe6945de719d100b2d8883a2d24ddf47552cdeda866341e2bb153cd824a864bc7e2a61190a4b66b18f9899907e0074e9e820d2912ac0789ea60 languageName: node linkType: hard @@ -4521,13 +7077,6 @@ __metadata: languageName: node linkType: hard -"@zxing/text-encoding@npm:0.9.0": - version: 0.9.0 - resolution: "@zxing/text-encoding@npm:0.9.0" - checksum: c23b12aee7639382e4949961304a1294776afaffa40f579e09ffecd0e5e68cf26ef3edd75009de46da8a536e571448755ca68b3e2ea707d53793c0edb2e2c34a - languageName: node - linkType: hard - "abab@npm:^2.0.3, abab@npm:^2.0.5": version: 2.0.6 resolution: "abab@npm:2.0.6" @@ -4535,21 +7084,24 @@ __metadata: languageName: node linkType: hard -"abbrev@npm:1": - version: 1.1.1 - resolution: "abbrev@npm:1.1.1" - checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17 +"abbrev@npm:^3.0.0": + version: 3.0.1 + resolution: "abbrev@npm:3.0.1" + checksum: e70b209f5f408dd3a3bbd0eec4b10a2ffd64704a4a3821d0969d84928cc490a8eb60f85b78a95622c1841113edac10161c62e52f5e7d0027aa26786a8136e02e languageName: node linkType: hard -"abbrev@npm:^2.0.0": +"accepts@npm:^2.0.0": version: 2.0.0 - resolution: "abbrev@npm:2.0.0" - checksum: 0e994ad2aa6575f94670d8a2149afe94465de9cedaaaac364e7fb43a40c3691c980ff74899f682f4ca58fa96b4cbd7421a015d3a6defe43a442117d7821a2f36 + resolution: "accepts@npm:2.0.0" + dependencies: + mime-types: ^3.0.0 + negotiator: ^1.0.0 + checksum: 49fe6c050cb6f6ff4e771b4d88324fca4d3127865f2473872e818dca127d809ba3aa8fdfc7acb51dd3c5bade7311ca6b8cfff7015ea6db2f7eb9c8444d223a4f languageName: node linkType: hard -"accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": +"accepts@npm:~1.3.4, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -4569,7 +7121,16 @@ __metadata: languageName: node linkType: hard -"acorn-jsx@npm:^5.3.1": +"acorn-import-phases@npm:^1.0.3": + version: 1.0.4 + resolution: "acorn-import-phases@npm:1.0.4" + peerDependencies: + acorn: ^8.14.0 + checksum: e669cccfb6711af305150fcbfddcf4485fffdc4547a0ecabebe94103b47124cc02bfd186240061c00ac954cfb0461b4ecc3e203e138e43042b7af32063fa9510 + languageName: node + linkType: hard + +"acorn-jsx@npm:^5.3.1, acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" peerDependencies: @@ -4585,23 +7146,16 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.2.0": - version: 8.3.2 - resolution: "acorn-walk@npm:8.3.2" - checksum: 3626b9d26a37b1b427796feaa5261faf712307a8920392c8dce9a5739fb31077667f4ad2ec71c7ac6aaf9f61f04a9d3d67ff56f459587206fc04aa31c27ef392 - languageName: node - linkType: hard - -"acorn@npm:^6.4.1": - version: 6.4.2 - resolution: "acorn@npm:6.4.2" - bin: - acorn: bin/acorn - checksum: 44b07053729db7f44d28343eed32247ed56dc4a6ec6dff2b743141ecd6b861406bbc1c20bf9d4f143ea7dd08add5dc8c290582756539bc03a8db605050ce2fb4 +"acorn-walk@npm:^8.1.1": + version: 8.3.4 + resolution: "acorn-walk@npm:8.3.4" + dependencies: + acorn: ^8.11.0 + checksum: 4ff03f42323e7cf90f1683e08606b0f460e1e6ac263d2730e3df91c7665b6f64e696db6ea27ee4bed18c2599569be61f28a8399fa170c611161a348c402ca19c languageName: node linkType: hard -"acorn@npm:^7.1.0, acorn@npm:^7.1.1, acorn@npm:^7.4.0": +"acorn@npm:^7.1.1, acorn@npm:^7.4.0": version: 7.4.1 resolution: "acorn@npm:7.4.1" bin: @@ -4610,36 +7164,29 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.10.0, acorn@npm:^8.11.3, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.5.0, acorn@npm:^8.8.2, acorn@npm:^8.9.0": - version: 8.11.3 - resolution: "acorn@npm:8.11.3" +"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.9.0": + version: 8.15.0 + resolution: "acorn@npm:8.15.0" bin: acorn: bin/acorn - checksum: 76d8e7d559512566b43ab4aadc374f11f563f0a9e21626dd59cb2888444e9445923ae9f3699972767f18af61df89cd89f5eaaf772d1327b055b45cb829b4a88c - languageName: node - linkType: hard - -"address@npm:1.1.2": - version: 1.1.2 - resolution: "address@npm:1.1.2" - checksum: d966deee6ab9a0f96ed1d25dc73e91a248f64479c91f9daeb15237b8e3c39a02faac4e6afe8987ef9e5aea60a1593cef5882b7456ab2e6196fc0229a93ec39c2 + checksum: 309c6b49aedf1a2e34aaf266de06de04aab6eb097c02375c66fdeb0f64556a6a823540409914fb364d9a11bc30d79d485a2eba29af47992d3490e9886c4391c3 languageName: node linkType: hard -"address@npm:^1.0.1": +"address@npm:^1.0.1, address@npm:^1.1.2": version: 1.2.2 resolution: "address@npm:1.2.2" checksum: ace439960c1e3564d8f523aff23a841904bf33a2a7c2e064f7f60a064194075758b9690e65bd9785692a4ef698a998c57eb74d145881a1cecab8ba658ddb1607 languageName: node linkType: hard -"adjust-sourcemap-loader@npm:3.0.0": - version: 3.0.0 - resolution: "adjust-sourcemap-loader@npm:3.0.0" +"adjust-sourcemap-loader@npm:^4.0.0": + version: 4.0.0 + resolution: "adjust-sourcemap-loader@npm:4.0.0" dependencies: loader-utils: ^2.0.0 regex-parser: ^2.2.11 - checksum: 5ceabea85219fcafed06f7d1aafb37dc761c6435e4ded2a8c6b01c69844250aa94ef65a4d07210dc7566c2d8b4c9ba8897518db596a550461eed26fbeb76b96f + checksum: d524ae23582f41e2275af5d88faab7a9dc09770ed588244e0a76d3196d0d6a90bf02760c71bc6213dbfef3aef4a86232ac9521bfd629752c32b7af37bc74c660 languageName: node linkType: hard @@ -4652,35 +7199,28 @@ __metadata: languageName: node linkType: hard -"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": - version: 7.1.1 - resolution: "agent-base@npm:7.1.1" - dependencies: - debug: ^4.3.4 - checksum: 51c158769c5c051482f9ca2e6e1ec085ac72b5a418a9b31b4e82fe6c0a6699adb94c1c42d246699a587b3335215037091c79e0de512c516f73b6ea844202f037 +"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": + version: 7.1.4 + resolution: "agent-base@npm:7.1.4" + checksum: 86a7f542af277cfbd77dd61e7df8422f90bac512953709003a1c530171a9d019d072e2400eab2b59f84b49ab9dd237be44315ca663ac73e82b3922d10ea5eafa languageName: node linkType: hard -"aggregate-error@npm:^3.0.0": - version: 3.1.0 - resolution: "aggregate-error@npm:3.1.0" +"ajv-formats@npm:^2.1.1": + version: 2.1.1 + resolution: "ajv-formats@npm:2.1.1" dependencies: - clean-stack: ^2.0.0 - indent-string: ^4.0.0 - checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 - languageName: node - linkType: hard - -"ajv-errors@npm:^1.0.0": - version: 1.0.1 - resolution: "ajv-errors@npm:1.0.1" + ajv: ^8.0.0 peerDependencies: - ajv: ">=5.0.0" - checksum: 2c9fc02cf58f9aae5bace61ebd1b162e1ea372ae9db5999243ba5e32a9a78c0d635d29ae085f652c61c941a43af0b2b1acdb255e29d44dc43a6e021085716d8c + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 4a287d937f1ebaad4683249a4c40c0fa3beed30d9ddc0adba04859026a622da0d317851316ea64b3680dc60f5c3c708105ddd5d5db8fe595d9d0207fd19f90b7 languageName: node linkType: hard -"ajv-keywords@npm:^3.1.0, ajv-keywords@npm:^3.4.1, ajv-keywords@npm:^3.5.2": +"ajv-keywords@npm:^3.4.1, ajv-keywords@npm:^3.5.2": version: 3.5.2 resolution: "ajv-keywords@npm:3.5.2" peerDependencies: @@ -4689,7 +7229,18 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.1.0, ajv@npm:^6.10.0, ajv@npm:^6.10.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5": +"ajv-keywords@npm:^5.1.0": + version: 5.1.0 + resolution: "ajv-keywords@npm:5.1.0" + dependencies: + fast-deep-equal: ^3.1.3 + peerDependencies: + ajv: ^8.8.2 + checksum: c35193940b853119242c6757787f09ecf89a2c19bcd36d03ed1a615e710d19d450cb448bfda407b939aba54b002368c8bff30529cc50a0536a8e10bcce300421 + languageName: node + linkType: hard + +"ajv@npm:^6.10.0, ajv@npm:^6.12.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -4701,29 +7252,15 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.1": - version: 8.12.0 - resolution: "ajv@npm:8.12.0" +"ajv@npm:^8.0.0, ajv@npm:^8.0.1, ajv@npm:^8.6.0, ajv@npm:^8.9.0": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" dependencies: - fast-deep-equal: ^3.1.1 + fast-deep-equal: ^3.1.3 + fast-uri: ^3.0.1 json-schema-traverse: ^1.0.0 require-from-string: ^2.0.2 - uri-js: ^4.2.2 - checksum: 4dc13714e316e67537c8b31bc063f99a1d9d9a497eb4bbd55191ac0dcd5e4985bbb71570352ad6f1e76684fb6d790928f96ba3b2d4fd6e10024be9612fe3f001 - languageName: node - linkType: hard - -"alphanum-sort@npm:^1.0.0": - version: 1.0.2 - resolution: "alphanum-sort@npm:1.0.2" - checksum: 5a32d0b3c0944e65d22ff3ae2f88d7a4f8d88a78a703033caeae33f2944915e053d283d02f630dc94823edc7757148ecdcf39fd687a5117bda5c10133a03a7d8 - languageName: node - linkType: hard - -"ansi-colors@npm:^3.0.0": - version: 3.2.4 - resolution: "ansi-colors@npm:3.2.4" - checksum: 026c51880e9f8eb59b112669a87dbea4469939ff94b131606303bbd697438a6691b16b9db3027aa9bf132a244214e83ab1508b998496a34d2aea5b437ac9e62d + checksum: 1797bf242cfffbaf3b870d13565bd1716b73f214bb7ada9a497063aada210200da36e3ed40237285f3255acc4feeae91b1fb183625331bad27da95973f7253d9 languageName: node linkType: hard @@ -4743,30 +7280,25 @@ __metadata: languageName: node linkType: hard -"ansi-html@npm:0.0.7, ansi-html@npm:^0.0.7": - version: 0.0.7 - resolution: "ansi-html@npm:0.0.7" +"ansi-html-community@npm:^0.0.8": + version: 0.0.8 + resolution: "ansi-html-community@npm:0.0.8" bin: - ansi-html: ./bin/ansi-html - checksum: 9b839ce99650b4c2d83621d67d68622d27e7948b54f7a4386f2218a3997ee4e684e5a6e8d290880c3f3260e8d90c2613c59c7028f04992ad5c8d99d3a0fcc02c - languageName: node - linkType: hard - -"ansi-regex@npm:^2.0.0": - version: 2.1.1 - resolution: "ansi-regex@npm:2.1.1" - checksum: 190abd03e4ff86794f338a31795d262c1dfe8c91f7e01d04f13f646f1dcb16c5800818f886047876f1272f065570ab86b24b99089f8b68a0e11ff19aed4ca8f1 + ansi-html: bin/ansi-html + checksum: 04c568e8348a636963f915e48eaa3e01218322e1169acafdd79c384f22e5558c003f79bbc480c1563865497482817c7eed025f0653ebc17642fededa5cb42089 languageName: node linkType: hard -"ansi-regex@npm:^4.1.0": - version: 4.1.1 - resolution: "ansi-regex@npm:4.1.1" - checksum: b1a6ee44cb6ecdabaa770b2ed500542714d4395d71c7e5c25baa631f680fb2ad322eb9ba697548d498a6fd366949fc8b5bfcf48d49a32803611f648005b01888 +"ansi-html@npm:^0.0.9": + version: 0.0.9 + resolution: "ansi-html@npm:0.0.9" + bin: + ansi-html: bin/ansi-html + checksum: a03754d6f66bae33938ed8bb3dd98174b7f4895ebe45226185036ed4a1388a7aaf2f2b9581608f0626432ba7add92cfc590aa6475a78bbb90d9d1e1d1af8cbe6 languageName: node linkType: hard -"ansi-regex@npm:^5.0.0, ansi-regex@npm:^5.0.1": +"ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b @@ -4774,20 +7306,13 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.0.1 - resolution: "ansi-regex@npm:6.0.1" - checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 - languageName: node - linkType: hard - -"ansi-styles@npm:^2.2.1": - version: 2.2.1 - resolution: "ansi-styles@npm:2.2.1" - checksum: ebc0e00381f2a29000d1dac8466a640ce11943cef3bda3cd0020dc042e31e1058ab59bf6169cd794a54c3a7338a61ebc404b7c91e004092dd20e028c432c9c2c + version: 6.2.2 + resolution: "ansi-regex@npm:6.2.2" + checksum: 9b17ce2c6daecc75bcd5966b9ad672c23b184dc3ed9bf3c98a0702f0d2f736c15c10d461913568f2cf527a5e64291c7473358885dd493305c84a1cfed66ba94f languageName: node linkType: hard -"ansi-styles@npm:^3.2.0, ansi-styles@npm:^3.2.1": +"ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" dependencies: @@ -4813,23 +7338,20 @@ __metadata: linkType: hard "ansi-styles@npm:^6.1.0": - version: 6.2.1 - resolution: "ansi-styles@npm:6.2.1" - checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 + version: 6.2.3 + resolution: "ansi-styles@npm:6.2.3" + checksum: f1b0829cf048cce870a305819f65ce2adcebc097b6d6479e12e955fd6225df9b9eb8b497083b764df796d94383ff20016cc4dbbae5b40f36138fb65a9d33c2e2 languageName: node linkType: hard -"anymatch@npm:^2.0.0": - version: 2.0.0 - resolution: "anymatch@npm:2.0.0" - dependencies: - micromatch: ^3.1.4 - normalize-path: ^2.1.1 - checksum: f7bb1929842b4585cdc28edbb385767d499ce7d673f96a8f11348d2b2904592ffffc594fe9229b9a1e9e4dccb9329b7692f9f45e6a11dcefbb76ecdc9ab740f6 +"any-promise@npm:^1.0.0": + version: 1.3.0 + resolution: "any-promise@npm:1.3.0" + checksum: 0ee8a9bdbe882c90464d75d1f55cf027f5458650c4bd1f0467e65aec38ccccda07ca5844969ee77ed46d04e7dded3eaceb027e8d32f385688523fe305fa7e1de languageName: node linkType: hard -"anymatch@npm:^3.0.0, anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": +"anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" dependencies: @@ -4846,13 +7368,6 @@ __metadata: languageName: node linkType: hard -"aproba@npm:^1.1.1": - version: 1.2.0 - resolution: "aproba@npm:1.2.0" - checksum: 0fca141966559d195072ed047658b6e6c4fe92428c385dd38e288eacfc55807e7b4989322f030faff32c0f46bb0bc10f1e0ac32ec22d25315a1e5bbc0ebb76dc - languageName: node - linkType: hard - "arg@npm:^4.1.0": version: 4.1.3 resolution: "arg@npm:4.1.3" @@ -4860,6 +7375,13 @@ __metadata: languageName: node linkType: hard +"arg@npm:^5.0.2": + version: 5.0.2 + resolution: "arg@npm:5.0.2" + checksum: 6c69ada1a9943d332d9e5382393e897c500908d91d5cb735a01120d5f71daf1b339b7b8980cbeaba8fd1afc68e658a739746179e4315a26e8a28951ff9930078 + languageName: node + linkType: hard + "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10" @@ -4868,27 +7390,15 @@ __metadata: checksum: 7ca6e45583a28de7258e39e13d81e925cfa25d7d4aacbf806a382d3c02fcb13403a07fb8aeef949f10a7cfe4a62da0e2e807b348a5980554cc28ee573ef95945 languageName: node linkType: hard - -"aria-query@npm:5.1.3": - version: 5.1.3 - resolution: "aria-query@npm:5.1.3" - dependencies: - deep-equal: ^2.0.5 - checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b - languageName: node - linkType: hard - -"aria-query@npm:^4.2.2": - version: 4.2.2 - resolution: "aria-query@npm:4.2.2" - dependencies: - "@babel/runtime": ^7.10.2 - "@babel/runtime-corejs3": ^7.10.2 - checksum: 38401a9a400f26f3dcc24b84997461a16b32869a9893d323602bed8da40a8bcc0243b8d2880e942249a1496cea7a7de769e93d21c0baa439f01e1ee936fed665 + +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced languageName: node linkType: hard -"aria-query@npm:^5.0.0, aria-query@npm:^5.3.0": +"aria-query@npm:5.3.0": version: 5.3.0 resolution: "aria-query@npm:5.3.0" dependencies: @@ -4897,41 +7407,20 @@ __metadata: languageName: node linkType: hard -"arity-n@npm:^1.0.4": - version: 1.0.4 - resolution: "arity-n@npm:1.0.4" - checksum: 3d76e16907f7b8a9452690c1efc301d0fbecea457365797eccfbade9b8d1653175b2c38343201bf26fdcbf0bcbb31eab6d912e7c008c6d19042301dc0be80a73 - languageName: node - linkType: hard - -"arr-diff@npm:^4.0.0": - version: 4.0.0 - resolution: "arr-diff@npm:4.0.0" - checksum: ea7c8834842ad3869297f7915689bef3494fd5b102ac678c13ffccab672d3d1f35802b79e90c4cfec2f424af3392e44112d1ccf65da34562ed75e049597276a0 - languageName: node - linkType: hard - -"arr-flatten@npm:^1.1.0": - version: 1.1.0 - resolution: "arr-flatten@npm:1.1.0" - checksum: 963fe12564fca2f72c055f3f6c206b9e031f7c433a0c66ca9858b484821f248c5b1e5d53c8e4989d80d764cd776cf6d9b160ad05f47bdc63022bfd63b5455e22 - languageName: node - linkType: hard - -"arr-union@npm:^3.1.0": - version: 3.1.0 - resolution: "arr-union@npm:3.1.0" - checksum: b5b0408c6eb7591143c394f3be082fee690ddd21f0fdde0a0a01106799e847f67fcae1b7e56b0a0c173290e29c6aca9562e82b300708a268bc8f88f3d6613cb9 +"aria-query@npm:^5.0.0, aria-query@npm:^5.3.2": + version: 5.3.2 + resolution: "aria-query@npm:5.3.2" + checksum: d971175c85c10df0f6d14adfe6f1292409196114ab3c62f238e208b53103686f46cc70695a4f775b73bc65f6a09b6a092fd963c4f3a5a7d690c8fc5094925717 languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.0, array-buffer-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "array-buffer-byte-length@npm:1.0.1" +"array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "array-buffer-byte-length@npm:1.0.2" dependencies: - call-bind: ^1.0.5 - is-array-buffer: ^3.0.4 - checksum: 53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e + call-bound: ^1.0.3 + is-array-buffer: ^3.0.5 + checksum: 0ae3786195c3211b423e5be8dd93357870e6fb66357d81da968c2c39ef43583ef6eece1f9cb1caccdae4806739c65dea832b44b8593414313cd76a89795fca63 languageName: node linkType: hard @@ -4942,33 +7431,19 @@ __metadata: languageName: node linkType: hard -"array-flatten@npm:^2.1.0": - version: 2.1.2 - resolution: "array-flatten@npm:2.1.2" - checksum: e8988aac1fbfcdaae343d08c9a06a6fddd2c6141721eeeea45c3cf523bf4431d29a46602929455ed548c7a3e0769928cdc630405427297e7081bd118fdec9262 - languageName: node - linkType: hard - -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.7": - version: 3.1.8 - resolution: "array-includes@npm:3.1.8" +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8, array-includes@npm:^3.1.9": + version: 3.1.9 + resolution: "array-includes@npm:3.1.9" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.4 define-properties: ^1.2.1 - es-abstract: ^1.23.2 - es-object-atoms: ^1.0.0 - get-intrinsic: ^1.2.4 - is-string: ^1.0.7 - checksum: eb39ba5530f64e4d8acab39297c11c1c5be2a4ea188ab2b34aba5fb7224d918f77717a9d57a3e2900caaa8440e59431bdaf5c974d5212ef65d97f132e38e2d91 - languageName: node - linkType: hard - -"array-union@npm:^1.0.1": - version: 1.0.2 - resolution: "array-union@npm:1.0.2" - dependencies: - array-uniq: ^1.0.1 - checksum: 82cec6421b6e6766556c484835a6d476a873f1b71cace5ab2b4f1b15b1e3162dc4da0d16f7a2b04d4aec18146c6638fe8f661340b31ba8e469fd811a1b45dc8d + es-abstract: ^1.24.0 + es-object-atoms: ^1.1.1 + get-intrinsic: ^1.3.0 + is-string: ^1.1.1 + math-intrinsics: ^1.1.0 + checksum: b58dc526fe415252e50319eaf88336e06e75aa673e3b58d252414739a4612dbe56e7b613fdcc7c90561dc9cf9202bbe5ca029ccd8c08362746459475ae5a8f3e languageName: node linkType: hard @@ -4979,21 +7454,7 @@ __metadata: languageName: node linkType: hard -"array-uniq@npm:^1.0.1": - version: 1.0.3 - resolution: "array-uniq@npm:1.0.3" - checksum: 1625f06b093d8bf279b81adfec6e72951c0857d65b5e3f65f053fffe9f9dd61c2fc52cff57e38a4700817e7e3f01a4faa433d505ea9e33cdae4514c334e0bf9e - languageName: node - linkType: hard - -"array-unique@npm:^0.3.2": - version: 0.3.2 - resolution: "array-unique@npm:0.3.2" - checksum: da344b89cfa6b0a5c221f965c21638bfb76b57b45184a01135382186924f55973cd9b171d4dad6bf606c6d9d36b0d721d091afdc9791535ead97ccbe78f8a888 - languageName: node - linkType: hard - -"array.prototype.findlast@npm:^1.2.4": +"array.prototype.findlast@npm:^1.2.5": version: 1.2.5 resolution: "array.prototype.findlast@npm:1.2.5" dependencies: @@ -5007,101 +7468,90 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.3": - version: 1.2.5 - resolution: "array.prototype.findlastindex@npm:1.2.5" +"array.prototype.findlastindex@npm:^1.2.6": + version: 1.2.6 + resolution: "array.prototype.findlastindex@npm:1.2.6" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.4 define-properties: ^1.2.1 - es-abstract: ^1.23.2 + es-abstract: ^1.23.9 es-errors: ^1.3.0 - es-object-atoms: ^1.0.0 - es-shim-unscopables: ^1.0.2 - checksum: 2c81cff2a75deb95bf1ed89b6f5f2bfbfb882211e3b7cc59c3d6b87df774cd9d6b36949a8ae39ac476e092c1d4a4905f5ee11a86a456abb10f35f8211ae4e710 + es-object-atoms: ^1.1.1 + es-shim-unscopables: ^1.1.0 + checksum: bd2665bd51f674d4e1588ce5d5848a8adb255f414070e8e652585598b801480516df2c6cef2c60b6ea1a9189140411c49157a3f112d52e9eabb4e9fc80936ea6 languageName: node linkType: hard -"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flat@npm:1.3.2" +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.3": + version: 1.3.3 + resolution: "array.prototype.flat@npm:1.3.3" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-shim-unscopables: ^1.0.0 - checksum: 5d6b4bf102065fb3f43764bfff6feb3295d372ce89591e6005df3d0ce388527a9f03c909af6f2a973969a4d178ab232ffc9236654149173e0e187ec3a1a6b87b + call-bind: ^1.0.8 + define-properties: ^1.2.1 + es-abstract: ^1.23.5 + es-shim-unscopables: ^1.0.2 + checksum: 5d5a7829ab2bb271a8d30a1c91e6271cef0ec534593c0fe6d2fb9ebf8bb62c1e5326e2fddcbbcbbe5872ca04f5e6b54a1ecf092e0af704fb538da9b2bfd95b40 languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flatmap@npm:1.3.2" +"array.prototype.flatmap@npm:^1.3.2, array.prototype.flatmap@npm:^1.3.3": + version: 1.3.3 + resolution: "array.prototype.flatmap@npm:1.3.3" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-shim-unscopables: ^1.0.0 - checksum: ce09fe21dc0bcd4f30271f8144083aa8c13d4639074d6c8dc82054b847c7fc9a0c97f857491f4da19d4003e507172a78f4bcd12903098adac8b9cd374f734be3 + call-bind: ^1.0.8 + define-properties: ^1.2.1 + es-abstract: ^1.23.5 + es-shim-unscopables: ^1.0.2 + checksum: 11b4de09b1cf008be6031bb507d997ad6f1892e57dc9153583de6ebca0f74ea403fffe0f203461d359de05048d609f3f480d9b46fed4099652d8b62cc972f284 languageName: node linkType: hard "array.prototype.reduce@npm:^1.0.6": - version: 1.0.7 - resolution: "array.prototype.reduce@npm:1.0.7" + version: 1.0.8 + resolution: "array.prototype.reduce@npm:1.0.8" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.4 define-properties: ^1.2.1 - es-abstract: ^1.23.2 + es-abstract: ^1.23.9 es-array-method-boxes-properly: ^1.0.0 es-errors: ^1.3.0 - es-object-atoms: ^1.0.0 - is-string: ^1.0.7 - checksum: 90303617bd70c8e9a81ebff041d3e10fad1a97f163699cb015b7c84a3f9e6960d9bb161a30f1d0309d6e476f166af5668c1e24f7add3202213d25f7c7f15475d - languageName: node - linkType: hard - -"array.prototype.toreversed@npm:^1.1.2": - version: 1.1.2 - resolution: "array.prototype.toreversed@npm:1.1.2" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-shim-unscopables: ^1.0.0 - checksum: 58598193426282155297bedf950dc8d464624a0d81659822fb73124286688644cb7e0e4927a07f3ab2daaeb6617b647736cc3a5e6ca7ade5bb8e573b284e6240 + es-object-atoms: ^1.1.1 + is-string: ^1.1.1 + checksum: a2a25e087a75e4caae09414acdfffb6ed69f7dd696d8c612d86dfaa5590bde4d7bc934db8bdd28625703f574aa93731848bfc24a7ba65c558aeb222b2a4fd4c4 languageName: node linkType: hard -"array.prototype.tosorted@npm:^1.1.3": - version: 1.1.3 - resolution: "array.prototype.tosorted@npm:1.1.3" +"array.prototype.tosorted@npm:^1.1.4": + version: 1.1.4 + resolution: "array.prototype.tosorted@npm:1.1.4" dependencies: - call-bind: ^1.0.5 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.22.3 - es-errors: ^1.1.0 + es-abstract: ^1.23.3 + es-errors: ^1.3.0 es-shim-unscopables: ^1.0.2 - checksum: 555e8808086bbde9e634c5dc5a8c0a2f1773075447b43b2fa76ab4f94f4e90f416d2a4f881024e1ce1a2931614caf76cd6b408af901c9d7cd13061d0d268f5af + checksum: e4142d6f556bcbb4f393c02e7dbaea9af8f620c040450c2be137c9cbbd1a17f216b9c688c5f2c08fbb038ab83f55993fa6efdd9a05881d84693c7bcb5422127a languageName: node linkType: hard -"arraybuffer.prototype.slice@npm:^1.0.3": - version: 1.0.3 - resolution: "arraybuffer.prototype.slice@npm:1.0.3" +"arraybuffer.prototype.slice@npm:^1.0.4": + version: 1.0.4 + resolution: "arraybuffer.prototype.slice@npm:1.0.4" dependencies: array-buffer-byte-length: ^1.0.1 - call-bind: ^1.0.5 + call-bind: ^1.0.8 define-properties: ^1.2.1 - es-abstract: ^1.22.3 - es-errors: ^1.2.1 - get-intrinsic: ^1.2.3 + es-abstract: ^1.23.5 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.6 is-array-buffer: ^3.0.4 - is-shared-array-buffer: ^1.0.2 - checksum: 352259cba534dcdd969c92ab002efd2ba5025b2e3b9bead3973150edbdf0696c629d7f4b3f061c5931511e8207bdc2306da614703c820b45dabce39e3daf7e3e + checksum: b1d1fd20be4e972a3779b1569226f6740170dca10f07aa4421d42cefeec61391e79c557cda8e771f5baefe47d878178cd4438f60916ce831813c08132bced765 languageName: node linkType: hard -"arrify@npm:^2.0.0, arrify@npm:^2.0.1": +"arrify@npm:^2.0.0": version: 2.0.1 resolution: "arrify@npm:2.0.1" checksum: 067c4c1afd182806a82e4c1cb8acee16ab8b5284fbca1ce29408e6e91281c36bb5b612f6ddfbd40a0f7a7e0c75bf2696eb94c027f6e328d6e9c52465c98e4209 @@ -5115,38 +7565,10 @@ __metadata: languageName: node linkType: hard -"asn1.js@npm:^4.10.1": - version: 4.10.1 - resolution: "asn1.js@npm:4.10.1" - dependencies: - bn.js: ^4.0.0 - inherits: ^2.0.1 - minimalistic-assert: ^1.0.0 - checksum: 9289a1a55401238755e3142511d7b8f6fc32f08c86ff68bd7100da8b6c186179dd6b14234fba2f7f6099afcd6758a816708485efe44bc5b2a6ec87d9ceeddbb5 - languageName: node - linkType: hard - -"assert@npm:^1.1.1": - version: 1.5.1 - resolution: "assert@npm:1.5.1" - dependencies: - object.assign: ^4.1.4 - util: ^0.10.4 - checksum: bfc539da97545f9b2989395d6b85be40b70649ce57464f3cc6e61f4975fb097ba0689c386f95bdb4c3ab867931e40a565c9e193ae3c02263a8e92acb17c9dc93 - languageName: node - linkType: hard - -"assertion-error@npm:^1.1.0": - version: 1.1.0 - resolution: "assertion-error@npm:1.1.0" - checksum: fd9429d3a3d4fd61782eb3962ae76b6d08aa7383123fca0596020013b3ebd6647891a85b05ce821c47d1471ed1271f00b0545cf6a4326cf2fc91efcc3b0fbecf - languageName: node - linkType: hard - -"assign-symbols@npm:^1.0.0": - version: 1.0.0 - resolution: "assign-symbols@npm:1.0.0" - checksum: c0eb895911d05b6b2d245154f70461c5e42c107457972e5ebba38d48967870dee53bcdf6c7047990586daa80fab8dab3cc6300800fbd47b454247fdedd859a2c +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: a0789dd882211b87116e81e2648ccb7f60340b34f19877dd020b39ebb4714e475eb943e14ba3e22201c221ef6645b7bfe10297e76b6ac95b48a9898c1211ce66 languageName: node linkType: hard @@ -5164,26 +7586,17 @@ __metadata: languageName: node linkType: hard -"async-each@npm:^1.0.1": - version: 1.0.6 - resolution: "async-each@npm:1.0.6" - checksum: d237e8c39348d5f1441edbd3893692912afbacaf83a2ccce8978ebeea804529a8838654b12208fbbc08c8b0411a1248948ee9bf9291ebe1921aabd5b613bc5db - languageName: node - linkType: hard - -"async-limiter@npm:~1.0.0": - version: 1.0.1 - resolution: "async-limiter@npm:1.0.1" - checksum: 2b849695b465d93ad44c116220dee29a5aeb63adac16c1088983c339b0de57d76e82533e8e364a93a9f997f28bbfc6a92948cefc120652bd07f3b59f8d75cf2b +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 9102e246d1ed9b37ac36f57f0a6ca55226876553251a31fc80677e71471f463a54c872dc78d5d7f80740c8ba624395cccbe8b60f7b690c4418f487d8e9fd1106 languageName: node linkType: hard -"async@npm:^2.6.4": - version: 2.6.4 - resolution: "async@npm:2.6.4" - dependencies: - lodash: ^4.17.14 - checksum: a52083fb32e1ebe1d63e5c5624038bb30be68ff07a6c8d7dfe35e47c93fc144bd8652cbec869e0ac07d57dde387aa5f1386be3559cdee799cb1f789678d88e19 +"async@npm:^3.2.6": + version: 3.2.6 + resolution: "async@npm:3.2.6" + checksum: ee6eb8cd8a0ab1b58bd2a3ed6c415e93e773573a91d31df9d5ef559baafa9dab37d3b096fa7993e84585cac3697b2af6ddb9086f45d3ac8cae821bb2aab65682 languageName: node linkType: hard @@ -5201,29 +7614,21 @@ __metadata: languageName: node linkType: hard -"atob@npm:^2.1.2": - version: 2.1.2 - resolution: "atob@npm:2.1.2" - bin: - atob: bin/atob.js - checksum: dfeeeb70090c5ebea7be4b9f787f866686c645d9f39a0d184c817252d0cf08455ed25267d79c03254d3be1f03ac399992a792edcd5ffb9c91e097ab5ef42833a - languageName: node - linkType: hard - -"autoprefixer@npm:^9.6.1": - version: 9.8.8 - resolution: "autoprefixer@npm:9.8.8" +"autoprefixer@npm:^10.4.13": + version: 10.4.21 + resolution: "autoprefixer@npm:10.4.21" dependencies: - browserslist: ^4.12.0 - caniuse-lite: ^1.0.30001109 + browserslist: ^4.24.4 + caniuse-lite: ^1.0.30001702 + fraction.js: ^4.3.7 normalize-range: ^0.1.2 - num2fraction: ^1.2.2 - picocolors: ^0.2.1 - postcss: ^7.0.32 - postcss-value-parser: ^4.1.0 + picocolors: ^1.1.1 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.1.0 bin: autoprefixer: bin/autoprefixer - checksum: 8f017672fbac248db0cf4e86aa707d8b148d9abadb842b5cf4c6be306d80fa6a654fadefd17e46213234c1f0947612acce2864f93e903f3e736b183fc1aedc45 + checksum: 11770ce635a0520e457eaf2ff89056cd57094796a9f5d6d9375513388a5a016cd947333dcfd213b822fdd8a0b43ce68ae4958e79c6f077c41d87444c8cca0235 languageName: node linkType: hard @@ -5236,103 +7641,65 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:=4.7.0": - version: 4.7.0 - resolution: "axe-core@npm:4.7.0" - checksum: f086bcab42be1761ba2b0b127dec350087f4c3a853bba8dd58f69d898cefaac31a1561da23146f6f3c07954c76171d1f2ce460e555e052d2b02cd79af628fa4a - languageName: node - linkType: hard - -"axios@npm:^0.27.2": - version: 0.27.2 - resolution: "axios@npm:0.27.2" - dependencies: - follow-redirects: ^1.14.9 - form-data: ^4.0.0 - checksum: 38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854 +"axe-core@npm:^4.10.0": + version: 4.10.3 + resolution: "axe-core@npm:4.10.3" + checksum: e89fa5bcad9216f2de29bbdf95d6211d8c5b1025cbdcf56b6695c18b2e9a1eebd0b997a0141334169f6f062fc68fd39a5b97f86348d9f5be05958eade5c1ec78 languageName: node linkType: hard -"axios@npm:^1.6.5": - version: 1.6.8 - resolution: "axios@npm:1.6.8" +"axios@npm:^1.11.0, axios@npm:^1.7.9": + version: 1.12.2 + resolution: "axios@npm:1.12.2" dependencies: follow-redirects: ^1.15.6 - form-data: ^4.0.0 + form-data: ^4.0.4 proxy-from-env: ^1.1.0 - checksum: bf007fa4b207d102459300698620b3b0873503c6d47bf5a8f6e43c0c64c90035a4f698b55027ca1958f61ab43723df2781c38a99711848d232cad7accbcdfcdd - languageName: node - linkType: hard - -"axobject-query@npm:^3.2.1": - version: 3.2.1 - resolution: "axobject-query@npm:3.2.1" - dependencies: - dequal: ^2.0.3 - checksum: a94047e702b57c91680e6a952ec4a1aaa2cfd0d80ead76bc8c954202980d8c51968a6ea18b4d8010e8e2cf95676533d8022a8ebba9abc1dfe25686721df26fd2 - languageName: node - linkType: hard - -"babel-eslint@npm:^10.1.0": - version: 10.1.0 - resolution: "babel-eslint@npm:10.1.0" - dependencies: - "@babel/code-frame": ^7.0.0 - "@babel/parser": ^7.7.0 - "@babel/traverse": ^7.7.0 - "@babel/types": ^7.7.0 - eslint-visitor-keys: ^1.0.0 - resolve: ^1.12.0 - peerDependencies: - eslint: ">= 4.12.1" - checksum: bdc1f62b6b0f9c4d5108c96d835dad0c0066bc45b7c020fcb2d6a08107cf69c9217a99d3438dbd701b2816896190c4283ba04270ed9a8349ee07bd8dafcdc050 + checksum: f0331594fe053a4bbff04104edb073973a3aabfad2e56b0aa18de82428aa63f6f0839ca3d837258ec739cb4528014121793b1649a21e5115ffb2bf8237eadca3 languageName: node linkType: hard -"babel-extract-comments@npm:^1.0.0": - version: 1.0.0 - resolution: "babel-extract-comments@npm:1.0.0" - dependencies: - babylon: ^6.18.0 - checksum: 6345c688ccb56a7b750223afb42c1ddc83865b8ac33d7b808b5ad5e3619624563cf8324fbacdcf41cf073a40d935468a05f806e1a7622b0186fa5dad1232a07b +"axobject-query@npm:^4.1.0": + version: 4.1.0 + resolution: "axobject-query@npm:4.1.0" + checksum: 7d1e87bf0aa7ae7a76cd39ab627b7c48fda3dc40181303d9adce4ba1d5b5ce73b5e5403ee6626ec8e91090448c887294d6144e24b6741a976f5be9347e3ae1df languageName: node linkType: hard -"babel-jest@npm:^26.6.0, babel-jest@npm:^26.6.3": - version: 26.6.3 - resolution: "babel-jest@npm:26.6.3" +"babel-jest@npm:^27.4.2, babel-jest@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-jest@npm:27.5.1" dependencies: - "@jest/transform": ^26.6.2 - "@jest/types": ^26.6.2 - "@types/babel__core": ^7.1.7 - babel-plugin-istanbul: ^6.0.0 - babel-preset-jest: ^26.6.2 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 + "@types/babel__core": ^7.1.14 + babel-plugin-istanbul: ^6.1.1 + babel-preset-jest: ^27.5.1 chalk: ^4.0.0 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 slash: ^3.0.0 peerDependencies: - "@babel/core": ^7.0.0 - checksum: 5917233f0d381e719e195b69b81e46da90293432d10288d79f8f59b8f3f9ac030e14701f3d9f90893fb739481df1d132446f1b983d841e65e2623775db100897 + "@babel/core": ^7.8.0 + checksum: 4e93e6e9fb996cc5f1505e924eb8e8cc7b25c294ba9629762a2715390f48af6a4c14dbb84cd9730013ac0e03267a5a9aa2fb6318c544489cda7f50f4e506def4 languageName: node linkType: hard -"babel-loader@npm:8.1.0": - version: 8.1.0 - resolution: "babel-loader@npm:8.1.0" +"babel-loader@npm:^8.2.3": + version: 8.4.1 + resolution: "babel-loader@npm:8.4.1" dependencies: - find-cache-dir: ^2.1.0 - loader-utils: ^1.4.0 - mkdirp: ^0.5.3 - pify: ^4.0.1 + find-cache-dir: ^3.3.1 + loader-utils: ^2.0.4 + make-dir: ^3.1.0 schema-utils: ^2.6.5 peerDependencies: "@babel/core": ^7.0.0 webpack: ">=2" - checksum: fdbcae91cc43366206320a1cbe40d358a64ba2dfaa561fbd690efe0db6256c9d27ab7600f7c84041fbc4c2a6f0279175b1f8d1fa5ed17ec30bbd734da84a1bc0 + checksum: fa02db1a7d3ebb7b4aab83e926fb51e627a00427943c9dd1b3302c8099c67fa6a242a2adeed37d95abcd39ba619edf558a1dec369ce0849c5a87dc290c90fe2f languageName: node linkType: hard -"babel-plugin-istanbul@npm:^6.0.0": +"babel-plugin-istanbul@npm:^6.1.1": version: 6.1.1 resolution: "babel-plugin-istanbul@npm:6.1.1" dependencies: @@ -5345,15 +7712,15 @@ __metadata: languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:^26.6.2": - version: 26.6.2 - resolution: "babel-plugin-jest-hoist@npm:26.6.2" +"babel-plugin-jest-hoist@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-plugin-jest-hoist@npm:27.5.1" dependencies: "@babel/template": ^7.3.3 "@babel/types": ^7.3.3 "@types/babel__core": ^7.0.0 "@types/babel__traverse": ^7.0.6 - checksum: abe3732fdf20f96e91cbf788a54d776b30bd7a6054cb002a744d7071c656813e26e77a780dc2a6f6b197472897e220836cd907bda3fadb9d0481126bfd6c3783 + checksum: 709c17727aa8fd3be755d256fb514bf945a5c2ea6017f037d80280fc44ae5fe7dfeebf63d8412df53796455c2c216119d628d8cc90b099434fd819005943d058 languageName: node linkType: hard @@ -5368,7 +7735,7 @@ __metadata: languageName: node linkType: hard -"babel-plugin-named-asset-import@npm:^0.3.7": +"babel-plugin-named-asset-import@npm:^0.3.8": version: 0.3.8 resolution: "babel-plugin-named-asset-import@npm:0.3.8" peerDependencies: @@ -5377,56 +7744,39 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs2@npm:^0.4.10": - version: 0.4.11 - resolution: "babel-plugin-polyfill-corejs2@npm:0.4.11" +"babel-plugin-polyfill-corejs2@npm:^0.4.14": + version: 0.4.14 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.14" dependencies: - "@babel/compat-data": ^7.22.6 - "@babel/helper-define-polyfill-provider": ^0.6.2 + "@babel/compat-data": ^7.27.7 + "@babel/helper-define-polyfill-provider": ^0.6.5 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: f098353ce7c7dde1a1d2710858e01b471e85689110c9e37813e009072347eb8c55d5f84d20d3bf1cab31755f20078ba90f8855fdc4686a9daa826a95ff280bd7 + checksum: d654334c1b4390d08282416144b7b6f3d74d2cab44b2bfa2b6405c828882c82907b8b67698dce1be046c218d2d4fe5bf7fb6d01879938f3129dad969e8cfc44d languageName: node linkType: hard -"babel-plugin-polyfill-corejs3@npm:^0.10.1, babel-plugin-polyfill-corejs3@npm:^0.10.4": - version: 0.10.4 - resolution: "babel-plugin-polyfill-corejs3@npm:0.10.4" +"babel-plugin-polyfill-corejs3@npm:^0.13.0": + version: 0.13.0 + resolution: "babel-plugin-polyfill-corejs3@npm:0.13.0" dependencies: - "@babel/helper-define-polyfill-provider": ^0.6.1 - core-js-compat: ^3.36.1 + "@babel/helper-define-polyfill-provider": ^0.6.5 + core-js-compat: ^3.43.0 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: b96a54495f7cc8b3797251c8c15f5ed015edddc3110fc122f6b32c94bec33af1e8bc56fa99091808f500bde0cccaaa266889cdc5935d9e6e9cf09898214f02dd + checksum: cf526031acd97ff2124e7c10e15047e6eeb0620d029c687f1dca99916a8fe6cac0e634b84c913db6cb68b7a024f82492ba8fdcc2a6266e7b05bdac2cba0c2434 languageName: node linkType: hard -"babel-plugin-polyfill-regenerator@npm:^0.6.1": - version: 0.6.2 - resolution: "babel-plugin-polyfill-regenerator@npm:0.6.2" +"babel-plugin-polyfill-regenerator@npm:^0.6.5": + version: 0.6.5 + resolution: "babel-plugin-polyfill-regenerator@npm:0.6.5" dependencies: - "@babel/helper-define-polyfill-provider": ^0.6.2 + "@babel/helper-define-polyfill-provider": ^0.6.5 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 150233571072b6b3dfe946242da39cba8587b7f908d1c006f7545fc88b0e3c3018d445739beb61e7a75835f0c2751dbe884a94ff9b245ec42369d9267e0e1b3f - languageName: node - linkType: hard - -"babel-plugin-syntax-object-rest-spread@npm:^6.8.0": - version: 6.13.0 - resolution: "babel-plugin-syntax-object-rest-spread@npm:6.13.0" - checksum: 14083f2783c760f5f199160f48e42ad4505fd35fc7cf9c4530812b176705259562b77db6d3ddc5e3cbce9e9b2b61ec9db3065941f0949b68e77cae3e395a6eef - languageName: node - linkType: hard - -"babel-plugin-transform-object-rest-spread@npm:^6.26.0": - version: 6.26.0 - resolution: "babel-plugin-transform-object-rest-spread@npm:6.26.0" - dependencies: - babel-plugin-syntax-object-rest-spread: ^6.8.0 - babel-runtime: ^6.26.0 - checksum: aad583fb0d08073678838f77fa822788b9a0b842ba33e34f8d131246852f7ed31cfb5fdf57644dec952f84dcae862a27dbf3d12ccbee6bdb0aed6e7ed13ca9ba + checksum: ed1932fa9a31e0752fd10ebf48ab9513a654987cab1182890839523cb898559d24ae0578fdc475d9f995390420e64eeaa4b0427045b56949dace3c725bc66dbb languageName: node linkType: hard @@ -5438,42 +7788,45 @@ __metadata: linkType: hard "babel-preset-current-node-syntax@npm:^1.0.0": - version: 1.0.1 - resolution: "babel-preset-current-node-syntax@npm:1.0.1" + version: 1.2.0 + resolution: "babel-preset-current-node-syntax@npm:1.2.0" dependencies: "@babel/plugin-syntax-async-generators": ^7.8.4 "@babel/plugin-syntax-bigint": ^7.8.3 - "@babel/plugin-syntax-class-properties": ^7.8.3 - "@babel/plugin-syntax-import-meta": ^7.8.3 + "@babel/plugin-syntax-class-properties": ^7.12.13 + "@babel/plugin-syntax-class-static-block": ^7.14.5 + "@babel/plugin-syntax-import-attributes": ^7.24.7 + "@babel/plugin-syntax-import-meta": ^7.10.4 "@babel/plugin-syntax-json-strings": ^7.8.3 - "@babel/plugin-syntax-logical-assignment-operators": ^7.8.3 + "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 - "@babel/plugin-syntax-numeric-separator": ^7.8.3 + "@babel/plugin-syntax-numeric-separator": ^7.10.4 "@babel/plugin-syntax-object-rest-spread": ^7.8.3 "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 "@babel/plugin-syntax-optional-chaining": ^7.8.3 - "@babel/plugin-syntax-top-level-await": ^7.8.3 + "@babel/plugin-syntax-private-property-in-object": ^7.14.5 + "@babel/plugin-syntax-top-level-await": ^7.14.5 peerDependencies: - "@babel/core": ^7.0.0 - checksum: d118c2742498c5492c095bc8541f4076b253e705b5f1ad9a2e7d302d81a84866f0070346662355c8e25fc02caa28dc2da8d69bcd67794a0d60c4d6fab6913cc8 + "@babel/core": ^7.0.0 || ^8.0.0-0 + checksum: 3608fa671cfa46364ea6ec704b8fcdd7514b7b70e6ec09b1199e13ae73ed346c51d5ce2cb6d4d5b295f6a3f2cad1fdeec2308aa9e037002dd7c929194cc838ea languageName: node linkType: hard -"babel-preset-jest@npm:^26.6.2": - version: 26.6.2 - resolution: "babel-preset-jest@npm:26.6.2" +"babel-preset-jest@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-preset-jest@npm:27.5.1" dependencies: - babel-plugin-jest-hoist: ^26.6.2 + babel-plugin-jest-hoist: ^27.5.1 babel-preset-current-node-syntax: ^1.0.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 1d9bef3a7ac6751a09d29ceb84be8b1998abd210fafa12223689c744db4f2a63ab90cba7986a71f3154d9aceda9dbeca563178731d21cbaf793b4096ed3a4d01 + checksum: 251bcea11c18fd9672fec104eadb45b43f117ceeb326fa7345ced778d4c1feab29343cd7a87a1dcfae4997d6c851a8b386d7f7213792da6e23b74f4443a8976d languageName: node linkType: hard -"babel-preset-react-app@npm:^10.0.0": - version: 10.0.1 - resolution: "babel-preset-react-app@npm:10.0.1" +"babel-preset-react-app@npm:^10.0.1": + version: 10.1.0 + resolution: "babel-preset-react-app@npm:10.1.0" dependencies: "@babel/core": ^7.16.0 "@babel/plugin-proposal-class-properties": ^7.16.0 @@ -5482,6 +7835,7 @@ __metadata: "@babel/plugin-proposal-numeric-separator": ^7.16.0 "@babel/plugin-proposal-optional-chaining": ^7.16.0 "@babel/plugin-proposal-private-methods": ^7.16.0 + "@babel/plugin-proposal-private-property-in-object": ^7.16.7 "@babel/plugin-transform-flow-strip-types": ^7.16.0 "@babel/plugin-transform-react-display-name": ^7.16.0 "@babel/plugin-transform-runtime": ^7.16.4 @@ -5491,26 +7845,7 @@ __metadata: "@babel/runtime": ^7.16.3 babel-plugin-macros: ^3.1.0 babel-plugin-transform-react-remove-prop-types: ^0.4.24 - checksum: ee66043484e67b8aef2541976388299691478ea00834f3bb14b6b3d5edcd316a5ac95351f6ec084b41ee555cad820d4194280ad38ce51884fedc7e8946a57b74 - languageName: node - linkType: hard - -"babel-runtime@npm:^6.26.0": - version: 6.26.0 - resolution: "babel-runtime@npm:6.26.0" - dependencies: - core-js: ^2.4.0 - regenerator-runtime: ^0.11.0 - checksum: 8aeade94665e67a73c1ccc10f6fd42ba0c689b980032b70929de7a6d9a12eb87ef51902733f8fefede35afea7a5c3ef7e916a64d503446c1eedc9e3284bd3d50 - languageName: node - linkType: hard - -"babylon@npm:^6.18.0": - version: 6.18.0 - resolution: "babylon@npm:6.18.0" - bin: - babylon: ./bin/babylon.js - checksum: 0777ae0c735ce1cbfc856d627589ed9aae212b84fb0c03c368b55e6c5d3507841780052808d0ad46e18a2ba516e93d55eeed8cd967f3b2938822dfeccfb2a16d + checksum: e4ac6c85be4f56c7e45b52700e04aed01422221b5c988e7a192a80d3b5aa3abbd415c0b76e8b5d564a411477a0b03323a15108663a9f541bd9397fa32f28ed89 languageName: node linkType: hard @@ -5518,16 +7853,18 @@ __metadata: version: 0.0.0-use.local resolution: "backend@workspace:src/backend" dependencies: - "@prisma/client": ^4.4.0 - "@slack/web-api": ^6.7.2 + "@prisma/client": 6.2.1 + "@slack/events-api": ^3.0.1 + "@slack/web-api": ^7.8.0 "@types/concat-stream": ^2.0.0 "@types/cookie-parser": ^1.4.3 "@types/cors": ^2.8.12 - "@types/express": ^4.17.6 + "@types/express": ^5.0.0 "@types/express-jwt": ^6.0.4 "@types/jsonwebtoken": ^8.5.9 "@types/multer": ^1.4.7 - "@types/node": 18.17.1 + "@types/node": ^20.0.0 + "@types/nodemailer": ^6.4.0 "@types/supertest": ^2.0.12 body-parser: ^1.19.0 concat-stream: ^2.0.0 @@ -5535,7 +7872,7 @@ __metadata: cors: ^2.8.5 decimal.js: ^10.4.3 dotenv: ^16.0.1 - express: ^4.17.1 + express: ^5.0.0 express-jwt: ^7.7.5 express-validator: ^6.14.2 google-auth-library: ^8.1.1 @@ -5544,20 +7881,19 @@ __metadata: multer: ^1.4.5-lts.1 nodemailer: ^6.9.1 nodemon: ^2.0.16 - prisma: ^4.4.0 + prisma: 6.2.1 shared: 1.0.0 supertest: ^6.2.4 - ts-jest: ^26.2.0 ts-node: ^8.10.1 - typescript: ^4.1.5 - vitest: ^0.32.1 + typescript: ^5.7.3 + vitest: ^3.0.0 languageName: unknown linkType: soft -"bail@npm:^1.0.0": - version: 1.0.5 - resolution: "bail@npm:1.0.5" - checksum: 6c334940d7eaa4e656a12fb12407b6555649b6deb6df04270fa806e0da82684ebe4a4e47815b271c794b40f8d6fa286e0c248b14ddbabb324a917fab09b7301a +"bail@npm:^2.0.0": + version: 2.0.2 + resolution: "bail@npm:2.0.2" + checksum: aab4e8ccdc8d762bf3fdfce8e706601695620c0c2eda256dd85088dc0be3cfd7ff126f6e99c2bee1f24f5d418414aacf09d7f9702f16d6963df2fa488cda8824 languageName: node linkType: hard @@ -5568,25 +7904,19 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": +"base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 languageName: node linkType: hard -"base@npm:^0.11.1": - version: 0.11.2 - resolution: "base@npm:0.11.2" - dependencies: - cache-base: ^1.0.1 - class-utils: ^0.3.5 - component-emitter: ^1.2.1 - define-property: ^1.0.0 - isobject: ^3.0.1 - mixin-deep: ^1.2.0 - pascalcase: ^0.1.1 - checksum: a4a146b912e27eea8f66d09cb0c9eab666f32ce27859a7dfd50f38cd069a2557b39f16dba1bc2aecb3b44bf096738dd207b7970d99b0318423285ab1b1994edd +"baseline-browser-mapping@npm:^2.8.3": + version: 2.8.4 + resolution: "baseline-browser-mapping@npm:2.8.4" + bin: + baseline-browser-mapping: dist/cli.js + checksum: c9580e27141fdaff3ad219a14906774c80a040f45527213d867ce8a2db02a60cf1db545041bfb69a9482c3101c5a0cd3cef1155cde3f1ba8e98bf817667756c5 languageName: node linkType: hard @@ -5625,16 +7955,9 @@ __metadata: linkType: hard "bignumber.js@npm:^9.0.0": - version: 9.1.2 - resolution: "bignumber.js@npm:9.1.2" - checksum: 582c03af77ec9cb0ebd682a373ee6c66475db94a4325f92299621d544aa4bd45cb45fd60001610e94aef8ae98a0905fa538241d9638d4422d57abbeeac6fadaf - languageName: node - linkType: hard - -"binary-extensions@npm:^1.0.0": - version: 1.13.1 - resolution: "binary-extensions@npm:1.13.1" - checksum: ad7747f33c07e94ba443055de130b50c8b8b130a358bca064c580d91769ca6a69c7ac65ca008ff044ed4541d2c6ad45496e1fadbef5218a68770996b6a2194d7 + version: 9.3.1 + resolution: "bignumber.js@npm:9.3.1" + checksum: 6ab100271a23a75bb8b99a4b1a34a1a94967ac0b9a52a198147607bd91064e72c6f356380d7a09cd687bf50d81ad2ed1a0a8edfaa90369c9003ed8bb2440d7f0 languageName: node linkType: hard @@ -5645,16 +7968,7 @@ __metadata: languageName: node linkType: hard -"bindings@npm:^1.5.0": - version: 1.5.0 - resolution: "bindings@npm:1.5.0" - dependencies: - file-uri-to-path: 1.0.0 - checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7 - languageName: node - linkType: hard - -"bl@npm:^4.1.0": +"bl@npm:^4.0.3": version: 4.1.0 resolution: "bl@npm:4.1.0" dependencies: @@ -5665,30 +7979,16 @@ __metadata: languageName: node linkType: hard -"bluebird@npm:^3.5.5, bluebird@npm:^3.7.2": +"bluebird@npm:^3.7.2": version: 3.7.2 resolution: "bluebird@npm:3.7.2" checksum: 869417503c722e7dc54ca46715f70e15f4d9c602a423a02c825570862d12935be59ed9c7ba34a9b31f186c017c23cac6b54e35446f8353059c101da73eac22ef languageName: node linkType: hard -"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": - version: 4.12.0 - resolution: "bn.js@npm:4.12.0" - checksum: 39afb4f15f4ea537b55eaf1446c896af28ac948fdcf47171961475724d1bb65118cca49fa6e3d67706e4790955ec0e74de584e45c8f1ef89f46c812bee5b5a12 - languageName: node - linkType: hard - -"bn.js@npm:^5.0.0, bn.js@npm:^5.2.1": - version: 5.2.1 - resolution: "bn.js@npm:5.2.1" - checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 - languageName: node - linkType: hard - -"body-parser@npm:1.20.2, body-parser@npm:^1.19.0": - version: 1.20.2 - resolution: "body-parser@npm:1.20.2" +"body-parser@npm:1.20.3, body-parser@npm:^1.19.0": + version: 1.20.3 + resolution: "body-parser@npm:1.20.3" dependencies: bytes: 3.1.2 content-type: ~1.0.5 @@ -5698,25 +7998,38 @@ __metadata: http-errors: 2.0.0 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.11.0 + qs: 6.13.0 raw-body: 2.5.2 type-is: ~1.6.18 unpipe: 1.0.0 - checksum: 14d37ec638ab5c93f6099ecaed7f28f890d222c650c69306872e00b9efa081ff6c596cd9afb9930656aae4d6c4e1c17537bea12bb73c87a217cb3cfea8896737 + checksum: 1a35c59a6be8d852b00946330141c4f142c6af0f970faa87f10ad74f1ee7118078056706a05ae3093c54dabca9cd3770fa62a170a85801da1a4324f04381167d languageName: node linkType: hard -"bonjour@npm:^3.5.0": - version: 3.5.0 - resolution: "bonjour@npm:3.5.0" +"body-parser@npm:^2.2.0": + version: 2.2.0 + resolution: "body-parser@npm:2.2.0" + dependencies: + bytes: ^3.1.2 + content-type: ^1.0.5 + debug: ^4.4.0 + http-errors: ^2.0.0 + iconv-lite: ^0.6.3 + on-finished: ^2.4.1 + qs: ^6.14.0 + raw-body: ^3.0.0 + type-is: ^2.0.0 + checksum: 7fe3a2d288f0b632528d6ccb90052d1a9492c5b79d5716d32c8de1f5fb8237b0d31ee5050e1d0b7ff143a492ff151804612c6e2686a222a1d4c9e2e6531b8fb2 + languageName: node + linkType: hard + +"bonjour-service@npm:^1.0.11": + version: 1.3.0 + resolution: "bonjour-service@npm:1.3.0" dependencies: - array-flatten: ^2.1.0 - deep-equal: ^1.0.1 - dns-equal: ^1.0.0 - dns-txt: ^2.0.2 - multicast-dns: ^6.0.1 - multicast-dns-service-types: ^1.1.0 - checksum: 2cfbe9fa861f4507b5ff3853eeae3ef03a231ede2b7363efedd80880ea3c0576f64416f98056c96e429ed68ff38dc4a70c0583d1eb4dab72e491ca44a0f03444 + fast-deep-equal: ^3.1.3 + multicast-dns: ^7.2.5 + checksum: 737bd40d0b609b18afdfcaf3c416a60d7dc94aedc4cb9d6e7af459a7f3bdffadc199370a48c46739d92689741cad4ec8a6987a3e4d869dd301b521227b92e082 languageName: node linkType: hard @@ -5727,59 +8040,47 @@ __metadata: languageName: node linkType: hard -"bootstrap@npm:^4.6.0": - version: 4.6.2 - resolution: "bootstrap@npm:4.6.2" +"bootstrap@npm:^5.3.0": + version: 5.3.8 + resolution: "bootstrap@npm:5.3.8" peerDependencies: - jquery: 1.9.1 - 3 - popper.js: ^1.16.1 - checksum: 3f4e7768ff7d618c49d4bf4f02aa54a9bfb679d4eecb0f3854fa4af1a17b9114b147009c435946432cdd1572efffc71d88ec385c55943a12fa66253cde0876b0 + "@popperjs/core": ^2.11.8 + checksum: 6813254a1140646ca53f33f2d0c5fbf7cf544dabba06cddc061243acf4ec71fadff348860ed4623e1b486c05c151d7807da017dc473e748add0926d2cf9f1a04 + languageName: node + linkType: hard + +"bowser@npm:^2.11.0": + version: 2.12.1 + resolution: "bowser@npm:2.12.1" + checksum: 994a3da9e9b628892e0fbc4fd5afeec672003a9a72300ec8ac832f6707ba6ce68d137d50316f08e6197f9e0cca5c486aa4b9ce9db50013061225cab4e432f8a0 languageName: node linkType: hard "brace-expansion@npm:^1.1.7": - version: 1.1.11 - resolution: "brace-expansion@npm:1.1.11" + version: 1.1.12 + resolution: "brace-expansion@npm:1.1.12" dependencies: balanced-match: ^1.0.0 concat-map: 0.0.1 - checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + checksum: 12cb6d6310629e3048cadb003e1aca4d8c9bb5c67c3c321bafdd7e7a50155de081f78ea3e0ed92ecc75a9015e784f301efc8132383132f4f7904ad1ac529c562 languageName: node linkType: hard "brace-expansion@npm:^2.0.1": - version: 2.0.1 - resolution: "brace-expansion@npm:2.0.1" + version: 2.0.2 + resolution: "brace-expansion@npm:2.0.2" dependencies: balanced-match: ^1.0.0 - checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 - languageName: node - linkType: hard - -"braces@npm:^2.3.1, braces@npm:^2.3.2": - version: 2.3.2 - resolution: "braces@npm:2.3.2" - dependencies: - arr-flatten: ^1.1.0 - array-unique: ^0.3.2 - extend-shallow: ^2.0.1 - fill-range: ^4.0.0 - isobject: ^3.0.1 - repeat-element: ^1.1.2 - snapdragon: ^0.8.1 - snapdragon-node: ^2.0.1 - split-string: ^3.0.2 - to-regex: ^3.0.1 - checksum: e30dcb6aaf4a31c8df17d848aa283a65699782f75ad61ae93ec25c9729c66cf58e66f0000a9fec84e4add1135bb7da40f7cb9601b36bebcfa9ca58e8d5c07de0 + checksum: 01dff195e3646bc4b0d27b63d9bab84d2ebc06121ff5013ad6e5356daa5a9d6b60fa26cf73c74797f2dc3fbec112af13578d51f75228c1112b26c790a87b0488 languageName: node linkType: hard -"braces@npm:^3.0.2, braces@npm:~3.0.2": - version: 3.0.2 - resolution: "braces@npm:3.0.2" +"braces@npm:^3.0.3, braces@npm:~3.0.2": + version: 3.0.3 + resolution: "braces@npm:3.0.3" dependencies: - fill-range: ^7.0.1 - checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459 + fill-range: ^7.1.1 + checksum: b95aa0b3bd909f6cd1720ffcf031aeaf46154dd88b4da01f9a1d3f7ea866a79eba76a6d01cbc3c422b2ee5cdc39a4f02491058d5df0d7bf6e6a162a832df1f69 languageName: node linkType: hard @@ -5799,128 +8100,25 @@ __metadata: languageName: node linkType: hard -"brorand@npm:^1.0.1, brorand@npm:^1.1.0": - version: 1.1.0 - resolution: "brorand@npm:1.1.0" - checksum: 8a05c9f3c4b46572dec6ef71012b1946db6cae8c7bb60ccd4b7dd5a84655db49fe043ecc6272e7ef1f69dc53d6730b9e2a3a03a8310509a3d797a618cbee52be - languageName: node - linkType: hard - -"browser-process-hrtime@npm:^1.0.0": - version: 1.0.0 - resolution: "browser-process-hrtime@npm:1.0.0" - checksum: e30f868cdb770b1201afb714ad1575dd86366b6e861900884665fb627109b3cc757c40067d3bfee1ff2a29c835257ea30725a8018a9afd02ac1c24b408b1e45f - languageName: node - linkType: hard - -"browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": - version: 1.2.0 - resolution: "browserify-aes@npm:1.2.0" - dependencies: - buffer-xor: ^1.0.3 - cipher-base: ^1.0.0 - create-hash: ^1.1.0 - evp_bytestokey: ^1.0.3 - inherits: ^2.0.1 - safe-buffer: ^5.0.1 - checksum: 4a17c3eb55a2aa61c934c286f34921933086bf6d67f02d4adb09fcc6f2fc93977b47d9d884c25619144fccd47b3b3a399e1ad8b3ff5a346be47270114bcf7104 - languageName: node - linkType: hard - -"browserify-cipher@npm:^1.0.0": - version: 1.0.1 - resolution: "browserify-cipher@npm:1.0.1" - dependencies: - browserify-aes: ^1.0.4 - browserify-des: ^1.0.0 - evp_bytestokey: ^1.0.0 - checksum: 2d8500acf1ee535e6bebe808f7a20e4c3a9e2ed1a6885fff1facbfd201ac013ef030422bec65ca9ece8ffe82b03ca580421463f9c45af6c8415fd629f4118c13 - languageName: node - linkType: hard - -"browserify-des@npm:^1.0.0": - version: 1.0.2 - resolution: "browserify-des@npm:1.0.2" - dependencies: - cipher-base: ^1.0.1 - des.js: ^1.0.0 - inherits: ^2.0.1 - safe-buffer: ^5.1.2 - checksum: b15a3e358a1d78a3b62ddc06c845d02afde6fc826dab23f1b9c016e643e7b1fda41de628d2110b712f6a44fb10cbc1800bc6872a03ddd363fb50768e010395b7 - languageName: node - linkType: hard - -"browserify-rsa@npm:^4.0.0, browserify-rsa@npm:^4.1.0": - version: 4.1.0 - resolution: "browserify-rsa@npm:4.1.0" - dependencies: - bn.js: ^5.0.0 - randombytes: ^2.0.1 - checksum: 155f0c135873efc85620571a33d884aa8810e40176125ad424ec9d85016ff105a07f6231650914a760cca66f29af0494087947b7be34880dd4599a0cd3c38e54 - languageName: node - linkType: hard - -"browserify-sign@npm:^4.0.0": - version: 4.2.3 - resolution: "browserify-sign@npm:4.2.3" - dependencies: - bn.js: ^5.2.1 - browserify-rsa: ^4.1.0 - create-hash: ^1.2.0 - create-hmac: ^1.1.7 - elliptic: ^6.5.5 - hash-base: ~3.0 - inherits: ^2.0.4 - parse-asn1: ^5.1.7 - readable-stream: ^2.3.8 - safe-buffer: ^5.2.1 - checksum: 403a8061d229ae31266670345b4a7c00051266761d2c9bbeb68b1a9bcb05f68143b16110cf23a171a5d6716396a1f41296282b3e73eeec0a1871c77f0ff4ee6b - languageName: node - linkType: hard - -"browserify-zlib@npm:^0.2.0": - version: 0.2.0 - resolution: "browserify-zlib@npm:0.2.0" - dependencies: - pako: ~1.0.5 - checksum: 5cd9d6a665190fedb4a97dfbad8dabc8698d8a507298a03f42c734e96d58ca35d3c7d4085e283440bbca1cd1938cff85031728079bedb3345310c58ab1ec92d6 - languageName: node - linkType: hard - -"browserslist@npm:4.14.2": - version: 4.14.2 - resolution: "browserslist@npm:4.14.2" - dependencies: - caniuse-lite: ^1.0.30001125 - electron-to-chromium: ^1.3.564 - escalade: ^3.0.2 - node-releases: ^1.1.61 - bin: - browserslist: cli.js - checksum: 44b5d7a444b867e1f027923f37a8ed537b4403f8a85a35869904e7d3e4071b37459df08d41ab4d425f5191f3125f1c5a191cbff9070f81f4d311803dc0a2fb0f +"browser-process-hrtime@npm:^1.0.0": + version: 1.0.0 + resolution: "browser-process-hrtime@npm:1.0.0" + checksum: e30f868cdb770b1201afb714ad1575dd86366b6e861900884665fb627109b3cc757c40067d3bfee1ff2a29c835257ea30725a8018a9afd02ac1c24b408b1e45f languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.12.0, browserslist@npm:^4.22.2, browserslist@npm:^4.23.0, browserslist@npm:^4.6.2, browserslist@npm:^4.6.4": - version: 4.23.0 - resolution: "browserslist@npm:4.23.0" +"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.25.3": + version: 4.26.2 + resolution: "browserslist@npm:4.26.2" dependencies: - caniuse-lite: ^1.0.30001587 - electron-to-chromium: ^1.4.668 - node-releases: ^2.0.14 - update-browserslist-db: ^1.0.13 + baseline-browser-mapping: ^2.8.3 + caniuse-lite: ^1.0.30001741 + electron-to-chromium: ^1.5.218 + node-releases: ^2.0.21 + update-browserslist-db: ^1.1.3 bin: browserslist: cli.js - checksum: 436f49e796782ca751ebab7edc010cfc9c29f68536f387666cd70ea22f7105563f04dd62c6ff89cb24cc3254d17cba385f979eeeb3484d43e012412ff7e75def - languageName: node - linkType: hard - -"bs-logger@npm:0.x": - version: 0.2.6 - resolution: "bs-logger@npm:0.2.6" - dependencies: - fast-json-stable-stringify: 2.x - checksum: d34bdaf68c64bd099ab97c3ea608c9ae7d3f5faa1178b3f3f345acd94e852e608b2d4f9103fb2e503f5e69780e98293df41691b84be909b41cf5045374d54606 + checksum: ebd96e8895cdfc72be074281eb377332b69ceb944ec0c063739d8eeb8e513b168ac1e27d26ce5cc260e69a340a44c6bb5e9408565449d7a16739e5844453d4c7 languageName: node linkType: hard @@ -5933,45 +8131,20 @@ __metadata: languageName: node linkType: hard -"buffer-equal-constant-time@npm:1.0.1": +"buffer-equal-constant-time@npm:^1.0.1": version: 1.0.1 resolution: "buffer-equal-constant-time@npm:1.0.1" checksum: 80bb945f5d782a56f374b292770901065bad21420e34936ecbe949e57724b4a13874f735850dd1cc61f078773c4fb5493a41391e7bda40d1fa388d6bd80daaab languageName: node linkType: hard -"buffer-from@npm:1.x, buffer-from@npm:^1.0.0": +"buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" checksum: 0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb languageName: node linkType: hard -"buffer-indexof@npm:^1.0.0": - version: 1.1.1 - resolution: "buffer-indexof@npm:1.1.1" - checksum: 0967abc2981a8e7d776324c6b84811e4d84a7ead89b54a3bb8791437f0c4751afd060406b06db90a436f1cf771867331b5ecf5c4aca95b4ccb9f6cb146c22ebc - languageName: node - linkType: hard - -"buffer-xor@npm:^1.0.3": - version: 1.0.3 - resolution: "buffer-xor@npm:1.0.3" - checksum: 10c520df29d62fa6e785e2800e586a20fc4f6dfad84bcdbd12e1e8a83856de1cb75c7ebd7abe6d036bbfab738a6cf18a3ae9c8e5a2e2eb3167ca7399ce65373a - languageName: node - linkType: hard - -"buffer@npm:^4.3.0": - version: 4.9.2 - resolution: "buffer@npm:4.9.2" - dependencies: - base64-js: ^1.0.2 - ieee754: ^1.1.4 - isarray: ^1.0.0 - checksum: 8801bc1ba08539f3be70eee307a8b9db3d40f6afbfd3cf623ab7ef41dffff1d0a31de0addbe1e66e0ca5f7193eeb667bfb1ecad3647f8f1b0750de07c13295c3 - languageName: node - linkType: hard - "buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" @@ -5989,21 +8162,14 @@ __metadata: languageName: node linkType: hard -"builtin-status-codes@npm:^3.0.0": - version: 3.0.0 - resolution: "builtin-status-codes@npm:3.0.0" - checksum: 1119429cf4b0d57bf76b248ad6f529167d343156ebbcc4d4e4ad600484f6bc63002595cbb61b67ad03ce55cd1d3c4711c03bbf198bf24653b8392420482f3773 - languageName: node - linkType: hard - -"bundle-require@npm:^3.0.4": - version: 3.1.2 - resolution: "bundle-require@npm:3.1.2" +"bundle-require@npm:^4.0.4": + version: 4.2.1 + resolution: "bundle-require@npm:4.2.1" dependencies: - load-tsconfig: ^0.2.0 + load-tsconfig: ^0.2.3 peerDependencies: - esbuild: ">=0.13" - checksum: 71f8cb81bcde97825317b0e516b7e479ec70bd2370f55a8f02795c0df6d541e6562c4b9ec0427cc7b5b835103a8dcf306da04e3846fa468146358471490fcf81 + esbuild: ">=0.17" + checksum: dcf97683772bd9b1461bde9ba83d2dc0f13c5d7aeecfc9d6e3678b21eeb859a03ee815db03ed14af9d7b1311f39e99ce0487d6f67f9244381436eecf478c9a2c languageName: node linkType: hard @@ -6016,14 +8182,7 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.0.0": - version: 3.0.0 - resolution: "bytes@npm:3.0.0" - checksum: a2b386dd8188849a5325f58eef69c3b73c51801c08ffc6963eddc9be244089ba32d19347caf6d145c86f315ae1b1fc7061a32b0c1aa6379e6a719090287ed101 - languageName: node - linkType: hard - -"bytes@npm:3.1.2": +"bytes@npm:3.1.2, bytes@npm:^3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: e4bcd3948d289c5127591fbedf10c0b639ccbf00243504e4e127374a15c3bc8eed0d28d4aaab08ff6f1cf2abc0cce6ba3085ed32f4f90e82a5683ce0014e1b6e @@ -6037,60 +8196,11 @@ __metadata: languageName: node linkType: hard -"cacache@npm:^12.0.2": - version: 12.0.4 - resolution: "cacache@npm:12.0.4" - dependencies: - bluebird: ^3.5.5 - chownr: ^1.1.1 - figgy-pudding: ^3.5.1 - glob: ^7.1.4 - graceful-fs: ^4.1.15 - infer-owner: ^1.0.3 - lru-cache: ^5.1.1 - mississippi: ^3.0.0 - mkdirp: ^0.5.1 - move-concurrently: ^1.0.1 - promise-inflight: ^1.0.1 - rimraf: ^2.6.3 - ssri: ^6.0.1 - unique-filename: ^1.1.1 - y18n: ^4.0.0 - checksum: c88a72f36939b2523533946ffb27828443db5bf5995d761b35ae17af1eb6c8e20ac55b00b74c2ca900b2e1e917f0afba6847bf8cc16bee05ccca6aa150e0830c - languageName: node - linkType: hard - -"cacache@npm:^15.0.5": - version: 15.3.0 - resolution: "cacache@npm:15.3.0" - dependencies: - "@npmcli/fs": ^1.0.0 - "@npmcli/move-file": ^1.0.1 - chownr: ^2.0.0 - fs-minipass: ^2.0.0 - glob: ^7.1.4 - infer-owner: ^1.0.4 - lru-cache: ^6.0.0 - minipass: ^3.1.1 - minipass-collect: ^1.0.2 - minipass-flush: ^1.0.5 - minipass-pipeline: ^1.2.2 - mkdirp: ^1.0.3 - p-map: ^4.0.0 - promise-inflight: ^1.0.1 - rimraf: ^3.0.2 - ssri: ^8.0.1 - tar: ^6.0.2 - unique-filename: ^1.1.1 - checksum: a07327c27a4152c04eb0a831c63c00390d90f94d51bb80624a66f4e14a6b6360bbf02a84421267bd4d00ca73ac9773287d8d7169e8d2eafe378d2ce140579db8 - languageName: node - linkType: hard - -"cacache@npm:^18.0.0": - version: 18.0.2 - resolution: "cacache@npm:18.0.2" +"cacache@npm:^19.0.1": + version: 19.0.1 + resolution: "cacache@npm:19.0.1" dependencies: - "@npmcli/fs": ^3.1.0 + "@npmcli/fs": ^4.0.0 fs-minipass: ^3.0.0 glob: ^10.2.2 lru-cache: ^10.0.1 @@ -6098,66 +8208,43 @@ __metadata: 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 - checksum: 0250df80e1ad0c828c956744850c5f742c24244e9deb5b7dc81bca90f8c10e011e132ecc58b64497cc1cad9a98968676147fb6575f4f94722f7619757b17a11b - languageName: node - linkType: hard - -"cache-base@npm:^1.0.1": - version: 1.0.1 - resolution: "cache-base@npm:1.0.1" - dependencies: - collection-visit: ^1.0.0 - component-emitter: ^1.2.1 - get-value: ^2.0.6 - has-value: ^1.0.0 - isobject: ^3.0.1 - set-value: ^2.0.0 - to-object-path: ^0.3.0 - union-value: ^1.0.0 - unset-value: ^1.0.0 - checksum: 9114b8654fe2366eedc390bad0bcf534e2f01b239a888894e2928cb58cdc1e6ea23a73c6f3450dcfd2058aa73a8a981e723cd1e7c670c047bf11afdc65880107 + p-map: ^7.0.2 + ssri: ^12.0.0 + tar: ^7.4.3 + unique-filename: ^4.0.0 + checksum: e95684717de6881b4cdaa949fa7574e3171946421cd8291769dd3d2417dbf7abf4aa557d1f968cca83dcbc95bed2a281072b09abfc977c942413146ef7ed4525 languageName: node linkType: hard -"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": - version: 1.0.7 - resolution: "call-bind@npm:1.0.7" +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" 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 - checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029 + checksum: b2863d74fcf2a6948221f65d95b91b4b2d90cfe8927650b506141e669f7d5de65cea191bf788838bc40d13846b7886c5bc5c84ab96c3adbcf88ad69a72fcdc6b languageName: node linkType: hard -"caller-callsite@npm:^2.0.0": - version: 2.0.0 - resolution: "caller-callsite@npm:2.0.0" +"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": + version: 1.0.8 + resolution: "call-bind@npm:1.0.8" dependencies: - callsites: ^2.0.0 - checksum: b685e9d126d9247b320cfdfeb3bc8da0c4be28d8fb98c471a96bc51aab3130099898a2fe3bf0308f0fe048d64c37d6d09f563958b9afce1a1e5e63d879c128a2 + call-bind-apply-helpers: ^1.0.0 + es-define-property: ^1.0.0 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.2 + checksum: aa2899bce917a5392fd73bd32e71799c37c0b7ab454e0ed13af7f6727549091182aade8bbb7b55f304a5bc436d543241c14090fb8a3137e9875e23f444f4f5a9 languageName: node linkType: hard -"caller-path@npm:^2.0.0": - version: 2.0.0 - resolution: "caller-path@npm:2.0.0" +"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" dependencies: - caller-callsite: ^2.0.0 - checksum: 3e12ccd0c71ec10a057aac69e3ec175b721ca858c640df021ef0d25999e22f7c1d864934b596b7d47038e9b56b7ec315add042abbd15caac882998b50102fb12 - languageName: node - linkType: hard - -"callsites@npm:^2.0.0": - version: 2.0.0 - resolution: "callsites@npm:2.0.0" - checksum: be2f67b247df913732b7dec1ec0bbfcdbaea263e5a95968b19ec7965affae9496b970e3024317e6d4baa8e28dc6ba0cec03f46fdddc2fdcc51396600e53c2623 + call-bind-apply-helpers: ^1.0.2 + get-intrinsic: ^1.3.0 + checksum: 2f6399488d1c272f56306ca60ff696575e2b7f31daf23bc11574798c84d9f2759dceb0cb1f471a85b77f28962a7ac6411f51d283ea2e45319009a19b6ccab3b2 languageName: node linkType: hard @@ -6168,7 +8255,7 @@ __metadata: languageName: node linkType: hard -"camel-case@npm:^4.1.1, camel-case@npm:^4.1.2": +"camel-case@npm:^4.1.2": version: 4.1.2 resolution: "camel-case@npm:4.1.2" dependencies: @@ -6178,14 +8265,21 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:5.3.1, camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": +"camelcase-css@npm:^2.0.1": + version: 2.0.1 + resolution: "camelcase-css@npm:2.0.1" + checksum: 1cec2b3b3dcb5026688a470b00299a8db7d904c4802845c353dbd12d9d248d3346949a814d83bfd988d4d2e5b9904c07efe76fecd195a1d4f05b543e7c0b56b1 + languageName: node + linkType: hard + +"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" checksum: e6effce26b9404e3c0f301498184f243811c30dfe6d0b9051863bd8e4034d09c8c2923794f280d6827e5aa055f6c434115ff97864a16a963366fb35fd673024b languageName: node linkType: hard -"camelcase@npm:^6.0.0, camelcase@npm:^6.1.0, camelcase@npm:^6.2.0": +"camelcase@npm:^6.2.0, camelcase@npm:^6.2.1": version: 6.3.0 resolution: "camelcase@npm:6.3.0" checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d @@ -6204,10 +8298,21 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001125, caniuse-lite@npm:^1.0.30001587": - version: 1.0.30001612 - resolution: "caniuse-lite@npm:1.0.30001612" - checksum: 2b6ab6a19c72bdf8dccac824944e828a2a1fae52c6dfeb2d64ccecfd60d0466d2e5a392e996da2150d92850188a5034666dceed34a38d978177f6934e0bf106d +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001741": + version: 1.0.30001743 + resolution: "caniuse-lite@npm:1.0.30001743" + checksum: 9e203fe09158b011bd4a6707f6e5f9ad040e5b4093b12e2e047636a71d6e2e3bf5209aae42f213251cc812d9091188d7f1da7bd4785bc0b879beb98f9aa04ebc + languageName: node + linkType: hard + +"canvas@npm:^3.0.0-rc2": + version: 3.2.0 + resolution: "canvas@npm:3.2.0" + dependencies: + node-addon-api: ^7.0.0 + node-gyp: latest + prebuild-install: ^7.1.3 + checksum: 68c7fe3c0c79efb3358d4ab4b04586068fefe06c7137e6636111ae91e68122ac069f05d883fdf11eb7fd08eba841096cb700324d02efca7abbf92d3476c567e4 languageName: node linkType: hard @@ -6222,59 +8327,34 @@ __metadata: languageName: node linkType: hard -"capture-exit@npm:^2.0.0": - version: 2.0.0 - resolution: "capture-exit@npm:2.0.0" - dependencies: - rsvp: ^4.8.4 - checksum: 0b9f10daca09e521da9599f34c8e7af14ad879c336e2bdeb19955b375398ae1c5bcc91ac9f2429944343057ee9ed028b1b2fb28816c384e0e55d70c439b226f4 - languageName: node - linkType: hard - -"case-sensitive-paths-webpack-plugin@npm:2.3.0": - version: 2.3.0 - resolution: "case-sensitive-paths-webpack-plugin@npm:2.3.0" - checksum: 2fa78f7a495d7e73e66d1f528eac5abde65df797c9487624eeae9815a409ba6d584d8fbfe8b6c89157292fbb08d0ee6cc3418fe7f8c75b83fb2c8e29c30f205d - languageName: node - linkType: hard - -"chai@npm:^4.3.7": - version: 4.4.1 - resolution: "chai@npm:4.4.1" - dependencies: - assertion-error: ^1.1.0 - check-error: ^1.0.3 - deep-eql: ^4.1.3 - get-func-name: ^2.0.2 - loupe: ^2.3.6 - pathval: ^1.1.1 - type-detect: ^4.0.8 - checksum: 9ab84f36eb8e0b280c56c6c21ca4da5933132cd8a0c89c384f1497f77953640db0bc151edd47f81748240a9fab57b78f7d925edfeedc8e8fc98016d71f40c36e +"case-sensitive-paths-webpack-plugin@npm:^2.4.0": + version: 2.4.0 + resolution: "case-sensitive-paths-webpack-plugin@npm:2.4.0" + checksum: bcf469446eeee9ac0046e30860074ebb9aa4803aab9140e6bb72b600b23b1d70635690754be4504ce35cd99cdf05226bee8d894ba362a3f5485d5f6310fc6d02 languageName: node linkType: hard -"chalk@npm:2.4.2, chalk@npm:^2.4.1, chalk@npm:^2.4.2": - version: 2.4.2 - resolution: "chalk@npm:2.4.2" - dependencies: - ansi-styles: ^3.2.1 - escape-string-regexp: ^1.0.5 - supports-color: ^5.3.0 - checksum: ec3661d38fe77f681200f878edbd9448821924e0f93a9cefc0e26a33b145f1027a2084bf19967160d11e1f03bfe4eaffcabf5493b89098b2782c3fe0b03d80c2 +"ccount@npm:^2.0.0": + version: 2.0.1 + resolution: "ccount@npm:2.0.1" + checksum: 48193dada54c9e260e0acf57fc16171a225305548f9ad20d5471e0f7a8c026aedd8747091dccb0d900cde7df4e4ddbd235df0d8de4a64c71b12f0d3303eeafd4 languageName: node linkType: hard -"chalk@npm:4.1.1": - version: 4.1.1 - resolution: "chalk@npm:4.1.1" +"chai@npm:^5.1.2, chai@npm:^5.2.0": + version: 5.3.3 + resolution: "chai@npm:5.3.3" dependencies: - ansi-styles: ^4.1.0 - supports-color: ^7.1.0 - checksum: 036e973e665ba1a32c975e291d5f3d549bceeb7b1b983320d4598fb75d70fe20c5db5d62971ec0fe76cdbce83985a00ee42372416abfc3a5584465005a7855ed + assertion-error: ^2.0.1 + check-error: ^2.1.1 + deep-eql: ^5.0.1 + loupe: ^3.1.0 + pathval: ^2.0.0 + checksum: bc4091f1cccfee63f6a3d02ce477fe847f5c57e747916a11bd72675c9459125084e2e55dc2363ee2b82b088a878039ee7ee27c75d6d90f7de9202bf1b12ce573 languageName: node linkType: hard -"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.1": +"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -6284,26 +8364,14 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^1.1.3": - version: 1.1.3 - resolution: "chalk@npm:1.1.3" - dependencies: - ansi-styles: ^2.2.1 - escape-string-regexp: ^1.0.2 - has-ansi: ^2.0.0 - strip-ansi: ^3.0.0 - supports-color: ^2.0.0 - checksum: 9d2ea6b98fc2b7878829eec223abcf404622db6c48396a9b9257f6d0ead2acf18231ae368d6a664a83f272b0679158da12e97b5229f794939e555cc574478acd - languageName: node - linkType: hard - -"chalk@npm:^3.0.0": - version: 3.0.0 - resolution: "chalk@npm:3.0.0" +"chalk@npm:^2.4.1, chalk@npm:^2.4.2": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" dependencies: - ansi-styles: ^4.1.0 - supports-color: ^7.1.0 - checksum: 8e3ddf3981c4da405ddbd7d9c8d91944ddf6e33d6837756979f7840a29272a69a5189ecae0ff84006750d6d1e92368d413335eab4db5476db6e6703a1d1e0505 + ansi-styles: ^3.2.1 + escape-string-regexp: ^1.0.5 + supports-color: ^5.3.0 + checksum: ec3661d38fe77f681200f878edbd9448821924e0f93a9cefc0e26a33b145f1027a2084bf19967160d11e1f03bfe4eaffcabf5493b89098b2782c3fe0b03d80c2 languageName: node linkType: hard @@ -6334,40 +8402,63 @@ __metadata: languageName: node linkType: hard -"character-entities-legacy@npm:^1.0.0": - version: 1.1.4 - resolution: "character-entities-legacy@npm:1.1.4" - checksum: fe03a82c154414da3a0c8ab3188e4237ec68006cbcd681cf23c7cfb9502a0e76cd30ab69a2e50857ca10d984d57de3b307680fff5328ccd427f400e559c3a811 +"char-regex@npm:^2.0.0": + version: 2.0.2 + resolution: "char-regex@npm:2.0.2" + checksum: 4965154ccf32b39c0f31df79e17686ee22fb6ebea774b6128e1d020cf2b01a3319bb608bfa2dba53cd478bed2f1991ac5246bee5ff93d0217ff7514e404694ed languageName: node linkType: hard -"character-entities@npm:^1.0.0": - version: 1.2.4 - resolution: "character-entities@npm:1.2.4" - checksum: e1545716571ead57beac008433c1ff69517cd8ca5b336889321c5b8ff4a99c29b65589a701e9c086cda8a5e346a67295e2684f6c7ea96819fe85cbf49bf8686d +"character-entities-html4@npm:^2.0.0": + version: 2.1.0 + resolution: "character-entities-html4@npm:2.1.0" + checksum: 7034aa7c7fa90309667f6dd50499c8a760c3d3a6fb159adb4e0bada0107d194551cdbad0714302f62d06ce4ed68565c8c2e15fdef2e8f8764eb63fa92b34b11d languageName: node linkType: hard -"character-reference-invalid@npm:^1.0.0": - version: 1.1.4 - resolution: "character-reference-invalid@npm:1.1.4" - checksum: 20274574c70e05e2f81135f3b93285536bc8ff70f37f0809b0d17791a832838f1e49938382899ed4cb444e5bbd4314ca1415231344ba29f4222ce2ccf24fea0b +"character-entities-legacy@npm:^3.0.0": + version: 3.0.0 + resolution: "character-entities-legacy@npm:3.0.0" + checksum: 7582af055cb488b626d364b7d7a4e46b06abd526fb63c0e4eb35bcb9c9799cc4f76b39f34fdccef2d1174ac95e53e9ab355aae83227c1a2505877893fce77731 languageName: node linkType: hard -"chardet@npm:^0.7.0": - version: 0.7.0 - resolution: "chardet@npm:0.7.0" - checksum: 6fd5da1f5d18ff5712c1e0aed41da200d7c51c28f11b36ee3c7b483f3696dabc08927fc6b227735eb8f0e1215c9a8abd8154637f3eff8cada5959df7f58b024d +"character-entities@npm:^2.0.0": + version: 2.0.2 + resolution: "character-entities@npm:2.0.2" + checksum: cf1643814023697f725e47328fcec17923b8f1799102a8a79c1514e894815651794a2bffd84bb1b3a4b124b050154e4529ed6e81f7c8068a734aecf07a6d3def languageName: node linkType: hard -"check-error@npm:^1.0.3": - version: 1.0.3 - resolution: "check-error@npm:1.0.3" +"character-reference-invalid@npm:^2.0.0": + version: 2.0.1 + resolution: "character-reference-invalid@npm:2.0.1" + checksum: 98d3b1a52ae510b7329e6ee7f6210df14f1e318c5415975d4c9e7ee0ef4c07875d47c6e74230c64551f12f556b4a8ccc24d9f3691a2aa197019e72a95e9297ee + languageName: node + linkType: hard + +"chart.js@npm:4.4.6": + version: 4.4.6 + resolution: "chart.js@npm:4.4.6" dependencies: - get-func-name: ^2.0.2 - checksum: e2131025cf059b21080f4813e55b3c480419256914601750b0fee3bd9b2b8315b531e551ef12560419b8b6d92a3636511322752b1ce905703239e7cc451b6399 + "@kurkle/color": ^0.3.0 + checksum: 4dcf6aa20f41115bb9e848d3053960eb4eeaaa94272344cc2b9b8faba33316c43893311897e20cd2bcd5b7963333cb30b7805829b78918d1d8c14a9e772e0c87 + languageName: node + linkType: hard + +"chartjs-plugin-datalabels@npm:^2.2.0": + version: 2.2.0 + resolution: "chartjs-plugin-datalabels@npm:2.2.0" + peerDependencies: + chart.js: ">=3.0.0" + checksum: 26086a908a8e88507959b7aaf798b2d9794ea95f7a5889b8bb9f6b9f3437a7e2fdf18952d3ba403b2ff78e5b70452439fb323bd0dfe76e9d7d1dae1328dacb99 + languageName: node + linkType: hard + +"check-error@npm:^2.1.1": + version: 2.1.1 + resolution: "check-error@npm:2.1.1" + checksum: d785ed17b1d4a4796b6e75c765a9a290098cf52ff9728ce0756e8ffd4293d2e419dd30c67200aee34202463b474306913f2fcfaf1890641026d9fc6966fea27a languageName: node linkType: hard @@ -6378,7 +8469,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.4.1, chokidar@npm:^3.4.2, chokidar@npm:^3.5.2, chokidar@npm:^3.5.3": +"chokidar@npm:^3.4.2, chokidar@npm:^3.5.2, chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -6397,26 +8488,12 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^2.1.8": - version: 2.1.8 - resolution: "chokidar@npm:2.1.8" +"chokidar@npm:^4.0.0": + version: 4.0.3 + resolution: "chokidar@npm:4.0.3" dependencies: - anymatch: ^2.0.0 - async-each: ^1.0.1 - braces: ^2.3.2 - fsevents: ^1.2.7 - glob-parent: ^3.1.0 - inherits: ^2.0.3 - is-binary-path: ^1.0.0 - is-glob: ^4.0.0 - normalize-path: ^3.0.0 - path-is-absolute: ^1.0.0 - readdirp: ^2.2.1 - upath: ^1.1.1 - dependenciesMeta: - fsevents: - optional: true - checksum: 0c43e89cbf0268ef1e1f41ce8ec5233c7ba022c6f3282c2ef6530e351d42396d389a1148c5a040f291cf1f4083a4c6b2f51dad3f31c726442ea9a337de316bcf + readdirp: ^4.0.1 + checksum: a8765e452bbafd04f3f2fad79f04222dd65f43161488bb6014a41099e6ca18d166af613d59a90771908c1c823efa3f46ba36b86ac50b701c20c1b9908c5fe36e languageName: node linkType: hard @@ -6427,24 +8504,17 @@ __metadata: languageName: node linkType: hard -"chownr@npm:^2.0.0": - version: 2.0.0 - resolution: "chownr@npm:2.0.0" - checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: fd73a4bab48b79e66903fe1cafbdc208956f41ea4f856df883d0c7277b7ab29fd33ee65f93b2ec9192fc0169238f2f8307b7735d27c155821d886b84aa97aa8d languageName: node linkType: hard "chrome-trace-event@npm:^1.0.2": - version: 1.0.3 - resolution: "chrome-trace-event@npm:1.0.3" - checksum: cb8b1fc7e881aaef973bd0c4a43cd353c2ad8323fb471a041e64f7c2dd849cde4aad15f8b753331a32dda45c973f032c8a03b8177fc85d60eaa75e91e08bfb97 - languageName: node - linkType: hard - -"ci-info@npm:^2.0.0": - version: 2.0.0 - resolution: "ci-info@npm:2.0.0" - checksum: 3b374666a85ea3ca43fa49aa3a048d21c9b475c96eb13c133505d2324e7ae5efd6a454f41efe46a152269e9b6a00c9edbe63ec7fa1921957165aae16625acd67 + version: 1.0.4 + resolution: "chrome-trace-event@npm:1.0.4" + checksum: fcbbd9dd0cd5b48444319007cc0c15870fd8612cc0df320908aa9d5e8a244084d48571eb28bf3c58c19327d2c5838f354c2d89fac3956d8e992273437401ac19 languageName: node linkType: hard @@ -6455,32 +8525,10 @@ __metadata: languageName: node linkType: hard -"cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": - version: 1.0.4 - resolution: "cipher-base@npm:1.0.4" - dependencies: - inherits: ^2.0.1 - safe-buffer: ^5.0.1 - checksum: 47d3568dbc17431a339bad1fe7dff83ac0891be8206911ace3d3b818fc695f376df809bea406e759cdea07fff4b454fa25f1013e648851bec790c1d75763032e - languageName: node - linkType: hard - -"cjs-module-lexer@npm:^0.6.0": - version: 0.6.0 - resolution: "cjs-module-lexer@npm:0.6.0" - checksum: 445b039607efd74561d7db8d0867031c8b6a69f25e83fdd861b0fa1fbc11f12de057ba1db80637f3c9016774354092af5325eebb90505d65ccc5389cae09d1fd - languageName: node - linkType: hard - -"class-utils@npm:^0.3.5": - version: 0.3.6 - resolution: "class-utils@npm:0.3.6" - dependencies: - arr-union: ^3.1.0 - define-property: ^0.2.5 - isobject: ^3.0.0 - static-extend: ^0.1.1 - checksum: be108900801e639e50f96a7e4bfa8867c753a7750a7603879f3981f8b0a89cba657497a2d5f40cd4ea557ff15d535a100818bb486baf6e26fe5d7872e75f1078 +"cjs-module-lexer@npm:^1.0.0": + version: 1.4.3 + resolution: "cjs-module-lexer@npm:1.4.3" + checksum: 221a1661a9ff4944b472c85ac7cd5029b2f2dc7f6c5f4ecf887f261503611110b43a48acb6c07f8f04109c772d1637fdb20b31252bf27058f35aa97bf5ad8b12 languageName: node linkType: hard @@ -6491,53 +8539,19 @@ __metadata: languageName: node linkType: hard -"clean-css@npm:^4.2.3": - version: 4.2.4 - resolution: "clean-css@npm:4.2.4" +"clean-css@npm:^5.2.2": + version: 5.3.3 + resolution: "clean-css@npm:5.3.3" dependencies: source-map: ~0.6.0 - checksum: 045ff6fcf4b5c76a084b24e1633e0c78a13b24080338fc8544565a9751559aa32ff4ee5886d9e52c18a644a6ff119bd8e37bc58e574377c05382a1fb7dbe39f8 - languageName: node - linkType: hard - -"clean-stack@npm:^2.0.0": - version: 2.2.0 - resolution: "clean-stack@npm:2.2.0" - checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 - languageName: node - linkType: hard - -"cli-cursor@npm:^3.1.0": - version: 3.1.0 - resolution: "cli-cursor@npm:3.1.0" - dependencies: - restore-cursor: ^3.1.0 - checksum: 2692784c6cd2fd85cfdbd11f53aea73a463a6d64a77c3e098b2b4697a20443f430c220629e1ca3b195ea5ac4a97a74c2ee411f3807abf6df2b66211fec0c0a29 - languageName: node - linkType: hard - -"cli-spinners@npm:^2.5.0": - version: 2.9.2 - resolution: "cli-spinners@npm:2.9.2" - checksum: 1bd588289b28432e4676cb5d40505cfe3e53f2e4e10fbe05c8a710a154d6fe0ce7836844b00d6858f740f2ffe67cdc36e0fce9c7b6a8430e80e6388d5aa4956c - languageName: node - linkType: hard - -"cli-width@npm:^3.0.0": - version: 3.0.0 - resolution: "cli-width@npm:3.0.0" - checksum: 4c94af3769367a70e11ed69aa6095f1c600c0ff510f3921ab4045af961820d57c0233acfa8b6396037391f31b4c397e1f614d234294f979ff61430a6c166c3f6 + checksum: 941987c14860dd7d346d5cf121a82fd2caf8344160b1565c5387f7ccca4bbcaf885bace961be37c4f4713ce2d8c488dd89483c1add47bb779790edbfdcc79cbc languageName: node linkType: hard -"cliui@npm:^5.0.0": - version: 5.0.0 - resolution: "cliui@npm:5.0.0" - dependencies: - string-width: ^3.1.0 - strip-ansi: ^5.2.0 - wrap-ansi: ^5.1.0 - checksum: 0bb8779efe299b8f3002a73619eaa8add4081eb8d1c17bc4fedc6240557fb4eacdc08fe87c39b002eacb6cfc117ce736b362dbfd8bf28d90da800e010ee97df4 +"cli-width@npm:^4.1.0": + version: 4.1.0 + resolution: "cli-width@npm:4.1.0" + checksum: 0a79cff2dbf89ef530bcd54c713703ba94461457b11e5634bd024c78796ed21401e32349c004995954e06f442d82609287e7aabf6a5f02c919a1cf3b9b6854ff languageName: node linkType: hard @@ -6552,6 +8566,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^7.0.2": + version: 7.0.4 + resolution: "cliui@npm:7.0.4" + dependencies: + string-width: ^4.2.0 + strip-ansi: ^6.0.0 + wrap-ansi: ^7.0.0 + checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f + languageName: node + linkType: hard + "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -6563,13 +8588,6 @@ __metadata: languageName: node linkType: hard -"clone@npm:^1.0.2": - version: 1.0.4 - resolution: "clone@npm:1.0.4" - checksum: d06418b7335897209e77bdd430d04f882189582e67bd1f75a04565f3f07f5b3f119a9d670c943b6697d0afb100f03b866b3b8a1f91d4d02d72c4ecf2bb64b5dd - languageName: node - linkType: hard - "clsx@npm:^1.2.1": version: 1.2.1 resolution: "clsx@npm:1.2.1" @@ -6577,7 +8595,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.0.0, clsx@npm:^2.1.0": +"clsx@npm:^2.0.0, clsx@npm:^2.1.1": version: 2.1.1 resolution: "clsx@npm:2.1.1" checksum: acd3e1ab9d8a433ecb3cc2f6a05ab95fe50b4a3cfc5ba47abb6cbf3754585fcb87b84e90c822a1f256c4198e3b41c7f6c391577ffc8678ad587fc0976b24fd57 @@ -6609,17 +8627,7 @@ __metadata: languageName: node linkType: hard -"collection-visit@npm:^1.0.0": - version: 1.0.0 - resolution: "collection-visit@npm:1.0.0" - dependencies: - map-visit: ^1.0.0 - object-visit: ^1.0.0 - checksum: 15d9658fe6eb23594728346adad5433b86bb7a04fd51bbab337755158722f9313a5376ef479de5b35fbc54140764d0d39de89c339f5d25b959ed221466981da9 - languageName: node - linkType: hard - -"color-convert@npm:^1.9.0, color-convert@npm:^1.9.3": +"color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" dependencies: @@ -6644,34 +8652,28 @@ __metadata: languageName: node linkType: hard -"color-name@npm:^1.0.0, color-name@npm:~1.1.4": +"color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 languageName: node linkType: hard -"color-string@npm:^1.6.0": - version: 1.9.1 - resolution: "color-string@npm:1.9.1" - dependencies: - color-name: ^1.0.0 - simple-swizzle: ^0.2.2 - checksum: c13fe7cff7885f603f49105827d621ce87f4571d78ba28ef4a3f1a104304748f620615e6bf065ecd2145d0d9dad83a3553f52bb25ede7239d18e9f81622f1cc5 +"colord@npm:^2.9.1": + version: 2.9.3 + resolution: "colord@npm:2.9.3" + checksum: 95d909bfbcfd8d5605cbb5af56f2d1ce2b323990258fd7c0d2eb0e6d3bb177254d7fb8213758db56bb4ede708964f78c6b992b326615f81a18a6aaf11d64c650 languageName: node linkType: hard -"color@npm:^3.0.0": - version: 3.2.1 - resolution: "color@npm:3.2.1" - dependencies: - color-convert: ^1.9.3 - color-string: ^1.6.0 - checksum: f81220e8b774d35865c2561be921f5652117638dcda7ca4029262046e37fc2444ac7bbfdd110cf1fd9c074a4ee5eda8f85944ffbdda26186b602dd9bb05f6400 +"colorette@npm:^2.0.10": + version: 2.0.20 + resolution: "colorette@npm:2.0.20" + checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d languageName: node linkType: hard -"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8": +"combined-stream@npm:^1.0.8": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" dependencies: @@ -6680,10 +8682,10 @@ __metadata: languageName: node linkType: hard -"comma-separated-tokens@npm:^1.0.0": - version: 1.0.8 - resolution: "comma-separated-tokens@npm:1.0.8" - checksum: 0adcb07174fa4d08cf0f5c8e3aec40a36b5ff0c2c720e5e23f50fe02e6789d1d00a67036c80e0c1e1539f41d3e7f0101b074039dd833b4e4a59031b659d6ca0d +"comma-separated-tokens@npm:^2.0.0": + version: 2.0.3 + resolution: "comma-separated-tokens@npm:2.0.3" + checksum: e3bf9e0332a5c45f49b90e79bcdb4a7a85f28d6a6f0876a94f1bb9b2bfbdbbb9292aac50e1e742d8c0db1e62a0229a106f57917e2d067fca951d81737651700d languageName: node linkType: hard @@ -6694,13 +8696,27 @@ __metadata: languageName: node linkType: hard -"commander@npm:^4.1.1": +"commander@npm:^4.0.0": version: 4.1.1 resolution: "commander@npm:4.1.1" checksum: d7b9913ff92cae20cb577a4ac6fcc121bd6223319e54a40f51a14740a681ad5c574fd29a57da478a5f234a6fa6c52cbf0b7c641353e03c648b1ae85ba670b977 languageName: node linkType: hard +"commander@npm:^7.2.0": + version: 7.2.0 + resolution: "commander@npm:7.2.0" + checksum: 53501cbeee61d5157546c0bef0fedb6cdfc763a882136284bed9a07225f09a14b82d2a84e7637edfd1a679fb35ed9502fd58ef1d091e6287f60d790147f68ddc + languageName: node + linkType: hard + +"commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 0f82321821fc27b83bd409510bb9deeebcfa799ff0bf5d102128b500b7af22872c0c92cb6a0ebc5a4cf19c6b550fba9cedfa7329d18c6442a625f851377bacf0 + languageName: node + linkType: hard + "common-tags@npm:^1.8.0": version: 1.8.2 resolution: "common-tags@npm:1.8.2" @@ -6715,23 +8731,14 @@ __metadata: languageName: node linkType: hard -"component-emitter@npm:^1.2.1, component-emitter@npm:^1.3.0": +"component-emitter@npm:^1.3.0": version: 1.3.1 resolution: "component-emitter@npm:1.3.1" checksum: 94550aa462c7bd5a61c1bc480e28554aa306066930152d1b1844a0dd3845d4e5db7e261ddec62ae184913b3e59b55a2ad84093b9d3596a8f17c341514d6c483d languageName: node linkType: hard -"compose-function@npm:3.0.3": - version: 3.0.3 - resolution: "compose-function@npm:3.0.3" - dependencies: - arity-n: ^1.0.4 - checksum: 9f17d431e3ee4797c844f2870e13494079882ac3dbc54c143b7d99967b371908e0ce7ceb71c6aed61e2ecddbcd7bb437d91428a3d0e6569aee17a87fcbc7918f - languageName: node - linkType: hard - -"compressible@npm:~2.0.16": +"compressible@npm:~2.0.18": version: 2.0.18 resolution: "compressible@npm:2.0.18" dependencies: @@ -6741,17 +8748,17 @@ __metadata: linkType: hard "compression@npm:^1.7.4": - version: 1.7.4 - resolution: "compression@npm:1.7.4" + version: 1.8.1 + resolution: "compression@npm:1.8.1" dependencies: - accepts: ~1.3.5 - bytes: 3.0.0 - compressible: ~2.0.16 + bytes: 3.1.2 + compressible: ~2.0.18 debug: 2.6.9 - on-headers: ~1.0.2 - safe-buffer: 5.1.2 + negotiator: ~0.6.4 + on-headers: ~1.1.0 + safe-buffer: 5.2.1 vary: ~1.1.2 - checksum: 35c0f2eb1f28418978615dc1bc02075b34b1568f7f56c62d60f4214d4b7cc00d0f6d282b5f8a954f59872396bd770b6b15ffd8aa94c67d4bce9b8887b906999b + checksum: 906325935180cd3507d30ed898fb129deccab03689383d55536245a94610f5003923bb14c95ee6adc8d658ee13be549407eb4346ef55169045f3e41e9969808e languageName: node linkType: hard @@ -6762,7 +8769,7 @@ __metadata: languageName: node linkType: hard -"concat-stream@npm:^1.5.0, concat-stream@npm:^1.5.2": +"concat-stream@npm:^1.5.2": version: 1.6.2 resolution: "concat-stream@npm:1.6.2" dependencies: @@ -6786,50 +8793,34 @@ __metadata: languageName: node linkType: hard -"concurrently@npm:^5.2.0": - version: 5.3.0 - resolution: "concurrently@npm:5.3.0" +"concurrently@npm:^9.1.0": + version: 9.2.1 + resolution: "concurrently@npm:9.2.1" dependencies: - chalk: ^2.4.2 - date-fns: ^2.0.1 - lodash: ^4.17.15 - read-pkg: ^4.0.1 - rxjs: ^6.5.2 - spawn-command: ^0.0.2-1 - supports-color: ^6.1.0 - tree-kill: ^1.2.2 - yargs: ^13.3.0 + chalk: 4.1.2 + rxjs: 7.8.2 + shell-quote: 1.8.3 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 bin: - concurrently: bin/concurrently.js - checksum: e12f32eab48e50fc5b7752dc43db7c78f5b553efc625d3b8741c3dd3088ba0050cb8e506f008c8a5fe30d7980849639d12b359a5aea88fd16707a0161b05babb - languageName: node - linkType: hard - -"confbox@npm:^0.1.7": - version: 0.1.7 - resolution: "confbox@npm:0.1.7" - checksum: bde836c26f5154a348b0c0a757f8a0138929e5737e0553be3c4f07a056abca618b861aa63ac3b22d344789b56be99a1382928933e08cd500df00213bf4d8fb43 + conc: dist/bin/concurrently.js + concurrently: dist/bin/concurrently.js + checksum: 95c6cdde21b6304d53005d872318805f69e153d4cedfd4d720cc5776f56fbd073b38297cfe56bacfc8fbdba9b6c38ac1233739abd25b023761fd03b896a4cea5 languageName: node linkType: hard -"confusing-browser-globals@npm:^1.0.10": +"confusing-browser-globals@npm:^1.0.11": version: 1.0.11 resolution: "confusing-browser-globals@npm:1.0.11" checksum: 3afc635abd37e566477f610e7978b15753f0e84025c25d49236f1f14d480117185516bdd40d2a2167e6bed8048641a9854964b9c067e3dcdfa6b5d0ad3c3a5ef languageName: node linkType: hard -"connect-history-api-fallback@npm:^1.6.0": - version: 1.6.0 - resolution: "connect-history-api-fallback@npm:1.6.0" - checksum: 804ca2be28c999032ecd37a9f71405e5d7b7a4b3defcebbe41077bb8c5a0a150d7b59f51dcc33b2de30bc7e217a31d10f8cfad27e8e74c2fc7655eeba82d6e7e - languageName: node - linkType: hard - -"console-browserify@npm:^1.1.0": - version: 1.2.0 - resolution: "console-browserify@npm:1.2.0" - checksum: 226591eeff8ed68e451dffb924c1fb750c654d54b9059b3b261d360f369d1f8f70650adecf2c7136656236a4bfeb55c39281b5d8a55d792ebbb99efd3d848d52 +"connect-history-api-fallback@npm:^2.0.0": + version: 2.0.0 + resolution: "connect-history-api-fallback@npm:2.0.0" + checksum: dc5368690f4a5c413889792f8df70d5941ca9da44523cde3f87af0745faee5ee16afb8195434550f0504726642734f2683d6c07f8b460f828a12c45fbd4c9a68 languageName: node linkType: hard @@ -6844,13 +8835,6 @@ __metadata: languageName: node linkType: hard -"constants-browserify@npm:^1.0.0": - version: 1.0.0 - resolution: "constants-browserify@npm:1.0.0" - checksum: f7ac8c6d0b6e4e0c77340a1d47a3574e25abd580bfd99ad707b26ff7618596cf1a5e5ce9caf44715e9e01d4a5d12cb3b4edaf1176f34c19adb2874815a56e64f - languageName: node - linkType: hard - "content-disposition@npm:0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" @@ -6860,26 +8844,19 @@ __metadata: languageName: node linkType: hard -"content-type@npm:~1.0.4, content-type@npm:~1.0.5": - version: 1.0.5 - resolution: "content-type@npm:1.0.5" - checksum: 566271e0a251642254cde0f845f9dd4f9856e52d988f4eb0d0dcffbb7a1f8ec98de7a5215fc628f3bce30fe2fb6fd2bc064b562d721658c59b544e2d34ea2766 - languageName: node - linkType: hard - -"convert-source-map@npm:1.7.0": - version: 1.7.0 - resolution: "convert-source-map@npm:1.7.0" +"content-disposition@npm:^1.0.0": + version: 1.0.0 + resolution: "content-disposition@npm:1.0.0" dependencies: - safe-buffer: ~5.1.1 - checksum: bcd2e3ea7d37f96b85a6e362c8a89402ccc73757256e3ee53aa2c22fe915adb854c66b1f81111be815a3a6a6ce3c58e8001858e883c9d5b4fe08a853fa865967 + safe-buffer: 5.2.1 + checksum: b27e2579fefe0ecf78238bb652fbc750671efce8344f0c6f05235b12433e6a965adb40906df1ac1fdde23e8f9f0e58385e44640e633165420f3f47d830ae0398 languageName: node linkType: hard -"convert-source-map@npm:^0.3.3": - version: 0.3.5 - resolution: "convert-source-map@npm:0.3.5" - checksum: 33b209aa8f33bcaa9a22f2dbf6bfb71f4a429d8e948068d61b6087304e3194c30016d1e02e842184e653b74442c7e2dd2e7db97532b67f556aded3d8b4377a2c +"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": + version: 1.0.5 + resolution: "content-type@npm:1.0.5" + checksum: 566271e0a251642254cde0f845f9dd4f9856e52d988f4eb0d0dcffbb7a1f8ec98de7a5215fc628f3bce30fe2fb6fd2bc064b562d721658c59b544e2d34ea2766 languageName: node linkType: hard @@ -6898,12 +8875,12 @@ __metadata: linkType: hard "cookie-parser@npm:^1.4.5": - version: 1.4.6 - resolution: "cookie-parser@npm:1.4.6" + version: 1.4.7 + resolution: "cookie-parser@npm:1.4.7" dependencies: - cookie: 0.4.1 + cookie: 0.7.2 cookie-signature: 1.0.6 - checksum: 1e5a63aa82e8eb4e02d2977c6902983dee87b02e87ec5ec43ac3cb1e72da354003716570cd5190c0ad9e8a454c9d3237f4ad6e2f16d0902205a96a1c72b77ba5 + checksum: 243fa13f217e793d20a57675e6552beea08c5989fcc68495d543997a31646875335e0e82d687b42dcfd466df57891d22bae7f5ba6ab33b7705ed2dd6eb989105 languageName: node linkType: hard @@ -6914,24 +8891,24 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.4.1": - version: 0.4.1 - resolution: "cookie@npm:0.4.1" - checksum: bd7c47f5d94ab70ccdfe8210cde7d725880d2fcda06d8e375afbdd82de0c8d3b73541996e9ce57d35f67f672c4ee6d60208adec06b3c5fc94cebb85196084cf8 +"cookie-signature@npm:^1.2.1": + version: 1.2.2 + resolution: "cookie-signature@npm:1.2.2" + checksum: 1ad4f9b3907c9f3673a0f0a07c0a23da7909ac6c9204c5d80a0ec102fe50ccc45f27fdf496361840d6c132c5bb0037122c0a381f856d070183d1ebe3e5e041ff languageName: node linkType: hard -"cookie@npm:0.6.0": - version: 0.6.0 - resolution: "cookie@npm:0.6.0" - checksum: f56a7d32a07db5458e79c726b77e3c2eff655c36792f2b6c58d351fb5f61531e5b1ab7f46987150136e366c65213cbe31729e02a3eaed630c3bf7334635fb410 +"cookie@npm:0.7.1": + version: 0.7.1 + resolution: "cookie@npm:0.7.1" + checksum: cec5e425549b3650eb5c3498a9ba3cde0b9cd419e3b36e4b92739d30b4d89e0b678b98c1ddc209ce7cf958cd3215671fd6ac47aec21f10c2a0cc68abd399d8a7 languageName: node linkType: hard -"cookie@npm:^0.4.2": - version: 0.4.2 - resolution: "cookie@npm:0.4.2" - checksum: a00833c998bedf8e787b4c342defe5fa419abd96b32f4464f718b91022586b8f1bafbddd499288e75c037642493c83083da426c6a9080d309e3bd90fd11baa9b +"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:^0.7.2": + version: 0.7.2 + resolution: "cookie@npm:0.7.2" + checksum: 9bf8555e33530affd571ea37b615ccad9b9a34febbf2c950c86787088eb00a8973690833b0f8ebd6b69b753c62669ea60cec89178c1fb007bf0749abed74f93e languageName: node linkType: hard @@ -6942,54 +8919,26 @@ __metadata: languageName: node linkType: hard -"copy-concurrently@npm:^1.0.0": - version: 1.0.5 - resolution: "copy-concurrently@npm:1.0.5" - dependencies: - aproba: ^1.1.1 - fs-write-stream-atomic: ^1.0.8 - iferr: ^0.1.5 - mkdirp: ^0.5.1 - rimraf: ^2.5.4 - run-queue: ^1.0.0 - checksum: 63c169f582e09445260988f697b2d07793d439dfc31e97c8999707bd188dd94d1c7f2ca3533c7786fb75f03a3f2f54ad1ee08055f95f61bb8d2e862498c1d460 - languageName: node - linkType: hard - -"copy-descriptor@npm:^0.1.0": - version: 0.1.1 - resolution: "copy-descriptor@npm:0.1.1" - checksum: d4b7b57b14f1d256bb9aa0b479241048afd7f5bcf22035fc7b94e8af757adeae247ea23c1a774fe44869fd5694efba4a969b88d966766c5245fdee59837fe45b - languageName: node - linkType: hard - -"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.36.1": - version: 3.37.0 - resolution: "core-js-compat@npm:3.37.0" +"core-js-compat@npm:^3.43.0": + version: 3.45.1 + resolution: "core-js-compat@npm:3.45.1" dependencies: - browserslist: ^4.23.0 - checksum: cab5078e98625f889fd9bbbb19e84cb408f31c87e68302d380db0d26ae8e35c1b38cde084358ff345d4aa461af5f3c60d8a913a5b30bff3a83b4b7859374db36 - languageName: node - linkType: hard - -"core-js-pure@npm:^3.30.2": - version: 3.37.0 - resolution: "core-js-pure@npm:3.37.0" - checksum: 206797d88046f4f5a62ecb9a7158bc6ba38127db2239bcbd1e85b2c8cf3cfb9bb3bbc6a312ecf0f87702f87659959d10625aeac74de6336a9303866f7010d364 + browserslist: ^4.25.3 + checksum: 817286f6b7deb90278fd1f46131664fda36b74983e2fc4859a36ae85ef9361868b307964eea0e364251763e415eab7589e9abe2a4ec4d1672c2870f03c52b1ac languageName: node linkType: hard -"core-js@npm:^2.4.0": - version: 2.6.12 - resolution: "core-js@npm:2.6.12" - checksum: 44fa9934a85f8c78d61e0c8b7b22436330471ffe59ec5076fe7f324d6e8cf7f824b14b1c81ca73608b13bdb0fef035bd820989bf059767ad6fa13123bb8bd016 +"core-js-pure@npm:^3.23.3": + version: 3.45.1 + resolution: "core-js-pure@npm:3.45.1" + checksum: 7427bc4c8991acabc537bc30da5da9e7afb12754c7cf59d5271b01d1750d4b216c44e2ea298b4354efa83873eeeff62e71d858e5c9cd0a3a69fea933971a6a8d languageName: node linkType: hard -"core-js@npm:^3.6.5": - version: 3.37.0 - resolution: "core-js@npm:3.37.0" - checksum: 212c3e9b3fc277dbb63739ef58a61c5709ccd0b36f09c3ce6946aa91fa180c60f57f976d4a5fdb9cda0c6cb55417379ba5a008fc3a1384ec94ec8ec61826469d +"core-js@npm:^3.19.2": + version: 3.45.1 + resolution: "core-js@npm:3.45.1" + checksum: 674c79e9c58ed923280cd4afbc3bc4c921b8b11bce70d269f1bd98db484e27f0ff436d1de34e198f27065a10386761b39f110309c471f329fe7376ab0fb32bf6 languageName: node linkType: hard @@ -7010,15 +8959,16 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^5.0.0": - version: 5.2.1 - resolution: "cosmiconfig@npm:5.2.1" +"cosmiconfig@npm:^6.0.0": + version: 6.0.0 + resolution: "cosmiconfig@npm:6.0.0" dependencies: - import-fresh: ^2.0.0 - is-directory: ^0.3.1 - js-yaml: ^3.13.1 - parse-json: ^4.0.0 - checksum: 8b6f1d3c8a5ffdf663a952f17af0761adf210b7a5933d0fe8988f3ca3a1f0e1e5cbbb74d5b419c15933dd2fdcaec31dbc5cc85cb8259a822342b93b529eff89c + "@types/parse-json": ^4.0.0 + import-fresh: ^3.1.0 + parse-json: ^5.0.0 + path-type: ^4.0.0 + yaml: ^1.7.2 + checksum: 8eed7c854b91643ecb820767d0deb038b50780ecc3d53b0b19e03ed8aabed4ae77271198d1ae3d49c3b110867edf679f5faad924820a8d1774144a87cb6f98fc languageName: node linkType: hard @@ -7035,43 +8985,6 @@ __metadata: languageName: node linkType: hard -"create-ecdh@npm:^4.0.0": - version: 4.0.4 - resolution: "create-ecdh@npm:4.0.4" - dependencies: - bn.js: ^4.1.0 - elliptic: ^6.5.3 - checksum: 0dd7fca9711d09e152375b79acf1e3f306d1a25ba87b8ff14c2fd8e68b83aafe0a7dd6c4e540c9ffbdd227a5fa1ad9b81eca1f233c38bb47770597ba247e614b - languageName: node - linkType: hard - -"create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": - version: 1.2.0 - resolution: "create-hash@npm:1.2.0" - dependencies: - cipher-base: ^1.0.1 - inherits: ^2.0.1 - md5.js: ^1.3.4 - ripemd160: ^2.0.1 - sha.js: ^2.4.0 - checksum: 02a6ae3bb9cd4afee3fabd846c1d8426a0e6b495560a977ba46120c473cb283be6aa1cace76b5f927cf4e499c6146fb798253e48e83d522feba807d6b722eaa9 - languageName: node - linkType: hard - -"create-hmac@npm:^1.1.0, create-hmac@npm:^1.1.4, create-hmac@npm:^1.1.7": - version: 1.1.7 - resolution: "create-hmac@npm:1.1.7" - dependencies: - cipher-base: ^1.0.3 - create-hash: ^1.1.0 - inherits: ^2.0.1 - ripemd160: ^2.0.0 - safe-buffer: ^5.0.1 - sha.js: ^2.4.8 - checksum: ba12bb2257b585a0396108c72830e85f882ab659c3320c83584b1037f8ab72415095167ced80dc4ce8e446a8ecc4b2acf36d87befe0707d73b26cf9dc77440ed - languageName: node - linkType: hard - "create-require@npm:^1.1.0": version: 1.1.1 resolution: "create-require@npm:1.1.1" @@ -7079,140 +8992,125 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:7.0.3, cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": - version: 7.0.3 - resolution: "cross-spawn@npm:7.0.3" +"cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" dependencies: path-key: ^3.1.0 shebang-command: ^2.0.0 which: ^2.0.1 - checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 - languageName: node - linkType: hard - -"cross-spawn@npm:^6.0.0": - version: 6.0.5 - resolution: "cross-spawn@npm:6.0.5" - dependencies: - nice-try: ^1.0.4 - path-key: ^2.0.1 - semver: ^5.5.0 - shebang-command: ^1.2.0 - which: ^1.2.9 - checksum: f893bb0d96cd3d5751d04e67145bdddf25f99449531a72e82dcbbd42796bbc8268c1076c6b3ea51d4d455839902804b94bc45dfb37ecbb32ea8e54a6741c3ab9 - languageName: node - linkType: hard - -"crypto-browserify@npm:^3.11.0": - version: 3.12.0 - resolution: "crypto-browserify@npm:3.12.0" - dependencies: - browserify-cipher: ^1.0.0 - browserify-sign: ^4.0.0 - create-ecdh: ^4.0.0 - create-hash: ^1.1.0 - create-hmac: ^1.1.0 - diffie-hellman: ^5.0.0 - inherits: ^2.0.1 - pbkdf2: ^3.0.3 - public-encrypt: ^4.0.0 - randombytes: ^2.0.0 - randomfill: ^1.0.3 - checksum: c1609af82605474262f3eaa07daa0b2140026bd264ab316d4bf1170272570dbe02f0c49e29407fe0d3634f96c507c27a19a6765fb856fed854a625f9d15618e2 + checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b languageName: node linkType: hard -"crypto-random-string@npm:^1.0.0": - version: 1.0.0 - resolution: "crypto-random-string@npm:1.0.0" - checksum: 6fc61a46c18547b49a93da24f4559c4a1c859f4ee730ecc9533c1ba89fa2a9e9d81f390c2789467afbbd0d1c55a6e96a71e4716b6cd3e77736ed5fced7a2df9a +"crypto-random-string@npm:^2.0.0": + version: 2.0.0 + resolution: "crypto-random-string@npm:2.0.0" + checksum: 0283879f55e7c16fdceacc181f87a0a65c53bc16ffe1d58b9d19a6277adcd71900d02bb2c4843dd55e78c51e30e89b0fec618a7f170ebcc95b33182c28f05fd6 languageName: node linkType: hard -"css-blank-pseudo@npm:^0.1.4": - version: 0.1.4 - resolution: "css-blank-pseudo@npm:0.1.4" +"css-blank-pseudo@npm:^3.0.3": + version: 3.0.3 + resolution: "css-blank-pseudo@npm:3.0.3" dependencies: - postcss: ^7.0.5 + postcss-selector-parser: ^6.0.9 + peerDependencies: + postcss: ^8.4 bin: - css-blank-pseudo: cli.js - checksum: f995a6ca5dbb867af4b30c3dc872a8f0b27ad120442c34796eef7f9c4dcf014249522aaa0a2da3c101c4afa5d7d376436bb978ae1b2c02deddec283fad30c998 + css-blank-pseudo: dist/cli.cjs + checksum: 9be0a13885a99d8ba9e1f45ea66e801d4da75b58c1c3c516a40772fa3a93ef9952b15dcac0418acbb6c89daaae0572819647701b8e553a02972826e33d4cd67f languageName: node linkType: hard -"css-color-names@npm:0.0.4, css-color-names@npm:^0.0.4": - version: 0.0.4 - resolution: "css-color-names@npm:0.0.4" - checksum: 9c6106320430a9da3a13daab8d8b4def39113edbfb68042444585d9a214af5fd5cb384b9be45124bc75f88261d461b517e00e278f4d2e0ab5a619b182f9f0e2d +"css-box-model@npm:^1.2.1": + version: 1.2.1 + resolution: "css-box-model@npm:1.2.1" + dependencies: + tiny-invariant: ^1.0.6 + checksum: 4d113f26fed6b9150e2c314502d00dabe06f12ae43a01a7e9b6e57f3de49b4281dbb0dc46a1158a7349618f8f34d9250af57cb43d7337e9485e73e6b821e470e languageName: node linkType: hard -"css-declaration-sorter@npm:^4.0.1": - version: 4.0.1 - resolution: "css-declaration-sorter@npm:4.0.1" - dependencies: - postcss: ^7.0.1 - timsort: ^0.3.0 - checksum: c38c00245c6706bd1127a6a2807bbdea3a2621c1f4e4bcb4710f6736c15c4ec414e02213adeab2171623351616090cb96374f683b90ec2aad18903066c4526d7 +"css-declaration-sorter@npm:^6.3.1": + version: 6.4.1 + resolution: "css-declaration-sorter@npm:6.4.1" + peerDependencies: + postcss: ^8.0.9 + checksum: cbdc9e0d481011b1a28fd5b60d4eb55fe204391d31a0b1b490b2cecf4baa85810f9b8c48adab4df644f4718104ed3ed72c64a9745e3216173767bf4aeca7f9b8 languageName: node linkType: hard -"css-has-pseudo@npm:^0.10.0": - version: 0.10.0 - resolution: "css-has-pseudo@npm:0.10.0" +"css-has-pseudo@npm:^3.0.4": + version: 3.0.4 + resolution: "css-has-pseudo@npm:3.0.4" dependencies: - postcss: ^7.0.6 - postcss-selector-parser: ^5.0.0-rc.4 + postcss-selector-parser: ^6.0.9 + peerDependencies: + postcss: ^8.4 bin: - css-has-pseudo: cli.js - checksum: 88d891ba18f821e8a94d821ecdd723c606019462664c7d86e7d8731622bd26f9d55582e494bcc2a62f9399cc7b89049ddc8a9d1e8f1bf1a133c2427739d2d334 + css-has-pseudo: dist/cli.cjs + checksum: 8f165d68f6621891d9fa1d874794916a52ed8847dfbec591523ad68774650cc1eae062ba08f59514666e04aeba27be72c9b211892f3a187c5ba6e287bd4260e7 languageName: node linkType: hard -"css-loader@npm:4.3.0": - version: 4.3.0 - resolution: "css-loader@npm:4.3.0" - dependencies: - camelcase: ^6.0.0 - cssesc: ^3.0.0 - icss-utils: ^4.1.1 - loader-utils: ^2.0.0 - postcss: ^7.0.32 - postcss-modules-extract-imports: ^2.0.0 - postcss-modules-local-by-default: ^3.0.3 - postcss-modules-scope: ^2.2.0 - postcss-modules-values: ^3.0.0 - postcss-value-parser: ^4.1.0 - schema-utils: ^2.7.1 - semver: ^7.3.2 +"css-loader@npm:^6.5.1": + version: 6.11.0 + resolution: "css-loader@npm:6.11.0" + 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 peerDependencies: - webpack: ^4.27.0 || ^5.0.0 - checksum: 697a8838f0975f86c634e7a920572604879a9738128fcc01e5393fae5ac9a7a1a925c0d14ebb6ed67fa7e14bd17849eec152a99e3299cc92f422f6b0cd4eff73 + "@rspack/core": 0.x || 1.x + webpack: ^5.0.0 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 5c8d35975a7121334905394e88e28f05df72f037dbed2fb8fec4be5f0b313ae73a13894ba791867d4a4190c35896da84a7fd0c54fb426db55d85ba5e714edbe3 languageName: node linkType: hard -"css-modules-loader-core@npm:^1.1.0": - version: 1.1.0 - resolution: "css-modules-loader-core@npm:1.1.0" +"css-minimizer-webpack-plugin@npm:^3.2.0": + version: 3.4.1 + resolution: "css-minimizer-webpack-plugin@npm:3.4.1" dependencies: - icss-replace-symbols: 1.1.0 - postcss: 6.0.1 - postcss-modules-extract-imports: 1.1.0 - postcss-modules-local-by-default: 1.2.0 - postcss-modules-scope: 1.1.0 - postcss-modules-values: 1.3.0 - checksum: e2d513cee6a407b46806e50b3eec9d9034355b6ee14f2f7303353ab0853b8dba9600cffc83ec46cebd3efd68fe2b2aa31808a1c906d043f1c405568fd484eaf5 + cssnano: ^5.0.6 + jest-worker: ^27.0.2 + postcss: ^8.3.5 + schema-utils: ^4.0.0 + serialize-javascript: ^6.0.0 + source-map: ^0.6.1 + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + "@parcel/css": + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + checksum: 065c6c1eadb7c99267db5d04d6f3909e9968b73c4cb79ab9e4502a5fbf1a3d564cfe6f8e0bff8e4ab00d4ed233e9c3c76a4ebe0ee89150b3d9ecb064ddf1e5e9 languageName: node linkType: hard -"css-prefers-color-scheme@npm:^3.1.1": - version: 3.1.1 - resolution: "css-prefers-color-scheme@npm:3.1.1" - dependencies: - postcss: ^7.0.5 +"css-prefers-color-scheme@npm:^6.0.3": + version: 6.0.3 + resolution: "css-prefers-color-scheme@npm:6.0.3" + peerDependencies: + postcss: ^8.4 bin: - css-prefers-color-scheme: cli.js - checksum: ba69a86b006818ffe3548bcbeb5e4e8139b8b6cf45815a3b3dddd12cd9acf3d8ac3b94e63fe0abd34e0683cf43ed8c2344e3bd472bbf02a6eb40c7bbf565d587 + css-prefers-color-scheme: dist/cli.cjs + checksum: 3a2b02f0454adda68861cdcaf6a0d11f462eadf165301cba61c5ec7c5f229ac261c5baa54c377d9b811ec5f21b30d72a02bc032cdad2415b3a566f08a0c47b3a languageName: node linkType: hard @@ -7248,16 +9146,6 @@ __metadata: languageName: node linkType: hard -"css-selector-tokenizer@npm:^0.7.0": - version: 0.7.3 - resolution: "css-selector-tokenizer@npm:0.7.3" - dependencies: - cssesc: ^3.0.0 - fastparse: ^1.1.2 - checksum: 92560a9616a8bc073b88c678aa04f22c599ac23c5f8587e60f4861069e2d5aeb37b722af581ae3c5fbce453bed7a893d9c3e06830912e6d28badc3b8b99acd24 - languageName: node - linkType: hard - "css-tree@npm:1.0.0-alpha.37": version: 1.0.0-alpha.37 resolution: "css-tree@npm:1.0.0-alpha.37" @@ -7268,7 +9156,7 @@ __metadata: languageName: node linkType: hard -"css-tree@npm:^1.1.2": +"css-tree@npm:^1.1.2, css-tree@npm:^1.1.3": version: 1.1.3 resolution: "css-tree@npm:1.1.3" dependencies: @@ -7286,9 +9174,9 @@ __metadata: linkType: hard "css-what@npm:^6.0.1": - version: 6.1.0 - resolution: "css-what@npm:6.1.0" - checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe + version: 6.2.2 + resolution: "css-what@npm:6.2.2" + checksum: 4d1f07b348a638e1f8b4c72804a1e93881f35e0f541256aec5ac0497c5855df7db7ab02da030de950d4813044f6d029a14ca657e0f92c3987e4b604246235b2b languageName: node linkType: hard @@ -7299,31 +9187,10 @@ __metadata: languageName: node linkType: hard -"css@npm:^2.0.0": - version: 2.2.4 - resolution: "css@npm:2.2.4" - dependencies: - inherits: ^2.0.3 - source-map: ^0.6.1 - source-map-resolve: ^0.5.2 - urix: ^0.1.0 - checksum: a35d483c5ccc04bcde3b1e7393d58ad3eee1dd6956df0f152de38e46a17c0ee193c30eec6b1e59831ad0e74599385732000e95987fcc9cb2b16c6d951bae49e1 - languageName: node - linkType: hard - -"cssdb@npm:^4.4.0": - version: 4.4.0 - resolution: "cssdb@npm:4.4.0" - checksum: 521dd2135da1ab93612a4161eb1024cfc7b155a35d95f9867d328cc88ad57fdd959aa88ea8f4e6cea3a82bca91b76570dc1abb18bfd902c6889973956a03e497 - languageName: node - linkType: hard - -"cssesc@npm:^2.0.0": - version: 2.0.0 - resolution: "cssesc@npm:2.0.0" - bin: - cssesc: bin/cssesc - checksum: 5e50886c2aca3f492fe808dbd146d30eb1c6f31fbe6093979a8376e39d171d989279199f6f3f1a42464109e082e0e42bc33eeff9467fb69bf346f5ba5853c3c6 +"cssdb@npm:^7.1.0": + version: 7.11.2 + resolution: "cssdb@npm:7.11.2" + checksum: 79b2c3b6de1d80c7f3e40f28c06138b7f1ca27fe5d9173195cc781d8acc0261c2bdeccdf141bd035b13709655cf724c8ad4757ddf12a3d21b6d002368c9cb027 languageName: node linkType: hard @@ -7336,87 +9203,68 @@ __metadata: languageName: node linkType: hard -"cssnano-preset-default@npm:^4.0.8": - version: 4.0.8 - resolution: "cssnano-preset-default@npm:4.0.8" - dependencies: - css-declaration-sorter: ^4.0.1 - cssnano-util-raw-cache: ^4.0.1 - postcss: ^7.0.0 - postcss-calc: ^7.0.1 - postcss-colormin: ^4.0.3 - postcss-convert-values: ^4.0.1 - postcss-discard-comments: ^4.0.2 - postcss-discard-duplicates: ^4.0.2 - postcss-discard-empty: ^4.0.1 - postcss-discard-overridden: ^4.0.1 - postcss-merge-longhand: ^4.0.11 - postcss-merge-rules: ^4.0.3 - postcss-minify-font-values: ^4.0.2 - postcss-minify-gradients: ^4.0.2 - postcss-minify-params: ^4.0.2 - postcss-minify-selectors: ^4.0.2 - postcss-normalize-charset: ^4.0.1 - postcss-normalize-display-values: ^4.0.2 - postcss-normalize-positions: ^4.0.2 - postcss-normalize-repeat-style: ^4.0.2 - postcss-normalize-string: ^4.0.2 - postcss-normalize-timing-functions: ^4.0.2 - postcss-normalize-unicode: ^4.0.1 - postcss-normalize-url: ^4.0.1 - postcss-normalize-whitespace: ^4.0.2 - postcss-ordered-values: ^4.1.2 - postcss-reduce-initial: ^4.0.3 - postcss-reduce-transforms: ^4.0.2 - postcss-svgo: ^4.0.3 - postcss-unique-selectors: ^4.0.1 - checksum: eb32c9fdd8bd4683e33d62284b6a9c4eb705b745235f4bb51a5571e1eb6738f636958fc9a6218fb51de43e0e2f74386a705b4c7ff2d1dcc611647953ba6ce159 - languageName: node - linkType: hard - -"cssnano-util-get-arguments@npm:^4.0.0": - version: 4.0.0 - resolution: "cssnano-util-get-arguments@npm:4.0.0" - checksum: 34222a1e848d573b74892eda7d7560c5422efa56f87d2b5242f9791593c6aa4ddc9d55e8e1708fb2f0d6f87c456314b78d93d3eec97d946ff756c63b09b72222 - languageName: node - linkType: hard - -"cssnano-util-get-match@npm:^4.0.0": - version: 4.0.0 - resolution: "cssnano-util-get-match@npm:4.0.0" - checksum: 56eacea0eb3d923359c9714ab25edde5eb4859e495954615d5529e81cdfabc2d41b57055c7f6a2f08e7d89df3a2794ef659306b539505d7f4e7202b897396fc2 - languageName: node - linkType: hard - -"cssnano-util-raw-cache@npm:^4.0.1": - version: 4.0.1 - resolution: "cssnano-util-raw-cache@npm:4.0.1" - dependencies: - postcss: ^7.0.0 - checksum: 66a23e5e5255ff65d0f49f135d0ddfdb96433aeceb2708a31e4b4a652110755f103f6c91e0f439c8f3052818eb2b04ebf6334680a810296290e2c3467c14202b +"cssnano-preset-default@npm:^5.2.14": + version: 5.2.14 + resolution: "cssnano-preset-default@npm:5.2.14" + dependencies: + css-declaration-sorter: ^6.3.1 + cssnano-utils: ^3.1.0 + postcss-calc: ^8.2.3 + postcss-colormin: ^5.3.1 + postcss-convert-values: ^5.1.3 + postcss-discard-comments: ^5.1.2 + postcss-discard-duplicates: ^5.1.0 + postcss-discard-empty: ^5.1.1 + postcss-discard-overridden: ^5.1.0 + postcss-merge-longhand: ^5.1.7 + postcss-merge-rules: ^5.1.4 + postcss-minify-font-values: ^5.1.0 + postcss-minify-gradients: ^5.1.1 + postcss-minify-params: ^5.1.4 + postcss-minify-selectors: ^5.2.1 + postcss-normalize-charset: ^5.1.0 + postcss-normalize-display-values: ^5.1.0 + postcss-normalize-positions: ^5.1.1 + postcss-normalize-repeat-style: ^5.1.1 + postcss-normalize-string: ^5.1.0 + postcss-normalize-timing-functions: ^5.1.0 + postcss-normalize-unicode: ^5.1.1 + postcss-normalize-url: ^5.1.0 + postcss-normalize-whitespace: ^5.1.1 + postcss-ordered-values: ^5.1.3 + postcss-reduce-initial: ^5.1.2 + postcss-reduce-transforms: ^5.1.0 + postcss-svgo: ^5.1.0 + postcss-unique-selectors: ^5.1.1 + peerDependencies: + postcss: ^8.2.15 + checksum: d3bbbe3d50c6174afb28d0bdb65b511fdab33952ec84810aef58b87189f3891c34aaa8b6a6101acd5314f8acded839b43513e39a75f91a698ddc985a1b1d9e95 languageName: node linkType: hard -"cssnano-util-same-parent@npm:^4.0.0": - version: 4.0.1 - resolution: "cssnano-util-same-parent@npm:4.0.1" - checksum: 97c6b3f670ee9d1d6342b6a1daf9867d5c08644365dc146bd76defd356069112148e382ca86fc3e6c55adf0687974f03535bba34df95efb468b266d2319c7b66 +"cssnano-utils@npm:^3.1.0": + version: 3.1.0 + resolution: "cssnano-utils@npm:3.1.0" + peerDependencies: + postcss: ^8.2.15 + checksum: 975c84ce9174cf23bb1da1e9faed8421954607e9ea76440cd3bb0c1bea7e17e490d800fca5ae2812d1d9e9d5524eef23ede0a3f52497d7ccc628e5d7321536f2 languageName: node linkType: hard -"cssnano@npm:^4.1.10": - version: 4.1.11 - resolution: "cssnano@npm:4.1.11" +"cssnano@npm:^5.0.6": + version: 5.1.15 + resolution: "cssnano@npm:5.1.15" dependencies: - cosmiconfig: ^5.0.0 - cssnano-preset-default: ^4.0.8 - is-resolvable: ^1.0.0 - postcss: ^7.0.0 - checksum: 2453fbe9f9f9e2ffe87dc5c718578f1b801fc7b82eaad12f5564c84bb0faf1774ea52e01874ecd29d1782aa7d0d84f0dbc95001eed9866ebd9bc523638999c9b + cssnano-preset-default: ^5.2.14 + lilconfig: ^2.0.3 + yaml: ^1.10.2 + peerDependencies: + postcss: ^8.2.15 + checksum: ca9e1922178617c66c2f1548824b2c7af2ecf69cc3a187fc96bf8d29251c2e84d9e4966c69cf64a2a6a057a37dff7d6d057bc8a2a0957e6ea382e452ae9d0bbb languageName: node linkType: hard -"csso@npm:^4.0.2": +"csso@npm:^4.0.2, csso@npm:^4.2.0": version: 4.2.0 resolution: "csso@npm:4.2.0" dependencies: @@ -7455,29 +9303,105 @@ __metadata: languageName: node linkType: hard -"customize-cra@npm:^0.9.1": - version: 0.9.1 - resolution: "customize-cra@npm:0.9.1" +"customize-cra@npm:^1.0.0": + version: 1.0.0 + resolution: "customize-cra@npm:1.0.0" dependencies: lodash.flow: ^3.5.0 - checksum: d616e4c21f231860b7cad445a52ec5c2b658c4fba9db35f4f60d943d00caeecb140562f89f4ef901b6ef4d6b16f3b6bddff3802358389ae1ab0f0eef936a66ab + checksum: b38c48a607efc2321e6f2f12a3b53f3497b2f9b0008b48242524a92a1f26f8ae50bd73c97526e7d89c32b51f53711948e0da8f7e3618c9875087227a11a5feeb languageName: node linkType: hard -"cyclist@npm:^1.0.1": - version: 1.0.2 - resolution: "cyclist@npm:1.0.2" - checksum: d7c0336565b9b72ee72347831cbd05fadcc59cc9ab89dcf38293b1a64c2c5fb777c9ce44967390dabe8235f9898f5cb222cd6672f4920b757da8861310082716 +"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6": + version: 3.2.4 + resolution: "d3-array@npm:3.2.4" + dependencies: + internmap: 1 - 2 + checksum: a5976a6d6205f69208478bb44920dd7ce3e788c9dceb86b304dbe401a4bfb42ecc8b04c20facde486e9adcb488b5d1800d49393a3f81a23902b68158e12cddd0 languageName: node linkType: hard -"d@npm:1, d@npm:^1.0.1, d@npm:^1.0.2": - version: 1.0.2 - resolution: "d@npm:1.0.2" +"d3-color@npm:1 - 3": + version: 3.1.0 + resolution: "d3-color@npm:3.1.0" + checksum: 4931fbfda5d7c4b5cfa283a13c91a954f86e3b69d75ce588d06cde6c3628cebfc3af2069ccf225e982e8987c612aa7948b3932163ce15eb3c11cd7c003f3ee3b + languageName: node + linkType: hard + +"d3-ease@npm:^3.0.1": + version: 3.0.1 + resolution: "d3-ease@npm:3.0.1" + checksum: 06e2ee5326d1e3545eab4e2c0f84046a123dcd3b612e68858219aa034da1160333d9ce3da20a1d3486d98cb5c2a06f7d233eee1bc19ce42d1533458bd85dedcd + languageName: node + linkType: hard + +"d3-format@npm:1 - 3": + version: 3.1.0 + resolution: "d3-format@npm:3.1.0" + checksum: f345ec3b8ad3cab19bff5dead395bd9f5590628eb97a389b1dd89f0b204c7c4fc1d9520f13231c2c7cf14b7c9a8cf10f8ef15bde2befbab41454a569bd706ca2 + languageName: node + linkType: hard + +"d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:^3.0.1": + version: 3.0.1 + resolution: "d3-interpolate@npm:3.0.1" + dependencies: + d3-color: 1 - 3 + checksum: a42ba314e295e95e5365eff0f604834e67e4a3b3c7102458781c477bd67e9b24b6bb9d8e41ff5521050a3f2c7c0c4bbbb6e187fd586daa3980943095b267e78b + languageName: node + linkType: hard + +"d3-path@npm:^3.1.0": + version: 3.1.0 + resolution: "d3-path@npm:3.1.0" + checksum: 2306f1bd9191e1eac895ec13e3064f732a85f243d6e627d242a313f9777756838a2215ea11562f0c7630c7c3b16a19ec1fe0948b1c82f3317fac55882f6ee5d8 + languageName: node + linkType: hard + +"d3-scale@npm:^4.0.2": + version: 4.0.2 + resolution: "d3-scale@npm:4.0.2" + dependencies: + d3-array: 2.10.0 - 3 + d3-format: 1 - 3 + d3-interpolate: 1.2.0 - 3 + d3-time: 2.1.1 - 3 + d3-time-format: 2 - 4 + checksum: a9c770d283162c3bd11477c3d9d485d07f8db2071665f1a4ad23eec3e515e2cefbd369059ec677c9ac849877d1a765494e90e92051d4f21111aa56791c98729e + languageName: node + linkType: hard + +"d3-shape@npm:^3.1.0": + version: 3.2.0 + resolution: "d3-shape@npm:3.2.0" + dependencies: + d3-path: ^3.1.0 + checksum: de2af5fc9a93036a7b68581ca0bfc4aca2d5a328aa7ba7064c11aedd44d24f310c20c40157cb654359d4c15c3ef369f95ee53d71221017276e34172c7b719cfa + languageName: node + linkType: hard + +"d3-time-format@npm:2 - 4": + version: 4.1.0 + resolution: "d3-time-format@npm:4.1.0" + dependencies: + d3-time: 1 - 3 + checksum: 7342bce28355378152bbd4db4e275405439cabba082d9cd01946d40581140481c8328456d91740b0fe513c51ec4a467f4471ffa390c7e0e30ea30e9ec98fcdf4 + languageName: node + linkType: hard + +"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:^3.0.0": + version: 3.1.0 + resolution: "d3-time@npm:3.1.0" dependencies: - es5-ext: ^0.10.64 - type: ^2.7.2 - checksum: 775db1e8ced6707cddf64a5840522fcf5475d38ef49a5d615be0ac47f86ef64d15f5a73de1522b09327cc466d4dc35ea83dbfeed456f7a0fdcab138deb800355 + d3-array: 2 - 3 + checksum: 613b435352a78d9f31b7f68540788186d8c331b63feca60ad21c88e9db1989fe888f97f242322ebd6365e45ec3fb206a4324cd4ca0dfffa1d9b5feb856ba00a7 + languageName: node + linkType: hard + +"d3-timer@npm:^3.0.1": + version: 3.0.1 + resolution: "d3-timer@npm:3.0.1" + checksum: 1cfddf86d7bca22f73f2c427f52dfa35c49f50d64e187eb788dcad6e927625c636aa18ae4edd44d084eb9d1f81d8ca4ec305dae7f733c15846a824575b789d73 languageName: node linkType: hard @@ -7499,63 +9423,54 @@ __metadata: languageName: node linkType: hard -"data-view-buffer@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-buffer@npm:1.0.1" +"data-view-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "data-view-buffer@npm:1.0.2" dependencies: - call-bind: ^1.0.6 + call-bound: ^1.0.3 es-errors: ^1.3.0 - is-data-view: ^1.0.1 - checksum: ce24348f3c6231223b216da92e7e6a57a12b4af81a23f27eff8feabdf06acfb16c00639c8b705ca4d167f761cfc756e27e5f065d0a1f840c10b907fdaf8b988c + is-data-view: ^1.0.2 + checksum: 1e1cd509c3037ac0f8ba320da3d1f8bf1a9f09b0be09394b5e40781b8cc15ff9834967ba7c9f843a425b34f9fe14ce44cf055af6662c44263424c1eb8d65659b languageName: node linkType: hard -"data-view-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-byte-length@npm:1.0.1" +"data-view-byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "data-view-byte-length@npm:1.0.2" dependencies: - call-bind: ^1.0.7 + call-bound: ^1.0.3 es-errors: ^1.3.0 - is-data-view: ^1.0.1 - checksum: dbb3200edcb7c1ef0d68979834f81d64fd8cab2f7691b3a4c6b97e67f22182f3ec2c8602efd7b76997b55af6ff8bce485829c1feda4fa2165a6b71fb7baa4269 + is-data-view: ^1.0.2 + checksum: 3600c91ced1cfa935f19ef2abae11029e01738de8d229354d3b2a172bf0d7e4ed08ff8f53294b715569fdf72dfeaa96aa7652f479c0f60570878d88e7e8bddf6 languageName: node linkType: hard -"data-view-byte-offset@npm:^1.0.0": - version: 1.0.0 - resolution: "data-view-byte-offset@npm:1.0.0" +"data-view-byte-offset@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-offset@npm:1.0.1" dependencies: - call-bind: ^1.0.6 + call-bound: ^1.0.2 es-errors: ^1.3.0 is-data-view: ^1.0.1 - checksum: 7f0bf8720b7414ca719eedf1846aeec392f2054d7af707c5dc9a753cc77eb8625f067fa901e0b5127e831f9da9056138d894b9c2be79c27a21f6db5824f009c2 + checksum: 8dd492cd51d19970876626b5b5169fbb67ca31ec1d1d3238ee6a71820ca8b80cafb141c485999db1ee1ef02f2cc3b99424c5eda8d59e852d9ebb79ab290eb5ee languageName: node linkType: hard -"date-fns@npm:^2.0.1": - version: 2.30.0 - resolution: "date-fns@npm:2.30.0" - dependencies: - "@babel/runtime": ^7.21.0 - checksum: f7be01523282e9bb06c0cd2693d34f245247a29098527d4420628966a2d9aad154bd0e90a6b1cf66d37adcb769cd108cf8a7bd49d76db0fb119af5cdd13644f4 +"date-fns@npm:^4.1.0": + version: 4.1.0 + resolution: "date-fns@npm:4.1.0" + checksum: fb681b242cccabed45494468f64282a7d375ea970e0adbcc5dcc92dcb7aba49b2081c2c9739d41bf71ce89ed68dd73bebfe06ca35129490704775d091895710b languageName: node linkType: hard "dayjs@npm:^1.11.10": - version: 1.11.10 - resolution: "dayjs@npm:1.11.10" - checksum: a6b5a3813b8884f5cd557e2e6b7fa569f4c5d0c97aca9558e38534af4f2d60daafd3ff8c2000fed3435cfcec9e805bcebd99f90130c6d1c5ef524084ced588c4 - languageName: node - linkType: hard - -"debounce@npm:^1.2.1": - version: 1.2.1 - resolution: "debounce@npm:1.2.1" - checksum: 682a89506d9e54fb109526f4da255c5546102fbb8e3ae75eef3b04effaf5d4853756aee97475cd4650641869794e44f410eeb20ace2b18ea592287ab2038519e + version: 1.11.18 + resolution: "dayjs@npm:1.11.18" + checksum: cc90054bad30ab011417a7a474b2ffa70e7a28ca6f834d7e86fe53a408a40a14c174f26155072628670e9eda4c48c4ed0d847d2edf83d47c0bfb78be15bbf2dd languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0": +"debug@npm:2.6.9, debug@npm:^2.6.0, debug@npm:^2.6.1": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -7564,15 +9479,15 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.3, debug@npm:^4.3.4": - version: 4.3.4 - resolution: "debug@npm:4.3.4" +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": + version: 4.4.3 + resolution: "debug@npm:4.4.3" dependencies: - ms: 2.1.2 + ms: ^2.1.3 peerDependenciesMeta: supports-color: optional: true - checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 + checksum: 4805abd570e601acdca85b6aa3757186084a45cff9b2fa6eee1f3b173caa776b45f478b2a71a572d616d2010cea9211d0ac4a02a610e4c18ac4324bde3760834 languageName: node linkType: hard @@ -7592,17 +9507,35 @@ __metadata: languageName: node linkType: hard +"decimal.js-light@npm:^2.4.1": + version: 2.5.1 + resolution: "decimal.js-light@npm:2.5.1" + checksum: f5a2c7eac1c4541c8ab8a5c8abea64fc1761cefc7794bd5f8afd57a8a78d1b51785e0c4e4f85f4895a043eaa90ddca1edc3981d1263eb6ddce60f32bf5fe66c9 + languageName: node + linkType: hard + "decimal.js@npm:^10.2.1, decimal.js@npm:^10.4.3": - version: 10.4.3 - resolution: "decimal.js@npm:10.4.3" - checksum: 796404dcfa9d1dbfdc48870229d57f788b48c21c603c3f6554a1c17c10195fc1024de338b0cf9e1efe0c7c167eeb18f04548979bcc5fdfabebb7cc0ae3287bae + version: 10.6.0 + resolution: "decimal.js@npm:10.6.0" + checksum: 9302b990cd6f4da1c7602200002e40e15d15660374432963421d3cd6d81cc6e27e0a488356b030fee64650947e32e78bdbea245d596dadfeeeb02e146d485999 languageName: node linkType: hard -"decode-uri-component@npm:^0.2.0": - version: 0.2.2 - resolution: "decode-uri-component@npm:0.2.2" - checksum: 95476a7d28f267292ce745eac3524a9079058bbb35767b76e3ee87d42e34cd0275d2eb19d9d08c3e167f97556e8a2872747f5e65cbebcac8b0c98d83e285f139 +"decode-named-character-reference@npm:^1.0.0": + version: 1.2.0 + resolution: "decode-named-character-reference@npm:1.2.0" + dependencies: + character-entities: ^2.0.0 + checksum: f26b23046c1a137c0b41fa51e3ce07ba8364640322c742a31570999784abc8572fc24cb108a76b14ff72ddb75d35aad3d14b10d7743639112145a2664b9d1864 + languageName: node + linkType: hard + +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: ^3.1.0 + checksum: d377cf47e02d805e283866c3f50d3d21578b779731e8c5072d6ce8c13cc31493db1c2f6784da9d1d5250822120cefa44f1deab112d5981015f2e17444b763812 languageName: node linkType: hard @@ -7613,52 +9546,17 @@ __metadata: languageName: node linkType: hard -"deep-eql@npm:^4.1.3": - version: 4.1.3 - resolution: "deep-eql@npm:4.1.3" - dependencies: - type-detect: ^4.0.0 - checksum: 7f6d30cb41c713973dc07eaadded848b2ab0b835e518a88b91bea72f34e08c4c71d167a722a6f302d3a6108f05afd8e6d7650689a84d5d29ec7fe6220420397f - languageName: node - linkType: hard - -"deep-equal@npm:^1.0.1": - version: 1.1.2 - resolution: "deep-equal@npm:1.1.2" - dependencies: - is-arguments: ^1.1.1 - is-date-object: ^1.0.5 - is-regex: ^1.1.4 - object-is: ^1.1.5 - object-keys: ^1.1.1 - regexp.prototype.flags: ^1.5.1 - checksum: 2d50f27fff785fb272cdef038ee5365ee5a30ab1aab053976e6a6add44cc60abd99b38179a46a01ac52c5e54ebb220e8f1a3a1954da20678b79c46ef4d97c9db +"deep-eql@npm:^5.0.1": + version: 5.0.2 + resolution: "deep-eql@npm:5.0.2" + checksum: 6aaaadb4c19cbce42e26b2bbe5bd92875f599d2602635dc97f0294bae48da79e89470aedee05f449e0ca8c65e9fd7e7872624d1933a1db02713d99c2ca8d1f24 languageName: node linkType: hard -"deep-equal@npm:^2.0.5": - version: 2.2.3 - resolution: "deep-equal@npm:2.2.3" - dependencies: - array-buffer-byte-length: ^1.0.0 - call-bind: ^1.0.5 - es-get-iterator: ^1.1.3 - get-intrinsic: ^1.2.2 - is-arguments: ^1.1.1 - is-array-buffer: ^3.0.2 - is-date-object: ^1.0.5 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - isarray: ^2.0.5 - object-is: ^1.1.5 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.5.1 - side-channel: ^1.0.4 - which-boxed-primitive: ^1.0.2 - which-collection: ^1.0.1 - which-typed-array: ^1.1.13 - checksum: ee8852f23e4d20a5626c13b02f415ba443a1b30b4b3d39eaf366d59c4a85e6545d7ec917db44d476a85ae5a86064f7e5f7af7479f38f113995ba869f3a1ddc53 +"deep-extend@npm:^0.6.0": + version: 0.6.0 + resolution: "deep-extend@npm:0.6.0" + checksum: 7be7e5a8d468d6b10e6a67c3de828f55001b6eb515d014f7aeb9066ce36bd5717161eb47d6a0f7bed8a9083935b465bc163ee2581c8b128d29bf61092fdf57a7 languageName: node linkType: hard @@ -7676,22 +9574,12 @@ __metadata: languageName: node linkType: hard -"default-gateway@npm:^4.2.0": - version: 4.2.0 - resolution: "default-gateway@npm:4.2.0" - dependencies: - execa: ^1.0.0 - ip-regex: ^2.1.0 - checksum: 1f5be765471689c6bab33e0c8b87363c3e2485cc1ab78904d383a8a8293a79f684da2a3303744b112503f986af4ea87d917c63a468ed913e9b0c31588c02d6a4 - languageName: node - linkType: hard - -"defaults@npm:^1.0.3": - version: 1.0.4 - resolution: "defaults@npm:1.0.4" +"default-gateway@npm:^6.0.3": + version: 6.0.3 + resolution: "default-gateway@npm:6.0.3" dependencies: - clone: ^1.0.2 - checksum: 3a88b7a587fc076b84e60affad8b85245c01f60f38fc1d259e7ac1d89eb9ce6abb19e27215de46b98568dd5bc48471730b327637e6f20b0f1bc85cf00440c80a + execa: ^5.0.0 + checksum: 126f8273ecac8ee9ff91ea778e8784f6cd732d77c3157e8c5bdd6ed03651b5291f71446d05bc02d04073b1e67583604db5394ea3cf992ede0088c70ea15b7378 languageName: node linkType: hard @@ -7706,7 +9594,14 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.1.2, define-properties@npm:^1.1.3, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": +"define-lazy-prop@npm:^2.0.0": + version: 2.0.0 + resolution: "define-lazy-prop@npm:2.0.0" + checksum: 0115fdb065e0490918ba271d7339c42453d209d4cb619dfe635870d906731eff3e1ade8028bb461ea27ce8264ec5e22c6980612d332895977e89c1bbc80fcee2 + languageName: node + linkType: hard + +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" dependencies: @@ -7717,49 +9612,6 @@ __metadata: languageName: node linkType: hard -"define-property@npm:^0.2.5": - version: 0.2.5 - resolution: "define-property@npm:0.2.5" - dependencies: - is-descriptor: ^0.1.0 - checksum: 85af107072b04973b13f9e4128ab74ddfda48ec7ad2e54b193c0ffb57067c4ce5b7786a7b4ae1f24bd03e87c5d18766b094571810b314d7540f86d4354dbd394 - languageName: node - linkType: hard - -"define-property@npm:^1.0.0": - version: 1.0.0 - resolution: "define-property@npm:1.0.0" - dependencies: - is-descriptor: ^1.0.0 - checksum: 5fbed11dace44dd22914035ba9ae83ad06008532ca814d7936a53a09e897838acdad5b108dd0688cc8d2a7cf0681acbe00ee4136cf36743f680d10517379350a - languageName: node - linkType: hard - -"define-property@npm:^2.0.2": - version: 2.0.2 - resolution: "define-property@npm:2.0.2" - dependencies: - is-descriptor: ^1.0.2 - isobject: ^3.0.1 - checksum: 3217ed53fc9eed06ba8da6f4d33e28c68a82e2f2a8ab4d562c4920d8169a166fe7271453675e6c69301466f36a65d7f47edf0cf7f474b9aa52a5ead9c1b13c99 - languageName: node - linkType: hard - -"del@npm:^4.1.1": - version: 4.1.1 - resolution: "del@npm:4.1.1" - dependencies: - "@types/glob": ^7.1.1 - globby: ^6.1.0 - is-path-cwd: ^2.0.0 - is-path-in-cwd: ^2.0.0 - p-map: ^2.0.0 - pify: ^4.0.1 - rimraf: ^2.6.3 - checksum: 521f7da44bd79da841c06d573923d1f64f423aee8b8219c973478d3150ce1dcc024d03ad605929292adbff56d6448bca60d96dcdd2d8a53b46dbcb27e265c94b - languageName: node - linkType: hard - "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -7767,7 +9619,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:2.0.0": +"depd@npm:2.0.0, depd@npm:^2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: abbe19c768c97ee2eed6282d8ce3031126662252c58d711f646921c9623f9052e3e1906443066beec1095832f534e57c523b7333f8e7e0d93051ab6baef5ab3a @@ -7780,21 +9632,11 @@ __metadata: checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9 languageName: node linkType: hard - -"dequal@npm:^2.0.3": - version: 2.0.3 - resolution: "dequal@npm:2.0.3" - checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 - languageName: node - linkType: hard - -"des.js@npm:^1.0.0": - version: 1.1.0 - resolution: "des.js@npm:1.1.0" - dependencies: - inherits: ^2.0.1 - minimalistic-assert: ^1.0.0 - checksum: 0e9c1584b70d31e20f20a613fc9ef60fbc6a147dfec9e448a168794a4b97ac04d8dc47ea008f1fa93b0f8aaf7c1ead632a5e59ce1913a6079d2d244c9f5ebe33 + +"dequal@npm:^2.0.0, dequal@npm:^2.0.3": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 languageName: node linkType: hard @@ -7805,6 +9647,22 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: daaaed925ffa7889bd91d56e9624e6c8033911bb60f3a50a74a87500680652969dbaab9526d1e200a4c94acf80fc862a22131841145a0a8482d60a99c24f4a3e + languageName: node + linkType: hard + +"detect-libc@npm:^2.0.0": + version: 2.1.0 + resolution: "detect-libc@npm:2.1.0" + checksum: a6430901d590bacc622e4304b9510fa99f5f8e71be7b5272d5dd03e07f361b9b5452da3416a8215125575946ec3c97c82bd6c51937a3923ab33405481a70e9ae + languageName: node + linkType: hard + "detect-newline@npm:^3.0.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -7819,7 +9677,7 @@ __metadata: languageName: node linkType: hard -"detect-port-alt@npm:1.1.6": +"detect-port-alt@npm:^1.1.6": version: 1.1.6 resolution: "detect-port-alt@npm:1.1.6" dependencies: @@ -7832,6 +9690,15 @@ __metadata: languageName: node linkType: hard +"devlop@npm:^1.0.0, devlop@npm:^1.1.0": + version: 1.1.0 + resolution: "devlop@npm:1.1.0" + dependencies: + dequal: ^2.0.0 + checksum: d2ff650bac0bb6ef08c48f3ba98640bb5fec5cce81e9957eb620408d1bab1204d382a45b785c6b3314dc867bb0684936b84c6867820da6db97cbb5d3c15dd185 + languageName: node + linkType: hard + "dezalgo@npm:^1.0.4": version: 1.0.4 resolution: "dezalgo@npm:1.0.4" @@ -7842,21 +9709,21 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^26.6.2": - version: 26.6.2 - resolution: "diff-sequences@npm:26.6.2" - checksum: 79af871776ef149a7ff3345d6b1bf37fe6e81f68632aa5542787851f6f60fba19b0be22fdd1e06046f56ae7382763ccfe94a982c39ee72bd107aef435ecbc0cf +"didyoumean@npm:^1.2.2": + version: 1.2.2 + resolution: "didyoumean@npm:1.2.2" + checksum: d5d98719d58b3c2fa59663c4c42ba9716f1fd01245c31d5fce31915bd3aa26e6aac149788e007358f778ebbd68a2256eb5973e8ca6f221df221ba060115acf2e languageName: node linkType: hard -"diff-sequences@npm:^28.1.1": - version: 28.1.1 - resolution: "diff-sequences@npm:28.1.1" - checksum: e2529036505567c7ca5a2dea86b6bcd1ca0e3ae63bf8ebf529b8a99cfa915bbf194b7021dc1c57361a4017a6d95578d4ceb29fabc3232a4f4cb866a2726c7690 +"diff-sequences@npm:^27.5.1": + version: 27.5.1 + resolution: "diff-sequences@npm:27.5.1" + checksum: a00db5554c9da7da225db2d2638d85f8e41124eccbd56cbaefb3b276dcbb1c1c2ad851c32defe2055a54a4806f030656cbf6638105fd6ce97bb87b90b32a33ca languageName: node linkType: hard -"diff-sequences@npm:^29.4.3, diff-sequences@npm:^29.6.3": +"diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" checksum: f4914158e1f2276343d98ff5b31fc004e7304f5470bf0f1adb2ac6955d85a531a6458d33e87667f98f6ae52ebd3891bb47d420bb48a5bd8b7a27ee25b20e33aa @@ -7870,17 +9737,6 @@ __metadata: languageName: node linkType: hard -"diffie-hellman@npm:^5.0.0": - version: 5.0.3 - resolution: "diffie-hellman@npm:5.0.3" - dependencies: - bn.js: ^4.1.0 - miller-rabin: ^4.0.0 - randombytes: ^2.0.0 - checksum: 0e620f322170c41076e70181dd1c24e23b08b47dbb92a22a644f3b89b6d3834b0f8ee19e37916164e5eb1ee26d2aa836d6129f92723995267250a0b541811065 - languageName: node - linkType: hard - "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -7890,29 +9746,19 @@ __metadata: languageName: node linkType: hard -"dns-equal@npm:^1.0.0": - version: 1.0.0 - resolution: "dns-equal@npm:1.0.0" - checksum: a8471ac849c7c13824f053babea1bc26e2f359394dd5a460f8340d8abd13434be01e3327a5c59d212f8c8997817450efd3f3ac77bec709b21979cf0235644524 - languageName: node - linkType: hard - -"dns-packet@npm:^1.3.1": - version: 1.3.4 - resolution: "dns-packet@npm:1.3.4" - dependencies: - ip: ^1.1.0 - safe-buffer: ^5.0.1 - checksum: 7dd87f85cb4f9d1a99c03470730e3d9385e67dc94f6c13868c4034424a5378631e492f9f1fbc43d3c42f319fbbfe18b6488bb9527c32d34692c52bf1f5eedf69 +"dlv@npm:^1.1.3": + version: 1.1.3 + resolution: "dlv@npm:1.1.3" + checksum: d7381bca22ed11933a1ccf376db7a94bee2c57aa61e490f680124fa2d1cd27e94eba641d9f45be57caab4f9a6579de0983466f620a2cd6230d7ec93312105ae7 languageName: node linkType: hard -"dns-txt@npm:^2.0.2": - version: 2.0.2 - resolution: "dns-txt@npm:2.0.2" +"dns-packet@npm:^5.2.2": + version: 5.6.1 + resolution: "dns-packet@npm:5.6.1" dependencies: - buffer-indexof: ^1.0.0 - checksum: 80130b665379ecd991687ae079fbee25d091e03e4c4cef41e7643b977849ac48c2f56bfcb3727e53594d29029b833749811110d9f3fbee1b26a6e6f8096a5cef + "@leichtgewicht/ip-codec": ^2.0.1 + checksum: 64c06457f0c6e143f7a0946e0aeb8de1c5f752217cfa143ef527467c00a6d78db1835cfdb6bb68333d9f9a4963cf23f410439b5262a8935cce1236f45e344b81 languageName: node linkType: hard @@ -7934,13 +9780,20 @@ __metadata: languageName: node linkType: hard -"dom-accessibility-api@npm:^0.5.6, dom-accessibility-api@npm:^0.5.9": +"dom-accessibility-api@npm:^0.5.9": version: 0.5.16 resolution: "dom-accessibility-api@npm:0.5.16" checksum: 005eb283caef57fc1adec4d5df4dd49189b628f2f575af45decb210e04d634459e3f1ee64f18b41e2dcf200c844bc1d9279d80807e686a30d69a4756151ad248 languageName: node linkType: hard +"dom-accessibility-api@npm:^0.6.3": + version: 0.6.3 + resolution: "dom-accessibility-api@npm:0.6.3" + checksum: c325b5144bb406df23f4affecffc117dbaec9af03daad9ee6b510c5be647b14d28ef0a4ea5ca06d696d8ab40bb777e5fed98b985976fdef9d8790178fa1d573f + languageName: node + linkType: hard + "dom-converter@npm:^0.2.0": version: 0.2.0 resolution: "dom-converter@npm:0.2.0" @@ -7981,13 +9834,6 @@ __metadata: languageName: node linkType: hard -"domain-browser@npm:^1.1.1": - version: 1.2.0 - resolution: "domain-browser@npm:1.2.0" - checksum: 8f1235c7f49326fb762f4675795246a6295e7dd566b4697abec24afdba2460daa7dfbd1a73d31efbf5606b3b7deadb06ce47cf06f0a476e706153d62a4ff2b90 - languageName: node - linkType: hard - "domelementtype@npm:1": version: 1.3.1 resolution: "domelementtype@npm:1.3.1" @@ -8051,52 +9897,42 @@ __metadata: languageName: node linkType: hard -"dot-prop@npm:^5.2.0": - version: 5.3.0 - resolution: "dot-prop@npm:5.3.0" - dependencies: - is-obj: ^2.0.0 - checksum: d5775790093c234ef4bfd5fbe40884ff7e6c87573e5339432870616331189f7f5d86575c5b5af2dcf0f61172990f4f734d07844b1f23482fff09e3c4bead05ea - languageName: node - linkType: hard - -"dotenv-expand@npm:5.1.0": +"dotenv-expand@npm:^5.1.0": version: 5.1.0 resolution: "dotenv-expand@npm:5.1.0" checksum: 8017675b7f254384915d55f9eb6388e577cf0a1231a28d54b0ca03b782be9501b0ac90ac57338636d395fa59051e6209e9b44b8ddf169ce6076dffb5dea227d3 languageName: node linkType: hard -"dotenv@npm:8.2.0": - version: 8.2.0 - resolution: "dotenv@npm:8.2.0" - checksum: ad4c8e0df3e24b4811c8e93377d048a10a9b213dcd9f062483b4a2d3168f08f10ec9c618c23f5639060d230ccdb174c08761479e9baa29610aa978e1ee66df76 +"dotenv@npm:^10.0.0": + version: 10.0.0 + resolution: "dotenv@npm:10.0.0" + checksum: f412c5fe8c24fbe313d302d2500e247ba8a1946492db405a4de4d30dd0eb186a88a43f13c958c5a7de303938949c4231c56994f97d05c4bc1f22478d631b4005 languageName: node linkType: hard "dotenv@npm:^16.0.1": - version: 16.4.5 - resolution: "dotenv@npm:16.4.5" - checksum: 301a12c3d44fd49888b74eb9ccf9f07a1f5df43f489e7fcb89647a2edcd84c42d6bc349dc8df099cd18f07c35c7b04685c1a4f3e6a6a9e6b30f8d48c15b7f49c + version: 16.6.1 + resolution: "dotenv@npm:16.6.1" + checksum: e8bd63c9a37f57934f7938a9cf35de698097fadf980cb6edb61d33b3e424ceccfe4d10f37130b904a973b9038627c2646a3365a904b4406514ea94d7f1816b69 languageName: node linkType: hard -"duplexer@npm:^0.1.1": - version: 0.1.2 - resolution: "duplexer@npm:0.1.2" - checksum: 62ba61a830c56801db28ff6305c7d289b6dc9f859054e8c982abd8ee0b0a14d2e9a8e7d086ffee12e868d43e2bbe8a964be55ddbd8c8957714c87373c7a4f9b0 +"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: ^1.0.1 + es-errors: ^1.3.0 + gopd: ^1.2.0 + checksum: 149207e36f07bd4941921b0ca929e3a28f1da7bd6b6ff8ff7f4e2f2e460675af4576eeba359c635723dc189b64cdd4787e0255897d5b135ccc5d15cb8685fc90 languageName: node linkType: hard -"duplexify@npm:^3.4.2, duplexify@npm:^3.6.0": - version: 3.7.1 - resolution: "duplexify@npm:3.7.1" - dependencies: - end-of-stream: ^1.0.0 - inherits: ^2.0.1 - readable-stream: ^2.0.0 - stream-shift: ^1.0.0 - checksum: 3c2ed2223d956a5da713dae12ba8295acb61d9acd966ccbba938090d04f4574ca4dca75cca089b5077c2d7e66101f32e6ea9b36a78ca213eff574e7a8b8accf2 +"duplexer@npm:^0.1.2": + version: 0.1.2 + resolution: "duplexer@npm:0.1.2" + checksum: 62ba61a830c56801db28ff6305c7d289b6dc9f859054e8c982abd8ee0b0a14d2e9a8e7d086ffee12e868d43e2bbe8a964be55ddbd8c8957714c87373c7a4f9b0 languageName: node linkType: hard @@ -8123,46 +9959,35 @@ __metadata: languageName: node linkType: hard -"ejs@npm:^2.6.1": - version: 2.7.4 - resolution: "ejs@npm:2.7.4" - checksum: a1d2bfc7d1f0b39e99ae19b20c9469a25aeddba1ffc225db098110b18d566f73772fcdcc740b108cfda7452276f67d7b64eb359f90285414c942f4ae70713371 - languageName: node - linkType: hard - -"electron-to-chromium@npm:^1.3.564, electron-to-chromium@npm:^1.4.668": - version: 1.4.747 - resolution: "electron-to-chromium@npm:1.4.747" - checksum: 6d302c2fbe71390ca666544017de5f8614ba8632ee02fd612d423439e813d72df09cbd8f614122a2ee07c8ffc2b3788882a5c5bb99363f162b9257f34c0eb31f +"ejs@npm:^3.1.6": + version: 3.1.10 + resolution: "ejs@npm:3.1.10" + dependencies: + jake: ^10.8.5 + bin: + ejs: bin/cli.js + checksum: ce90637e9c7538663ae023b8a7a380b2ef7cc4096de70be85abf5a3b9641912dde65353211d05e24d56b1f242d71185c6d00e02cb8860701d571786d92c71f05 languageName: node linkType: hard -"elliptic@npm:^6.5.3, elliptic@npm:^6.5.5": - version: 6.5.5 - resolution: "elliptic@npm:6.5.5" - dependencies: - bn.js: ^4.11.9 - brorand: ^1.1.0 - hash.js: ^1.0.0 - hmac-drbg: ^1.0.1 - inherits: ^2.0.4 - minimalistic-assert: ^1.0.1 - minimalistic-crypto-utils: ^1.0.1 - checksum: ec9105e4469eb3b32b0ee2579756c888ddf3f99d259aa0d65fccb906ee877768aaf8880caae73e3e669c9a4adeb3eb1945703aa974ec5000d2d33a239f4567eb +"electron-to-chromium@npm:^1.5.218": + version: 1.5.218 + resolution: "electron-to-chromium@npm:1.5.218" + checksum: 869953636f9d7ff865c827a65e3a8e5f2b4162f1ba58389d93e19f2c945001a2e5925d2c29b49af57c2ddbbf75c6205d01d472bf0d54085c42d606b97fd76eab languageName: node linkType: hard -"emittery@npm:^0.7.1": - version: 0.7.2 - resolution: "emittery@npm:0.7.2" - checksum: 908cd933d48a9bcb58ddf39e9a7d4ba1e049de392ccbef010102539a636e03cea2b28218331b7ede41de8165d9ed7f148851c5112ebd2e943117c0f61eff5f10 +"emittery@npm:^0.10.2": + version: 0.10.2 + resolution: "emittery@npm:0.10.2" + checksum: ee3e21788b043b90885b18ea756ec3105c1cedc50b29709c92b01e239c7e55345d4bb6d3aef4ddbaf528eef448a40b3bb831bad9ee0fc9c25cbf1367ab1ab5ac languageName: node linkType: hard -"emoji-regex@npm:^7.0.1": - version: 7.0.3 - resolution: "emoji-regex@npm:7.0.3" - checksum: 9159b2228b1511f2870ac5920f394c7e041715429a68459ebe531601555f11ea782a8e1718f969df2711d38c66268174407cbca57ce36485544f695c2dfdc96e +"emittery@npm:^0.8.1": + version: 0.8.1 + resolution: "emittery@npm:0.8.1" + checksum: 2457e8c7b0688bb006126f2c025b2655abe682f66b184954122a8a065b5277f9813d49d627896a10b076b81c513ec5f491fd9c14fbd42c04b95ca3c9f3c365ee languageName: node linkType: hard @@ -8183,536 +10008,532 @@ __metadata: "emojis-list@npm:^3.0.0": version: 3.0.0 resolution: "emojis-list@npm:3.0.0" - checksum: ddaaa02542e1e9436c03970eeed445f4ed29a5337dfba0fe0c38dfdd2af5da2429c2a0821304e8a8d1cadf27fdd5b22ff793571fa803ae16852a6975c65e8e70 - languageName: node - linkType: hard - -"encodeurl@npm:~1.0.2": - version: 1.0.2 - resolution: "encodeurl@npm:1.0.2" - checksum: e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c - languageName: node - linkType: hard - -"encoding@npm:^0.1.13": - version: 0.1.13 - resolution: "encoding@npm:0.1.13" - dependencies: - iconv-lite: ^0.6.2 - checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f - languageName: node - linkType: hard - -"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0": - version: 1.4.4 - resolution: "end-of-stream@npm:1.4.4" - dependencies: - once: ^1.4.0 - checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b - languageName: node - linkType: hard - -"enhanced-resolve@npm:^4.3.0": - version: 4.5.0 - resolution: "enhanced-resolve@npm:4.5.0" - dependencies: - graceful-fs: ^4.1.2 - memory-fs: ^0.5.0 - tapable: ^1.0.0 - checksum: 4d87488584c4d67d356ef4ba04978af4b2d4d18190cb859efac8e8475a34d5d6c069df33faa5a0a22920b0586dbf330f6a08d52bb15a8771a9ce4d70a2da74ba - languageName: node - linkType: hard - -"enquirer@npm:^2.3.5": - version: 2.4.1 - resolution: "enquirer@npm:2.4.1" - dependencies: - ansi-colors: ^4.1.1 - strip-ansi: ^6.0.1 - checksum: f080f11a74209647dbf347a7c6a83c8a47ae1ebf1e75073a808bc1088eb780aa54075bfecd1bcdb3e3c724520edb8e6ee05da031529436b421b71066fcc48cb5 - languageName: node - linkType: hard - -"entities@npm:^2.0.0": - version: 2.2.0 - resolution: "entities@npm:2.2.0" - checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3 - languageName: node - linkType: hard - -"env-paths@npm:^2.2.0": - version: 2.2.1 - resolution: "env-paths@npm:2.2.1" - checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e - languageName: node - linkType: hard - -"err-code@npm:^2.0.2": - version: 2.0.3 - resolution: "err-code@npm:2.0.3" - checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 - languageName: node - linkType: hard - -"errno@npm:^0.1.3, errno@npm:~0.1.7": - version: 0.1.8 - resolution: "errno@npm:0.1.8" - dependencies: - prr: ~1.0.1 - bin: - errno: cli.js - checksum: 1271f7b9fbb3bcbec76ffde932485d1e3561856d21d847ec613a9722ee924cdd4e523a62dc71a44174d91e898fe21fdc8d5b50823f4b5e0ce8c35c8271e6ef4a - languageName: node - linkType: hard - -"error-ex@npm:^1.3.1": - version: 1.3.2 - resolution: "error-ex@npm:1.3.2" - dependencies: - is-arrayish: ^0.2.1 - checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001 - languageName: node - linkType: hard - -"error-stack-parser@npm:^2.0.6": - version: 2.1.4 - resolution: "error-stack-parser@npm:2.1.4" - dependencies: - stackframe: ^1.3.4 - checksum: 3b916d2d14c6682f287c8bfa28e14672f47eafe832701080e420e7cdbaebb2c50293868256a95706ac2330fe078cf5664713158b49bc30d7a5f2ac229ded0e18 - languageName: node - linkType: hard - -"es-abstract@npm:^1.17.2, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.1, es-abstract@npm:^1.23.2": - version: 1.23.3 - resolution: "es-abstract@npm:1.23.3" - dependencies: - array-buffer-byte-length: ^1.0.1 - arraybuffer.prototype.slice: ^1.0.3 - available-typed-arrays: ^1.0.7 - call-bind: ^1.0.7 - data-view-buffer: ^1.0.1 - data-view-byte-length: ^1.0.1 - data-view-byte-offset: ^1.0.0 - es-define-property: ^1.0.0 - es-errors: ^1.3.0 - es-object-atoms: ^1.0.0 - es-set-tostringtag: ^2.0.3 - es-to-primitive: ^1.2.1 - function.prototype.name: ^1.1.6 - get-intrinsic: ^1.2.4 - get-symbol-description: ^1.0.2 - globalthis: ^1.0.3 - gopd: ^1.0.1 - has-property-descriptors: ^1.0.2 - has-proto: ^1.0.3 - has-symbols: ^1.0.3 - hasown: ^2.0.2 - internal-slot: ^1.0.7 - is-array-buffer: ^3.0.4 - is-callable: ^1.2.7 - is-data-view: ^1.0.1 - is-negative-zero: ^2.0.3 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.3 - is-string: ^1.0.7 - is-typed-array: ^1.1.13 - is-weakref: ^1.0.2 - object-inspect: ^1.13.1 - object-keys: ^1.1.1 - object.assign: ^4.1.5 - regexp.prototype.flags: ^1.5.2 - safe-array-concat: ^1.1.2 - safe-regex-test: ^1.0.3 - string.prototype.trim: ^1.2.9 - string.prototype.trimend: ^1.0.8 - string.prototype.trimstart: ^1.0.8 - typed-array-buffer: ^1.0.2 - typed-array-byte-length: ^1.0.1 - typed-array-byte-offset: ^1.0.2 - typed-array-length: ^1.0.6 - unbox-primitive: ^1.0.2 - which-typed-array: ^1.1.15 - checksum: f840cf161224252512f9527306b57117192696571e07920f777cb893454e32999206198b4f075516112af6459daca282826d1735c450528470356d09eff3a9ae - languageName: node - linkType: hard - -"es-array-method-boxes-properly@npm:^1.0.0": - version: 1.0.0 - resolution: "es-array-method-boxes-properly@npm:1.0.0" - checksum: 2537fcd1cecf187083890bc6f5236d3a26bf39237433587e5bf63392e88faae929dbba78ff0120681a3f6f81c23fe3816122982c160d63b38c95c830b633b826 - languageName: node - linkType: hard - -"es-define-property@npm:^1.0.0": - version: 1.0.0 - resolution: "es-define-property@npm:1.0.0" - dependencies: - get-intrinsic: ^1.2.4 - checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 - languageName: node - linkType: hard - -"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": - version: 1.3.0 - resolution: "es-errors@npm:1.3.0" - checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 - languageName: node - linkType: hard - -"es-get-iterator@npm:^1.1.3": - version: 1.1.3 - resolution: "es-get-iterator@npm:1.1.3" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.3 - has-symbols: ^1.0.3 - is-arguments: ^1.1.1 - is-map: ^2.0.2 - is-set: ^2.0.2 - is-string: ^1.0.7 - isarray: ^2.0.5 - stop-iteration-iterator: ^1.0.0 - checksum: 8fa118da42667a01a7c7529f8a8cca514feeff243feec1ce0bb73baaa3514560bd09d2b3438873cf8a5aaec5d52da248131de153b28e2638a061b6e4df13267d - languageName: node - linkType: hard - -"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.17": - version: 1.0.18 - resolution: "es-iterator-helpers@npm:1.0.18" - dependencies: - call-bind: ^1.0.7 - define-properties: ^1.2.1 - es-abstract: ^1.23.0 - es-errors: ^1.3.0 - es-set-tostringtag: ^2.0.3 - function-bind: ^1.1.2 - get-intrinsic: ^1.2.4 - globalthis: ^1.0.3 - has-property-descriptors: ^1.0.2 - has-proto: ^1.0.3 - has-symbols: ^1.0.3 - internal-slot: ^1.0.7 - iterator.prototype: ^1.1.2 - safe-array-concat: ^1.1.2 - checksum: 1594324ff3ca8890fe30c98b2419d3007d2b14b35f9773f188114408ff973e13c526f6045d88209e932f58dc0c55fc9a4ae1554636f8938ed7d926ffc27d3e1a - languageName: node - linkType: hard - -"es-object-atoms@npm:^1.0.0": - version: 1.0.0 - resolution: "es-object-atoms@npm:1.0.0" - dependencies: - es-errors: ^1.3.0 - checksum: 26f0ff78ab93b63394e8403c353842b2272836968de4eafe97656adfb8a7c84b9099bf0fe96ed58f4a4cddc860f6e34c77f91649a58a5daa4a9c40b902744e3c - languageName: node - linkType: hard - -"es-set-tostringtag@npm:^2.0.3": - version: 2.0.3 - resolution: "es-set-tostringtag@npm:2.0.3" - dependencies: - get-intrinsic: ^1.2.4 - has-tostringtag: ^1.0.2 - hasown: ^2.0.1 - checksum: 7227fa48a41c0ce83e0377b11130d324ac797390688135b8da5c28994c0165be8b252e15cd1de41e1325e5a5412511586960213e88f9ab4a5e7d028895db5129 - languageName: node - linkType: hard - -"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": - version: 1.0.2 - resolution: "es-shim-unscopables@npm:1.0.2" - dependencies: - hasown: ^2.0.0 - checksum: 432bd527c62065da09ed1d37a3f8e623c423683285e6188108286f4a1e8e164a5bcbfbc0051557c7d14633cd2a41ce24c7048e6bbb66a985413fd32f1be72626 - languageName: node - linkType: hard - -"es-to-primitive@npm:^1.2.1": - version: 1.2.1 - resolution: "es-to-primitive@npm:1.2.1" - dependencies: - is-callable: ^1.1.4 - is-date-object: ^1.0.1 - is-symbol: ^1.0.2 - checksum: 4ead6671a2c1402619bdd77f3503991232ca15e17e46222b0a41a5d81aebc8740a77822f5b3c965008e631153e9ef0580540007744521e72de8e33599fca2eed - languageName: node - linkType: hard - -"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.62, es5-ext@npm:^0.10.64, es5-ext@npm:~0.10.14": - version: 0.10.64 - resolution: "es5-ext@npm:0.10.64" - dependencies: - es6-iterator: ^2.0.3 - es6-symbol: ^3.1.3 - esniff: ^2.0.1 - next-tick: ^1.1.0 - checksum: 01179fab0769fdbef213062222f99d0346724dbaccf04b87c0e6ee7f0c97edabf14be647ca1321f0497425ea7145de0fd278d1b3f3478864b8933e7136a5c645 - languageName: node - linkType: hard - -"es6-iterator@npm:2.0.3, es6-iterator@npm:^2.0.3": - version: 2.0.3 - resolution: "es6-iterator@npm:2.0.3" - dependencies: - d: 1 - es5-ext: ^0.10.35 - es6-symbol: ^3.1.1 - checksum: 6e48b1c2d962c21dee604b3d9f0bc3889f11ed5a8b33689155a2065d20e3107e2a69cc63a71bd125aeee3a589182f8bbcb5c8a05b6a8f38fa4205671b6d09697 - languageName: node - linkType: hard - -"es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": - version: 3.1.4 - resolution: "es6-symbol@npm:3.1.4" - dependencies: - d: ^1.0.2 - ext: ^1.7.0 - checksum: 52125ec4b5d1b6b93b8d3d42830bb19f8da21080ffcf45253b614bc6ff3e31349be202fb745d4d1af6778cdf5e38fea30e0c7e7dc37e2aecd44acc43502055f9 + checksum: ddaaa02542e1e9436c03970eeed445f4ed29a5337dfba0fe0c38dfdd2af5da2429c2a0821304e8a8d1cadf27fdd5b22ff793571fa803ae16852a6975c65e8e70 languageName: node linkType: hard -"esbuild-android-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-android-64@npm:0.14.54" - conditions: os=android & cpu=x64 +"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe languageName: node linkType: hard -"esbuild-android-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-android-arm64@npm:0.14.54" - conditions: os=android & cpu=arm64 +"encodeurl@npm:~1.0.2": + version: 1.0.2 + resolution: "encodeurl@npm:1.0.2" + checksum: e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c languageName: node linkType: hard -"esbuild-darwin-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-darwin-64@npm:0.14.54" - conditions: os=darwin & cpu=x64 +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: ^0.6.2 + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f languageName: node linkType: hard -"esbuild-darwin-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-darwin-arm64@npm:0.14.54" - conditions: os=darwin & cpu=arm64 +"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": + version: 1.4.5 + resolution: "end-of-stream@npm:1.4.5" + dependencies: + once: ^1.4.0 + checksum: 1e0cfa6e7f49887544e03314f9dfc56a8cb6dde910cbb445983ecc2ff426fc05946df9d75d8a21a3a64f2cecfe1bf88f773952029f46756b2ed64a24e95b1fb8 languageName: node linkType: hard -"esbuild-freebsd-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-freebsd-64@npm:0.14.54" - conditions: os=freebsd & cpu=x64 +"enhanced-resolve@npm:^5.17.3": + version: 5.18.3 + resolution: "enhanced-resolve@npm:5.18.3" + dependencies: + graceful-fs: ^4.2.4 + tapable: ^2.2.0 + checksum: e2b2188a7f9b68616984b5ce1f43b97bef3c5fde4d193c24ea4cfdb4eb784a700093f049f14155733a3cb3ae1204550590aa37dda7e742022c8f447f618a4816 languageName: node linkType: hard -"esbuild-freebsd-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-freebsd-arm64@npm:0.14.54" - conditions: os=freebsd & cpu=arm64 +"enquirer@npm:^2.3.5": + version: 2.4.1 + resolution: "enquirer@npm:2.4.1" + dependencies: + ansi-colors: ^4.1.1 + strip-ansi: ^6.0.1 + checksum: f080f11a74209647dbf347a7c6a83c8a47ae1ebf1e75073a808bc1088eb780aa54075bfecd1bcdb3e3c724520edb8e6ee05da031529436b421b71066fcc48cb5 languageName: node linkType: hard -"esbuild-linux-32@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-32@npm:0.14.54" - conditions: os=linux & cpu=ia32 +"entities@npm:^2.0.0": + version: 2.2.0 + resolution: "entities@npm:2.2.0" + checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3 languageName: node linkType: hard -"esbuild-linux-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-64@npm:0.14.54" - conditions: os=linux & cpu=x64 +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e languageName: node linkType: hard -"esbuild-linux-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-arm64@npm:0.14.54" - conditions: os=linux & cpu=arm64 +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 languageName: node linkType: hard -"esbuild-linux-arm@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-arm@npm:0.14.54" - conditions: os=linux & cpu=arm +"error-ex@npm:^1.3.1": + version: 1.3.4 + resolution: "error-ex@npm:1.3.4" + dependencies: + is-arrayish: ^0.2.1 + checksum: 25136c0984569c8d68417036a9a1624804314296f24675199a391e5d20b2e26fe6d9304d40901293fa86900603a229983c9a8921ea7f1d16f814c2db946ff4ef languageName: node linkType: hard -"esbuild-linux-mips64le@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-mips64le@npm:0.14.54" - conditions: os=linux & cpu=mips64el +"error-stack-parser@npm:^2.0.6": + version: 2.1.4 + resolution: "error-stack-parser@npm:2.1.4" + dependencies: + stackframe: ^1.3.4 + checksum: 3b916d2d14c6682f287c8bfa28e14672f47eafe832701080e420e7cdbaebb2c50293868256a95706ac2330fe078cf5664713158b49bc30d7a5f2ac229ded0e18 languageName: node linkType: hard -"esbuild-linux-ppc64le@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-ppc64le@npm:0.14.54" - conditions: os=linux & cpu=ppc64 +"es-abstract@npm:^1.17.2, es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0": + version: 1.24.0 + resolution: "es-abstract@npm:1.24.0" + dependencies: + array-buffer-byte-length: ^1.0.2 + arraybuffer.prototype.slice: ^1.0.4 + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.4 + data-view-buffer: ^1.0.2 + data-view-byte-length: ^1.0.2 + data-view-byte-offset: ^1.0.1 + es-define-property: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.1.1 + es-set-tostringtag: ^2.1.0 + es-to-primitive: ^1.3.0 + function.prototype.name: ^1.1.8 + get-intrinsic: ^1.3.0 + get-proto: ^1.0.1 + get-symbol-description: ^1.1.0 + globalthis: ^1.0.4 + gopd: ^1.2.0 + has-property-descriptors: ^1.0.2 + has-proto: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + internal-slot: ^1.1.0 + is-array-buffer: ^3.0.5 + is-callable: ^1.2.7 + is-data-view: ^1.0.2 + is-negative-zero: ^2.0.3 + is-regex: ^1.2.1 + is-set: ^2.0.3 + is-shared-array-buffer: ^1.0.4 + is-string: ^1.1.1 + is-typed-array: ^1.1.15 + is-weakref: ^1.1.1 + math-intrinsics: ^1.1.0 + object-inspect: ^1.13.4 + object-keys: ^1.1.1 + object.assign: ^4.1.7 + own-keys: ^1.0.1 + regexp.prototype.flags: ^1.5.4 + safe-array-concat: ^1.1.3 + safe-push-apply: ^1.0.0 + safe-regex-test: ^1.1.0 + set-proto: ^1.0.0 + stop-iteration-iterator: ^1.1.0 + string.prototype.trim: ^1.2.10 + string.prototype.trimend: ^1.0.9 + string.prototype.trimstart: ^1.0.8 + typed-array-buffer: ^1.0.3 + typed-array-byte-length: ^1.0.3 + typed-array-byte-offset: ^1.0.4 + typed-array-length: ^1.0.7 + unbox-primitive: ^1.1.0 + which-typed-array: ^1.1.19 + checksum: 06b3d605e56e3da9d16d4db2629a42dac1ca31f2961a41d15c860422a266115e865b43e82d6b9da81a0fabbbb65ebc12fb68b0b755bc9dbddacb6bf7450e96df languageName: node linkType: hard -"esbuild-linux-riscv64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-riscv64@npm:0.14.54" - conditions: os=linux & cpu=riscv64 +"es-array-method-boxes-properly@npm:^1.0.0": + version: 1.0.0 + resolution: "es-array-method-boxes-properly@npm:1.0.0" + checksum: 2537fcd1cecf187083890bc6f5236d3a26bf39237433587e5bf63392e88faae929dbba78ff0120681a3f6f81c23fe3816122982c160d63b38c95c830b633b826 languageName: node linkType: hard -"esbuild-linux-s390x@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-linux-s390x@npm:0.14.54" - conditions: os=linux & cpu=s390x +"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 0512f4e5d564021c9e3a644437b0155af2679d10d80f21adaf868e64d30efdfbd321631956f20f42d655fedb2e3a027da479fad3fa6048f768eb453a80a5f80a languageName: node linkType: hard -"esbuild-netbsd-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-netbsd-64@npm:0.14.54" - conditions: os=netbsd & cpu=x64 +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 languageName: node linkType: hard -"esbuild-openbsd-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-openbsd-64@npm:0.14.54" - conditions: os=openbsd & cpu=x64 +"es-iterator-helpers@npm:^1.2.1": + version: 1.2.1 + resolution: "es-iterator-helpers@npm:1.2.1" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + es-abstract: ^1.23.6 + es-errors: ^1.3.0 + es-set-tostringtag: ^2.0.3 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.6 + globalthis: ^1.0.4 + gopd: ^1.2.0 + has-property-descriptors: ^1.0.2 + has-proto: ^1.2.0 + has-symbols: ^1.1.0 + internal-slot: ^1.1.0 + iterator.prototype: ^1.1.4 + safe-array-concat: ^1.1.3 + checksum: 952808dd1df3643d67ec7adf20c30b36e5eecadfbf36354e6f39ed3266c8e0acf3446ce9bc465e38723d613cb1d915c1c07c140df65bdce85da012a6e7bda62b languageName: node linkType: hard -"esbuild-sunos-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-sunos-64@npm:0.14.54" - conditions: os=sunos & cpu=x64 +"es-module-lexer@npm:^1.2.1, es-module-lexer@npm:^1.5.4, es-module-lexer@npm:^1.7.0": + version: 1.7.0 + resolution: "es-module-lexer@npm:1.7.0" + checksum: 7858bb76ae387fdbf8a6fccc951bf18919768309850587553eca34698b9193fbc65fab03d3d9f69163d860321fbf66adf89d5821e7f4148c7cb7d7b997259211 languageName: node linkType: hard -"esbuild-windows-32@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-windows-32@npm:0.14.54" - conditions: os=win32 & cpu=ia32 +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: ^1.3.0 + checksum: 214d3767287b12f36d3d7267ef342bbbe1e89f899cfd67040309fc65032372a8e60201410a99a1645f2f90c1912c8c49c8668066f6bdd954bcd614dda2e3da97 languageName: node linkType: hard -"esbuild-windows-64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-windows-64@npm:0.14.54" - conditions: os=win32 & cpu=x64 +"es-set-tostringtag@npm:^2.0.3, es-set-tostringtag@npm:^2.1.0": + version: 2.1.0 + resolution: "es-set-tostringtag@npm:2.1.0" + dependencies: + es-errors: ^1.3.0 + get-intrinsic: ^1.2.6 + has-tostringtag: ^1.0.2 + hasown: ^2.0.2 + checksum: 789f35de4be3dc8d11fdcb91bc26af4ae3e6d602caa93299a8c45cf05d36cc5081454ae2a6d3afa09cceca214b76c046e4f8151e092e6fc7feeb5efb9e794fc6 languageName: node linkType: hard -"esbuild-windows-arm64@npm:0.14.54": - version: 0.14.54 - resolution: "esbuild-windows-arm64@npm:0.14.54" - conditions: os=win32 & cpu=arm64 +"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": + version: 1.1.0 + resolution: "es-shim-unscopables@npm:1.1.0" + dependencies: + hasown: ^2.0.2 + checksum: 33cfb1ebcb2f869f0bf528be1a8660b4fe8b6cec8fc641f330e508db2284b58ee2980fad6d0828882d22858c759c0806076427a3673b6daa60f753e3b558ee15 languageName: node linkType: hard -"esbuild@npm:^0.14.21": - version: 0.14.54 - resolution: "esbuild@npm:0.14.54" - dependencies: - "@esbuild/linux-loong64": 0.14.54 - esbuild-android-64: 0.14.54 - esbuild-android-arm64: 0.14.54 - esbuild-darwin-64: 0.14.54 - esbuild-darwin-arm64: 0.14.54 - esbuild-freebsd-64: 0.14.54 - esbuild-freebsd-arm64: 0.14.54 - esbuild-linux-32: 0.14.54 - esbuild-linux-64: 0.14.54 - esbuild-linux-arm: 0.14.54 - esbuild-linux-arm64: 0.14.54 - esbuild-linux-mips64le: 0.14.54 - esbuild-linux-ppc64le: 0.14.54 - esbuild-linux-riscv64: 0.14.54 - esbuild-linux-s390x: 0.14.54 - esbuild-netbsd-64: 0.14.54 - esbuild-openbsd-64: 0.14.54 - esbuild-sunos-64: 0.14.54 - esbuild-windows-32: 0.14.54 - esbuild-windows-64: 0.14.54 - esbuild-windows-arm64: 0.14.54 +"es-to-primitive@npm:^1.3.0": + version: 1.3.0 + resolution: "es-to-primitive@npm:1.3.0" + dependencies: + is-callable: ^1.2.7 + is-date-object: ^1.0.5 + is-symbol: ^1.0.4 + checksum: 966965880356486cd4d1fe9a523deda2084c81b3702d951212c098f5f2ee93605d1b7c1840062efb48a07d892641c7ed1bc194db563645c0dd2b919cb6d65b93 + languageName: node + linkType: hard + +"esbuild@npm:^0.17.0": + version: 0.17.19 + resolution: "esbuild@npm:0.17.19" + dependencies: + "@esbuild/android-arm": 0.17.19 + "@esbuild/android-arm64": 0.17.19 + "@esbuild/android-x64": 0.17.19 + "@esbuild/darwin-arm64": 0.17.19 + "@esbuild/darwin-x64": 0.17.19 + "@esbuild/freebsd-arm64": 0.17.19 + "@esbuild/freebsd-x64": 0.17.19 + "@esbuild/linux-arm": 0.17.19 + "@esbuild/linux-arm64": 0.17.19 + "@esbuild/linux-ia32": 0.17.19 + "@esbuild/linux-loong64": 0.17.19 + "@esbuild/linux-mips64el": 0.17.19 + "@esbuild/linux-ppc64": 0.17.19 + "@esbuild/linux-riscv64": 0.17.19 + "@esbuild/linux-s390x": 0.17.19 + "@esbuild/linux-x64": 0.17.19 + "@esbuild/netbsd-x64": 0.17.19 + "@esbuild/openbsd-x64": 0.17.19 + "@esbuild/sunos-x64": 0.17.19 + "@esbuild/win32-arm64": 0.17.19 + "@esbuild/win32-ia32": 0.17.19 + "@esbuild/win32-x64": 0.17.19 + dependenciesMeta: + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: ac11b1a5a6008e4e37ccffbd6c2c054746fc58d0ed4a2f9ee643bd030cfcea9a33a235087bc777def8420f2eaafb3486e76adb7bdb7241a9143b43a69a10afd8 + languageName: node + linkType: hard + +"esbuild@npm:^0.21.3": + version: 0.21.5 + resolution: "esbuild@npm:0.21.5" + dependencies: + "@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 dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true "@esbuild/linux-loong64": optional: true - esbuild-android-64: + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 2911c7b50b23a9df59a7d6d4cdd3a4f85855787f374dce751148dbb13305e0ce7e880dde1608c2ab7a927fc6cec3587b80995f7fc87a64b455f8b70b55fd8ec1 + languageName: node + linkType: hard + +"esbuild@npm:^0.24.2": + version: 0.24.2 + resolution: "esbuild@npm:0.24.2" + dependencies: + "@esbuild/aix-ppc64": 0.24.2 + "@esbuild/android-arm": 0.24.2 + "@esbuild/android-arm64": 0.24.2 + "@esbuild/android-x64": 0.24.2 + "@esbuild/darwin-arm64": 0.24.2 + "@esbuild/darwin-x64": 0.24.2 + "@esbuild/freebsd-arm64": 0.24.2 + "@esbuild/freebsd-x64": 0.24.2 + "@esbuild/linux-arm": 0.24.2 + "@esbuild/linux-arm64": 0.24.2 + "@esbuild/linux-ia32": 0.24.2 + "@esbuild/linux-loong64": 0.24.2 + "@esbuild/linux-mips64el": 0.24.2 + "@esbuild/linux-ppc64": 0.24.2 + "@esbuild/linux-riscv64": 0.24.2 + "@esbuild/linux-s390x": 0.24.2 + "@esbuild/linux-x64": 0.24.2 + "@esbuild/netbsd-arm64": 0.24.2 + "@esbuild/netbsd-x64": 0.24.2 + "@esbuild/openbsd-arm64": 0.24.2 + "@esbuild/openbsd-x64": 0.24.2 + "@esbuild/sunos-x64": 0.24.2 + "@esbuild/win32-arm64": 0.24.2 + "@esbuild/win32-ia32": 0.24.2 + "@esbuild/win32-x64": 0.24.2 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": optional: true - esbuild-android-arm64: + "@esbuild/freebsd-arm64": optional: true - esbuild-darwin-64: + "@esbuild/freebsd-x64": optional: true - esbuild-darwin-arm64: + "@esbuild/linux-arm": optional: true - esbuild-freebsd-64: + "@esbuild/linux-arm64": optional: true - esbuild-freebsd-arm64: + "@esbuild/linux-ia32": optional: true - esbuild-linux-32: + "@esbuild/linux-loong64": optional: true - esbuild-linux-64: + "@esbuild/linux-mips64el": optional: true - esbuild-linux-arm: + "@esbuild/linux-ppc64": optional: true - esbuild-linux-arm64: + "@esbuild/linux-riscv64": optional: true - esbuild-linux-mips64le: + "@esbuild/linux-s390x": optional: true - esbuild-linux-ppc64le: + "@esbuild/linux-x64": optional: true - esbuild-linux-riscv64: + "@esbuild/netbsd-arm64": optional: true - esbuild-linux-s390x: + "@esbuild/netbsd-x64": optional: true - esbuild-netbsd-64: + "@esbuild/openbsd-arm64": optional: true - esbuild-openbsd-64: + "@esbuild/openbsd-x64": optional: true - esbuild-sunos-64: + "@esbuild/sunos-x64": optional: true - esbuild-windows-32: + "@esbuild/win32-arm64": optional: true - esbuild-windows-64: + "@esbuild/win32-ia32": optional: true - esbuild-windows-arm64: + "@esbuild/win32-x64": optional: true bin: esbuild: bin/esbuild - checksum: 49e360b1185c797f5ca3a7f5f0a75121494d97ddf691f65ed1796e6257d318f928342a97f559bb8eced6a90cf604dd22db4a30e0dbbf15edd9dbf22459b639af - languageName: node - linkType: hard - -"esbuild@npm:^0.18.10": - version: 0.18.20 - resolution: "esbuild@npm:0.18.20" - dependencies: - "@esbuild/android-arm": 0.18.20 - "@esbuild/android-arm64": 0.18.20 - "@esbuild/android-x64": 0.18.20 - "@esbuild/darwin-arm64": 0.18.20 - "@esbuild/darwin-x64": 0.18.20 - "@esbuild/freebsd-arm64": 0.18.20 - "@esbuild/freebsd-x64": 0.18.20 - "@esbuild/linux-arm": 0.18.20 - "@esbuild/linux-arm64": 0.18.20 - "@esbuild/linux-ia32": 0.18.20 - "@esbuild/linux-loong64": 0.18.20 - "@esbuild/linux-mips64el": 0.18.20 - "@esbuild/linux-ppc64": 0.18.20 - "@esbuild/linux-riscv64": 0.18.20 - "@esbuild/linux-s390x": 0.18.20 - "@esbuild/linux-x64": 0.18.20 - "@esbuild/netbsd-x64": 0.18.20 - "@esbuild/openbsd-x64": 0.18.20 - "@esbuild/sunos-x64": 0.18.20 - "@esbuild/win32-arm64": 0.18.20 - "@esbuild/win32-ia32": 0.18.20 - "@esbuild/win32-x64": 0.18.20 + checksum: e2303f8331887e31330b5a972fb9640ad93dfc5af76cb2156faa9eaa32bac5c403244096cbdafc45622829913e63664dfd88410987e3468df4354492f908a094 + languageName: node + linkType: hard + +"esbuild@npm:^0.25.0": + version: 0.25.9 + resolution: "esbuild@npm:0.25.9" + dependencies: + "@esbuild/aix-ppc64": 0.25.9 + "@esbuild/android-arm": 0.25.9 + "@esbuild/android-arm64": 0.25.9 + "@esbuild/android-x64": 0.25.9 + "@esbuild/darwin-arm64": 0.25.9 + "@esbuild/darwin-x64": 0.25.9 + "@esbuild/freebsd-arm64": 0.25.9 + "@esbuild/freebsd-x64": 0.25.9 + "@esbuild/linux-arm": 0.25.9 + "@esbuild/linux-arm64": 0.25.9 + "@esbuild/linux-ia32": 0.25.9 + "@esbuild/linux-loong64": 0.25.9 + "@esbuild/linux-mips64el": 0.25.9 + "@esbuild/linux-ppc64": 0.25.9 + "@esbuild/linux-riscv64": 0.25.9 + "@esbuild/linux-s390x": 0.25.9 + "@esbuild/linux-x64": 0.25.9 + "@esbuild/netbsd-arm64": 0.25.9 + "@esbuild/netbsd-x64": 0.25.9 + "@esbuild/openbsd-arm64": 0.25.9 + "@esbuild/openbsd-x64": 0.25.9 + "@esbuild/openharmony-arm64": 0.25.9 + "@esbuild/sunos-x64": 0.25.9 + "@esbuild/win32-arm64": 0.25.9 + "@esbuild/win32-ia32": 0.25.9 + "@esbuild/win32-x64": 0.25.9 dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true "@esbuild/android-arm": optional: true "@esbuild/android-arm64": @@ -8745,10 +10566,16 @@ __metadata: optional: true "@esbuild/linux-x64": optional: true + "@esbuild/netbsd-arm64": + optional: true "@esbuild/netbsd-x64": optional: true + "@esbuild/openbsd-arm64": + optional: true "@esbuild/openbsd-x64": optional: true + "@esbuild/openharmony-arm64": + optional: true "@esbuild/sunos-x64": optional: true "@esbuild/win32-arm64": @@ -8759,38 +10586,38 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 5d253614e50cdb6ec22095afd0c414f15688e7278a7eb4f3720a6dd1306b0909cf431e7b9437a90d065a31b1c57be60130f63fe3e8d0083b588571f31ee6ec7b + checksum: 718bc15016266da5b4675c2226923cadfe014b119e5c7a9240a6fe826c01ec2e7d5492af052e1c8a03b511778187f234cef2e994e6195287945ce0a824b79974 languageName: node linkType: hard -"escalade@npm:^3.0.2, escalade@npm:^3.1.1": - version: 3.1.2 - resolution: "escalade@npm:3.1.2" - checksum: 1ec0977aa2772075493002bdbd549d595ff6e9393b1cb0d7d6fcaf78c750da0c158f180938365486f75cb69fba20294351caddfce1b46552a7b6c3cde52eaa02 +"escalade@npm:^3.1.1, escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 47b029c83de01b0d17ad99ed766347b974b0d628e848de404018f3abee728e987da0d2d370ad4574aa3d5b5bfc368754fd085d69a30f8e75903486ec4b5b709e languageName: node linkType: hard -"escape-html@npm:~1.0.3": +"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" checksum: 6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24 languageName: node linkType: hard -"escape-string-regexp@npm:2.0.0, escape-string-regexp@npm:^2.0.0": - version: 2.0.0 - resolution: "escape-string-regexp@npm:2.0.0" - checksum: 9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395 - languageName: node - linkType: hard - -"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": +"escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 languageName: node linkType: hard +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395 + languageName: node + linkType: hard + "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -8835,40 +10662,38 @@ __metadata: languageName: node linkType: hard -"eslint-config-prettier@npm:^8.5.0": - version: 8.10.0 - resolution: "eslint-config-prettier@npm:8.10.0" +"eslint-config-prettier@npm:^10.0.1": + version: 10.1.8 + resolution: "eslint-config-prettier@npm:10.1.8" peerDependencies: eslint: ">=7.0.0" bin: eslint-config-prettier: bin/cli.js - checksum: 153266badd477e49b0759816246b2132f1dbdb6c7f313ca60a9af5822fd1071c2bc5684a3720d78b725452bbac04bb130878b2513aea5e72b1b792de5a69fec8 + checksum: 9140e19f78f0dbc888b160bb72b85f8043bada7b12a548faa56cea0ba74f8ef16653250ffd014d85d9a376a88c4941c96a3cdc9d39a07eb3def6967166635bd8 languageName: node linkType: hard -"eslint-config-react-app@npm:^6.0.0": - version: 6.0.0 - resolution: "eslint-config-react-app@npm:6.0.0" - dependencies: - confusing-browser-globals: ^1.0.10 - peerDependencies: - "@typescript-eslint/eslint-plugin": ^4.0.0 - "@typescript-eslint/parser": ^4.0.0 - babel-eslint: ^10.0.0 - eslint: ^7.5.0 - eslint-plugin-flowtype: ^5.2.0 - eslint-plugin-import: ^2.22.0 - eslint-plugin-jest: ^24.0.0 - eslint-plugin-jsx-a11y: ^6.3.1 - eslint-plugin-react: ^7.20.3 - eslint-plugin-react-hooks: ^4.0.8 - eslint-plugin-testing-library: ^3.9.0 - peerDependenciesMeta: - eslint-plugin-jest: - optional: true - eslint-plugin-testing-library: - optional: true - checksum: b265852455b1c10e9c5f0cebe199306fffc7f8e1b6548fcb0bccdc4415c288dfee8ab10717122a32275b91130dfb482dcbbc87d2fb79d8728d4c2bfa889f0915 +"eslint-config-react-app@npm:^7.0.1": + version: 7.0.1 + resolution: "eslint-config-react-app@npm:7.0.1" + dependencies: + "@babel/core": ^7.16.0 + "@babel/eslint-parser": ^7.16.3 + "@rushstack/eslint-patch": ^1.1.0 + "@typescript-eslint/eslint-plugin": ^5.5.0 + "@typescript-eslint/parser": ^5.5.0 + babel-preset-react-app: ^10.0.1 + confusing-browser-globals: ^1.0.11 + eslint-plugin-flowtype: ^8.0.3 + eslint-plugin-import: ^2.25.3 + eslint-plugin-jest: ^25.3.0 + eslint-plugin-jsx-a11y: ^6.5.1 + eslint-plugin-react: ^7.27.1 + eslint-plugin-react-hooks: ^4.3.0 + eslint-plugin-testing-library: ^5.0.1 + peerDependencies: + eslint: ^8.0.0 + checksum: a67e0821809e62308d6e419753fa2acfc7cd353659fab08cf34735f59c6c66910c0b6fda0471c4ec0d712ce762d65efc6431b39569f8d575e2d9bdfc384e0824 languageName: node linkType: hard @@ -8883,182 +10708,203 @@ __metadata: languageName: node linkType: hard -"eslint-module-utils@npm:^2.8.0": - version: 2.8.1 - resolution: "eslint-module-utils@npm:2.8.1" +"eslint-module-utils@npm:^2.12.1": + version: 2.12.1 + resolution: "eslint-module-utils@npm:2.12.1" dependencies: debug: ^3.2.7 peerDependenciesMeta: eslint: optional: true - checksum: 3cecd99b6baf45ffc269167da0f95dcb75e5aa67b93d73a3bab63e2a7eedd9cdd6f188eed048e2f57c1b77db82c9cbf2adac20b512fa70e597d863dd3720170d + checksum: 2f074670d8c934687820a83140048776b28bbaf35fc37f35623f63cc9c438d496d11f0683b4feabb9a120435435d4a69604b1c6c567f118be2c9a0aba6760fc1 + languageName: node + linkType: hard + +"eslint-plugin-cypress@npm:4.3.0": + version: 4.3.0 + resolution: "eslint-plugin-cypress@npm:4.3.0" + dependencies: + globals: ^15.15.0 + peerDependencies: + eslint: ">=9" + checksum: 6e385e0111bce47b81defe04bf07bb81646e7a96266564e4b3835a9c7e768fd30871461ce2dfdcacdcded09b5e03cce9e47dea392557dfaa96dd5bf1138f1de8 languageName: node linkType: hard -"eslint-plugin-flowtype@npm:^5.2.0": - version: 5.10.0 - resolution: "eslint-plugin-flowtype@npm:5.10.0" +"eslint-plugin-flowtype@npm:^8.0.3": + version: 8.0.3 + resolution: "eslint-plugin-flowtype@npm:8.0.3" dependencies: - lodash: ^4.17.15 + lodash: ^4.17.21 string-natural-compare: ^3.0.1 peerDependencies: - eslint: ^7.1.0 - checksum: 791cd53c886bf819d52d6353cdfb4d49276dcd8a14f564a85d275d5017d81c7b1cc1921013ac9749f69c3f1bc4d23f36182137aab42bc059c2ae3f9773dd7740 + "@babel/plugin-syntax-flow": ^7.14.5 + "@babel/plugin-transform-react-jsx": ^7.14.9 + eslint: ^8.1.0 + checksum: 30e63c5357b0b5571f39afed51e59c140084f4aa53c106b1fd04f26da42b268908466daa6020b92943e71409bdaee1c67202515ed9012404d027cc92cb03cefa languageName: node linkType: hard -"eslint-plugin-import@npm:^2.22.1": - version: 2.29.1 - resolution: "eslint-plugin-import@npm:2.29.1" +"eslint-plugin-import@npm:^2.25.3": + version: 2.32.0 + resolution: "eslint-plugin-import@npm:2.32.0" dependencies: - array-includes: ^3.1.7 - array.prototype.findlastindex: ^1.2.3 - array.prototype.flat: ^1.3.2 - array.prototype.flatmap: ^1.3.2 + "@rtsao/scc": ^1.1.0 + array-includes: ^3.1.9 + array.prototype.findlastindex: ^1.2.6 + array.prototype.flat: ^1.3.3 + array.prototype.flatmap: ^1.3.3 debug: ^3.2.7 doctrine: ^2.1.0 eslint-import-resolver-node: ^0.3.9 - eslint-module-utils: ^2.8.0 - hasown: ^2.0.0 - is-core-module: ^2.13.1 + eslint-module-utils: ^2.12.1 + hasown: ^2.0.2 + is-core-module: ^2.16.1 is-glob: ^4.0.3 minimatch: ^3.1.2 - object.fromentries: ^2.0.7 - object.groupby: ^1.0.1 - object.values: ^1.1.7 + object.fromentries: ^2.0.8 + object.groupby: ^1.0.3 + object.values: ^1.2.1 semver: ^6.3.1 + string.prototype.trimend: ^1.0.9 tsconfig-paths: ^3.15.0 peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: e65159aef808136d26d029b71c8c6e4cb5c628e65e5de77f1eb4c13a379315ae55c9c3afa847f43f4ff9df7e54515c77ffc6489c6a6f81f7dd7359267577468c + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + checksum: 8cd40595b5e4346d3698eb577014b4b6d0ba57b7b9edf975be4f052a89330ec202d0cc5c3861d37ebeafa151b6264821410243889b0c31710911a6b625bcf76b languageName: node linkType: hard -"eslint-plugin-jest@npm:^24.1.0": - version: 24.7.0 - resolution: "eslint-plugin-jest@npm:24.7.0" +"eslint-plugin-jest@npm:^25.3.0": + version: 25.7.0 + resolution: "eslint-plugin-jest@npm:25.7.0" dependencies: - "@typescript-eslint/experimental-utils": ^4.0.1 + "@typescript-eslint/experimental-utils": ^5.0.0 peerDependencies: - "@typescript-eslint/eslint-plugin": ">= 4" - eslint: ">=5" + "@typescript-eslint/eslint-plugin": ^4.0.0 || ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: "@typescript-eslint/eslint-plugin": optional: true - checksum: a4056582825ab3359d2e0e3aae50518f6f867d1cfb3240496605247d3ff9c84b4164f1a7e1f7087d5a2eae1343d738ada1ba74c422b13ad20b737601dc47ae08 + jest: + optional: true + checksum: fc6da96131f4cbf33d15ef911ec8e600ccd71deb97d73c0ca340427cef7b01ff41a797e2e7d1e351abf97321a46ed0c0acff5ee8eeedac94961dd6dad1f718a9 languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:^6.3.1": - version: 6.8.0 - resolution: "eslint-plugin-jsx-a11y@npm:6.8.0" +"eslint-plugin-jsx-a11y@npm:^6.5.1": + version: 6.10.2 + resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" dependencies: - "@babel/runtime": ^7.23.2 - aria-query: ^5.3.0 - array-includes: ^3.1.7 + aria-query: ^5.3.2 + array-includes: ^3.1.8 array.prototype.flatmap: ^1.3.2 ast-types-flow: ^0.0.8 - axe-core: =4.7.0 - axobject-query: ^3.2.1 + axe-core: ^4.10.0 + axobject-query: ^4.1.0 damerau-levenshtein: ^1.0.8 emoji-regex: ^9.2.2 - es-iterator-helpers: ^1.0.15 - hasown: ^2.0.0 + hasown: ^2.0.2 jsx-ast-utils: ^3.3.5 language-tags: ^1.0.9 minimatch: ^3.1.2 - object.entries: ^1.1.7 - object.fromentries: ^2.0.7 + object.fromentries: ^2.0.8 + safe-regex-test: ^1.0.3 + string.prototype.includes: ^2.0.1 peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 3dec00e2a3089c4c61ac062e4196a70985fb7eda1fd67fe035363d92578debde92fdb8ed2e472321fc0d71e75f4a1e8888c6a3218c14dd93c8e8d19eb6f51554 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + checksum: 0cc861398fa26ada61ed5703eef5b335495fcb96253263dcd5e399488ff019a2636372021baacc040e3560d1a34bfcd5d5ad9f1754f44cd0509c956f7df94050 languageName: node linkType: hard -"eslint-plugin-prettier@npm:^4.2.1": - version: 4.2.1 - resolution: "eslint-plugin-prettier@npm:4.2.1" +"eslint-plugin-prettier@npm:^5.2.2": + version: 5.5.4 + resolution: "eslint-plugin-prettier@npm:5.5.4" dependencies: prettier-linter-helpers: ^1.0.0 + synckit: ^0.11.7 peerDependencies: - eslint: ">=7.28.0" - prettier: ">=2.0.0" + "@types/eslint": ">=8.0.0" + eslint: ">=8.0.0" + eslint-config-prettier: ">= 7.0.0 <10.0.0 || >=10.1.0" + prettier: ">=3.0.0" peerDependenciesMeta: + "@types/eslint": + optional: true eslint-config-prettier: optional: true - checksum: b9e839d2334ad8ec7a5589c5cb0f219bded260839a857d7a486997f9870e95106aa59b8756ff3f37202085ebab658de382b0267cae44c3a7f0eb0bcc03a4f6d6 + checksum: 0dd05ed85018ab0e98da80325b7bd4c4ab6dd684398f1270a7c8cf4261df714dd4502ba4c7f85f651aade9989da0a7d2adda03af8873b73b52014141abf385de languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^4.2.0": - version: 4.6.0 - resolution: "eslint-plugin-react-hooks@npm:4.6.0" +"eslint-plugin-react-hooks@npm:^4.3.0": + version: 4.6.2 + resolution: "eslint-plugin-react-hooks@npm:4.6.2" peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 23001801f14c1d16bf0a837ca7970d9dd94e7b560384b41db378b49b6e32dc43d6e2790de1bd737a652a86f81a08d6a91f402525061b47719328f586a57e86c3 + checksum: 395c433610f59577cfcf3f2e42bcb130436c8a0b3777ac64f441d88c5275f4fcfc89094cedab270f2822daf29af1079151a7a6579a8e9ea8cee66540ba0384c4 languageName: node linkType: hard -"eslint-plugin-react@npm:^7.21.5": - version: 7.34.1 - resolution: "eslint-plugin-react@npm:7.34.1" +"eslint-plugin-react@npm:^7.27.1": + version: 7.37.5 + resolution: "eslint-plugin-react@npm:7.37.5" dependencies: - array-includes: ^3.1.7 - array.prototype.findlast: ^1.2.4 - array.prototype.flatmap: ^1.3.2 - array.prototype.toreversed: ^1.1.2 - array.prototype.tosorted: ^1.1.3 + array-includes: ^3.1.8 + array.prototype.findlast: ^1.2.5 + array.prototype.flatmap: ^1.3.3 + array.prototype.tosorted: ^1.1.4 doctrine: ^2.1.0 - es-iterator-helpers: ^1.0.17 + es-iterator-helpers: ^1.2.1 estraverse: ^5.3.0 + hasown: ^2.0.2 jsx-ast-utils: ^2.4.1 || ^3.0.0 minimatch: ^3.1.2 - object.entries: ^1.1.7 - object.fromentries: ^2.0.7 - object.hasown: ^1.1.3 - object.values: ^1.1.7 + object.entries: ^1.1.9 + object.fromentries: ^2.0.8 + object.values: ^1.2.1 prop-types: ^15.8.1 resolve: ^2.0.0-next.5 semver: ^6.3.1 - string.prototype.matchall: ^4.0.10 + string.prototype.matchall: ^4.0.12 + string.prototype.repeat: ^1.0.0 peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 82f391c5a093235c3bc2f664c54e009c49460778ee7d1b86c1536df9ac4d2a80d1dedc9241ac797df4a9dced936e955d9c89042fb3ac8d017b5359d1320d3c0f + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + checksum: 8675e7558e646e3c2fcb04bb60cfe416000b831ef0b363f0117838f5bfc799156113cb06058ad4d4b39fc730903b7360b05038da11093064ca37caf76b7cf2ca languageName: node linkType: hard -"eslint-plugin-testing-library@npm:^3.9.2": - version: 3.10.2 - resolution: "eslint-plugin-testing-library@npm:3.10.2" +"eslint-plugin-testing-library@npm:^5.0.1": + version: 5.11.1 + resolution: "eslint-plugin-testing-library@npm:5.11.1" dependencies: - "@typescript-eslint/experimental-utils": ^3.10.1 + "@typescript-eslint/utils": ^5.58.0 peerDependencies: - eslint: ^5 || ^6 || ^7 - checksum: 3859d4a4816b130cfefc3b45bc7d303aff19b8d4e83a5e35ca3d634de9f3c4aa1b4340cb4f41e2d1bfe70b173562b9882c58ac48be4e07ddf6a1f88659e2604d + eslint: ^7.5.0 || ^8.0.0 + checksum: 9f3fc68ef9f13016a4381b33ab5dbffcc189e5de3eaeba184bcf7d2771faa7f54e59c04b652162fb1c0f83fb52428dd909db5450a25508b94be59eba69fcc990 languageName: node linkType: hard -"eslint-scope@npm:^4.0.3": - version: 4.0.3 - resolution: "eslint-scope@npm:4.0.3" +"eslint-scope@npm:5.1.1, eslint-scope@npm:^5.1.1": + version: 5.1.1 + resolution: "eslint-scope@npm:5.1.1" dependencies: - esrecurse: ^4.1.0 + esrecurse: ^4.3.0 estraverse: ^4.1.1 - checksum: c5f835f681884469991fe58d76a554688d9c9e50811299ccd4a8f79993a039f5bcb0ee6e8de2b0017d97c794b5832ef3b21c9aac66228e3aa0f7a0485bcfb65b + checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb languageName: node linkType: hard -"eslint-scope@npm:^5.0.0, eslint-scope@npm:^5.1.1": - version: 5.1.1 - resolution: "eslint-scope@npm:5.1.1" +"eslint-scope@npm:^7.2.2": + version: 7.2.2 + resolution: "eslint-scope@npm:7.2.2" dependencies: esrecurse: ^4.3.0 - estraverse: ^4.1.1 - checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb + estraverse: ^5.2.0 + checksum: ec97dbf5fb04b94e8f4c5a91a7f0a6dd3c55e46bfc7bbcd0e3138c3a76977570e02ed89a1810c778dcd72072ff0e9621ba1379b4babe53921d71e2e4486fda3e languageName: node linkType: hard -"eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0": +"eslint-utils@npm:^2.1.0": version: 2.1.0 resolution: "eslint-utils@npm:2.1.0" dependencies: @@ -9067,49 +10913,51 @@ __metadata: languageName: node linkType: hard -"eslint-utils@npm:^3.0.0": - version: 3.0.0 - resolution: "eslint-utils@npm:3.0.0" - dependencies: - eslint-visitor-keys: ^2.0.0 - peerDependencies: - eslint: ">=5" - checksum: 0668fe02f5adab2e5a367eee5089f4c39033af20499df88fe4e6aba2015c20720404d8c3d6349b6f716b08fdf91b9da4e5d5481f265049278099c4c836ccb619 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^1.0.0, eslint-visitor-keys@npm:^1.1.0, eslint-visitor-keys@npm:^1.3.0": +"eslint-visitor-keys@npm:^1.1.0, eslint-visitor-keys@npm:^1.3.0": version: 1.3.0 resolution: "eslint-visitor-keys@npm:1.3.0" checksum: 37a19b712f42f4c9027e8ba98c2b06031c17e0c0a4c696cd429bd9ee04eb43889c446f2cd545e1ff51bef9593fcec94ecd2c2ef89129fcbbf3adadbef520376a languageName: node linkType: hard -"eslint-visitor-keys@npm:^2.0.0": +"eslint-visitor-keys@npm:^2.0.0, eslint-visitor-keys@npm:^2.1.0": version: 2.1.0 resolution: "eslint-visitor-keys@npm:2.1.0" checksum: e3081d7dd2611a35f0388bbdc2f5da60b3a3c5b8b6e928daffff7391146b434d691577aa95064c8b7faad0b8a680266bcda0a42439c18c717b80e6718d7e267d languageName: node linkType: hard -"eslint-webpack-plugin@npm:^2.5.2": - version: 2.7.0 - resolution: "eslint-webpack-plugin@npm:2.7.0" +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": + version: 3.4.3 + resolution: "eslint-visitor-keys@npm:3.4.3" + checksum: 36e9ef87fca698b6fd7ca5ca35d7b2b6eeaaf106572e2f7fd31c12d3bfdaccdb587bba6d3621067e5aece31c8c3a348b93922ab8f7b2cbc6aaab5e1d89040c60 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^4.2.0": + version: 4.2.1 + resolution: "eslint-visitor-keys@npm:4.2.1" + checksum: 3a77e3f99a49109f6fb2c5b7784bc78f9743b834d238cdba4d66c602c6b52f19ed7bcd0a5c5dbbeae3a8689fd785e76c001799f53d2228b278282cf9f699fff5 + languageName: node + linkType: hard + +"eslint-webpack-plugin@npm:^3.1.1": + version: 3.2.0 + resolution: "eslint-webpack-plugin@npm:3.2.0" dependencies: - "@types/eslint": ^7.29.0 - arrify: ^2.0.1 - jest-worker: ^27.5.1 + "@types/eslint": ^7.29.0 || ^8.4.1 + jest-worker: ^28.0.2 micromatch: ^4.0.5 normalize-path: ^3.0.0 - schema-utils: ^3.1.1 + schema-utils: ^4.0.0 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - webpack: ^4.0.0 || ^5.0.0 - checksum: b6fd7cf4c49078b345a908b82b0bee06bc82ab0cec214ddd5fe5bb18b065765d52a07ad4077f6bba5830ba2f55f37d8f2208a52d11f34ee29df81153e3124d9c + webpack: ^5.0.0 + checksum: 095034c35e773fdb21ec7e597ae1f8a6899679c290db29d8568ca94619e8c7f4971f0f9edccc8a965322ab8af9286c87205985a38f4fdcf17654aee7cd8bb7b5 languageName: node linkType: hard -"eslint@npm:^7.0.0, eslint@npm:^7.11.0": +"eslint@npm:^7.0.0": version: 7.32.0 resolution: "eslint@npm:7.32.0" dependencies: @@ -9159,15 +11007,51 @@ __metadata: languageName: node linkType: hard -"esniff@npm:^2.0.1": - version: 2.0.1 - resolution: "esniff@npm:2.0.1" +"eslint@npm:^8.3.0": + version: 8.57.1 + resolution: "eslint@npm:8.57.1" dependencies: - d: ^1.0.1 - es5-ext: ^0.10.62 - event-emitter: ^0.3.5 - type: ^2.7.2 - checksum: d814c0e5c39bce9925b2e65b6d8767af72c9b54f35a65f9f3d6e8c606dce9aebe35a9599d30f15b0807743f88689f445163cfb577a425de4fb8c3c5bc16710cc + "@eslint-community/eslint-utils": ^4.2.0 + "@eslint-community/regexpp": ^4.6.1 + "@eslint/eslintrc": ^2.1.4 + "@eslint/js": 8.57.1 + "@humanwhocodes/config-array": ^0.13.0 + "@humanwhocodes/module-importer": ^1.0.1 + "@nodelib/fs.walk": ^1.2.8 + "@ungap/structured-clone": ^1.2.0 + ajv: ^6.12.4 + chalk: ^4.0.0 + cross-spawn: ^7.0.2 + debug: ^4.3.2 + doctrine: ^3.0.0 + escape-string-regexp: ^4.0.0 + eslint-scope: ^7.2.2 + eslint-visitor-keys: ^3.4.3 + espree: ^9.6.1 + esquery: ^1.4.2 + esutils: ^2.0.2 + fast-deep-equal: ^3.1.3 + file-entry-cache: ^6.0.1 + find-up: ^5.0.0 + glob-parent: ^6.0.2 + globals: ^13.19.0 + graphemer: ^1.4.0 + ignore: ^5.2.0 + imurmurhash: ^0.1.4 + is-glob: ^4.0.0 + is-path-inside: ^3.0.3 + js-yaml: ^4.1.0 + json-stable-stringify-without-jsonify: ^1.0.1 + levn: ^0.4.1 + lodash.merge: ^4.6.2 + minimatch: ^3.1.2 + natural-compare: ^1.4.0 + optionator: ^0.9.3 + strip-ansi: ^6.0.1 + text-table: ^0.2.0 + bin: + eslint: bin/eslint.js + checksum: e2489bb7f86dd2011967759a09164e65744ef7688c310bc990612fc26953f34cc391872807486b15c06833bdff737726a23e9b4cdba5de144c311377dc41d91b languageName: node linkType: hard @@ -9182,6 +11066,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^9.6.0, espree@npm:^9.6.1": + version: 9.6.1 + resolution: "espree@npm:9.6.1" + dependencies: + acorn: ^8.9.0 + acorn-jsx: ^5.3.2 + eslint-visitor-keys: ^3.4.1 + checksum: eb8c149c7a2a77b3f33a5af80c10875c3abd65450f60b8af6db1bfcfa8f101e21c1e56a561c6dc13b848e18148d43469e7cd208506238554fb5395a9ea5a1ab9 + languageName: node + linkType: hard + "esprima@npm:1.2.2": version: 1.2.2 resolution: "esprima@npm:1.2.2" @@ -9202,16 +11097,16 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.0": - version: 1.5.0 - resolution: "esquery@npm:1.5.0" +"esquery@npm:^1.4.0, esquery@npm:^1.4.2": + version: 1.6.0 + resolution: "esquery@npm:1.6.0" dependencies: estraverse: ^5.1.0 - checksum: aefb0d2596c230118656cd4ec7532d447333a410a48834d80ea648b1e7b5c9bc9ed8b5e33a89cb04e487b60d622f44cf5713bf4abed7c97343edefdc84a35900 + checksum: 08ec4fe446d9ab27186da274d979558557fbdbbd10968fa9758552482720c54152a5640e08b9009e5a30706b66aba510692054d4129d32d0e12e05bbc0b96fb2 languageName: node linkType: hard -"esrecurse@npm:^4.1.0, esrecurse@npm:^4.3.0": +"esrecurse@npm:^4.3.0": version: 4.3.0 resolution: "esrecurse@npm:4.3.0" dependencies: @@ -9234,10 +11129,10 @@ __metadata: languageName: node linkType: hard -"estree-walker@npm:^0.6.1": - version: 0.6.1 - resolution: "estree-walker@npm:0.6.1" - checksum: 9d6f82a4921f11eec18f8089fb3cce6e53bcf45a8e545c42a2674d02d055fb30f25f90495f8be60803df6c39680c80dcee7f944526867eb7aa1fc9254883b23d +"estree-util-is-identifier-name@npm:^3.0.0": + version: 3.0.0 + resolution: "estree-util-is-identifier-name@npm:3.0.0" + checksum: ea3909f0188ea164af0aadeca87c087e3e5da78d76da5ae9c7954ff1340ea3e4679c4653bbf4299ffb70caa9b322218cc1128db2541f3d2976eb9704f9857787 languageName: node linkType: hard @@ -9248,6 +11143,15 @@ __metadata: languageName: node linkType: hard +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": ^1.0.0 + checksum: a65728d5727b71de172c5df323385755a16c0fdab8234dc756c3854cfee343261ddfbb72a809a5660fac8c75d960bb3e21aa898c2d7e9b19bb298482ca58a3af + languageName: node + linkType: hard + "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -9255,98 +11159,48 @@ __metadata: languageName: node linkType: hard -"etag@npm:~1.8.1": +"etag@npm:^1.8.1, etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff languageName: node linkType: hard -"event-emitter@npm:^0.3.5": - version: 0.3.5 - resolution: "event-emitter@npm:0.3.5" - dependencies: - d: 1 - es5-ext: ~0.10.14 - checksum: 27c1399557d9cd7e0aa0b366c37c38a4c17293e3a10258e8b692a847dd5ba9fb90429c3a5a1eeff96f31f6fa03ccbd31d8ad15e00540b22b22f01557be706030 - languageName: node - linkType: hard - -"eventemitter3@npm:^3.1.0": - version: 3.1.2 - resolution: "eventemitter3@npm:3.1.2" - checksum: 81e4e82b8418f5cfd986d2b4a2fa5397ac4eb8134e09bcb47005545e22fdf8e9e61d5c053d34651112245aae411bdfe6d0ad5511da0400743fef5fc38bfcfbe3 - languageName: node - linkType: hard - -"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.4": +"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.1, eventemitter3@npm:^4.0.4": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7" checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 languageName: node linkType: hard -"events@npm:^3.0.0, events@npm:^3.3.0": - version: 3.3.0 - resolution: "events@npm:3.3.0" - checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780 - languageName: node - linkType: hard - -"eventsource@npm:^2.0.2": - version: 2.0.2 - resolution: "eventsource@npm:2.0.2" - checksum: c0072d972753e10c705d9b2285b559184bf29d011bc208973dde9c8b6b8b7b6fdad4ef0846cecb249f7b1585e860fdf324cbd2ac854a76bc53649e797496e99a - languageName: node - linkType: hard - -"evp_bytestokey@npm:^1.0.0, evp_bytestokey@npm:^1.0.3": - version: 1.0.3 - resolution: "evp_bytestokey@npm:1.0.3" - dependencies: - md5.js: ^1.3.4 - node-gyp: latest - safe-buffer: ^5.1.1 - checksum: ad4e1577f1a6b721c7800dcc7c733fe01f6c310732bb5bf2240245c2a5b45a38518b91d8be2c610611623160b9d1c0e91f1ce96d639f8b53e8894625cf20fa45 - languageName: node - linkType: hard - -"exec-sh@npm:^0.3.2": - version: 0.3.6 - resolution: "exec-sh@npm:0.3.6" - checksum: 0be4f06929c8e4834ea4812f29fe59e2dfcc1bc3fc4b4bb71acb38a500c3b394628a05ef7ba432520bc6c5ec4fadab00cc9c513c4ff6a32104965af302e998e0 +"eventemitter3@npm:^5.0.1": + version: 5.0.1 + resolution: "eventemitter3@npm:5.0.1" + checksum: 543d6c858ab699303c3c32e0f0f47fc64d360bf73c3daf0ac0b5079710e340d6fe9f15487f94e66c629f5f82cd1a8678d692f3dbb6f6fcd1190e1b97fcad36f8 languageName: node linkType: hard -"execa@npm:^1.0.0": - version: 1.0.0 - resolution: "execa@npm:1.0.0" - dependencies: - cross-spawn: ^6.0.0 - get-stream: ^4.0.0 - is-stream: ^1.1.0 - npm-run-path: ^2.0.0 - p-finally: ^1.0.0 - signal-exit: ^3.0.0 - strip-eof: ^1.0.0 - checksum: ddf1342c1c7d02dd93b41364cd847640f6163350d9439071abf70bf4ceb1b9b2b2e37f54babb1d8dc1df8e0d8def32d0e81e74a2e62c3e1d70c303eb4c306bc4 +"events@npm:^3.2.0": + version: 3.3.0 + resolution: "events@npm:3.3.0" + checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780 languageName: node linkType: hard -"execa@npm:^4.0.0": - version: 4.1.0 - resolution: "execa@npm:4.1.0" +"execa@npm:^5.0.0": + version: 5.1.1 + resolution: "execa@npm:5.1.1" dependencies: - cross-spawn: ^7.0.0 - get-stream: ^5.0.0 - human-signals: ^1.1.1 + cross-spawn: ^7.0.3 + get-stream: ^6.0.0 + human-signals: ^2.1.0 is-stream: ^2.0.0 merge-stream: ^2.0.0 - npm-run-path: ^4.0.0 - onetime: ^5.1.0 - signal-exit: ^3.0.2 + npm-run-path: ^4.0.1 + onetime: ^5.1.2 + signal-exit: ^3.0.3 strip-final-newline: ^2.0.0 - checksum: e30d298934d9c52f90f3847704fd8224e849a081ab2b517bbc02f5f7732c24e56a21f14cb96a08256deffeb2d12b2b7cb7e2b014a12fb36f8d3357e06417ed55 + checksum: fba9022c8c8c15ed862847e94c252b3d946036d7547af310e344a527e59021fd8b6bb0723883ea87044dc4f0201f949046993124a42ccb0855cae5bf8c786343 languageName: node linkType: hard @@ -9357,45 +11211,29 @@ __metadata: languageName: node linkType: hard -"expand-brackets@npm:^2.1.4": - version: 2.1.4 - resolution: "expand-brackets@npm:2.1.4" - dependencies: - debug: ^2.3.3 - define-property: ^0.2.5 - extend-shallow: ^2.0.1 - posix-character-classes: ^0.1.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: 1781d422e7edfa20009e2abda673cadb040a6037f0bd30fcd7357304f4f0c284afd420d7622722ca4a016f39b6d091841ab57b401c1f7e2e5131ac65b9f14fa1 +"expand-template@npm:^2.0.3": + version: 2.0.3 + resolution: "expand-template@npm:2.0.3" + checksum: 588c19847216421ed92befb521767b7018dc88f88b0576df98cb242f20961425e96a92cbece525ef28cc5becceae5d544ae0f5b9b5e2aa05acb13716ca5b3099 languageName: node linkType: hard -"expect@npm:^26.6.0, expect@npm:^26.6.2": - version: 26.6.2 - resolution: "expect@npm:26.6.2" - dependencies: - "@jest/types": ^26.6.2 - ansi-styles: ^4.0.0 - jest-get-type: ^26.3.0 - jest-matcher-utils: ^26.6.2 - jest-message-util: ^26.6.2 - jest-regex-util: ^26.0.0 - checksum: 79a9b888c5c6d37d11f2cb76def6cf1dc8ff098d38662ee20c9f2ee0da67e9a93435f2327854b2e7554732153870621843e7f83e8cefb1250447ee2bc39883a4 +"expect-type@npm:^1.1.0, expect-type@npm:^1.2.1": + version: 1.2.2 + resolution: "expect-type@npm:1.2.2" + checksum: dc347e853b059f95f3c897db2a6f5eab37662e7a0c3c9fcf014f25afa90fca76e5235246fd37e08f2c0535901b52f66b8ace1e0ee236673c4f70c36724bd3f42 languageName: node linkType: hard -"expect@npm:^28.0.0": - version: 28.1.3 - resolution: "expect@npm:28.1.3" +"expect@npm:^27.5.1": + version: 27.5.1 + resolution: "expect@npm:27.5.1" dependencies: - "@jest/expect-utils": ^28.1.3 - jest-get-type: ^28.0.2 - jest-matcher-utils: ^28.1.3 - jest-message-util: ^28.1.3 - jest-util: ^28.1.3 - checksum: 101e0090de300bcafedb7dbfd19223368a2251ce5fe0105bbb6de5720100b89fb6b64290ebfb42febc048324c76d6a4979cdc4b61eb77747857daf7a5de9b03d + "@jest/types": ^27.5.1 + jest-get-type: ^27.5.1 + jest-matcher-utils: ^27.5.1 + jest-message-util: ^27.5.1 + checksum: b2c66beb52de53ef1872165aace40224e722bca3c2274c54cfa74b6d617d55cf0ccdbf36783ccd64dbea501b280098ed33fd0b207d4f15bc03cd3c7a24364a6a languageName: node linkType: hard @@ -9413,20 +11251,20 @@ __metadata: linkType: hard "exponential-backoff@npm:^3.1.1": - version: 3.1.1 - resolution: "exponential-backoff@npm:3.1.1" - checksum: 3d21519a4f8207c99f7457287291316306255a328770d320b401114ec8481986e4e467e854cb9914dd965e0a1ca810a23ccb559c642c88f4c7f55c55778a9b48 + version: 3.1.2 + resolution: "exponential-backoff@npm:3.1.2" + checksum: 7e191e3dd6edd8c56c88f2c8037c98fbb8034fe48778be53ed8cb30ccef371a061a4e999a469aab939b92f8f12698f3b426d52f4f76b7a20da5f9f98c3cbc862 languageName: node linkType: hard "express-jwt@npm:^7.7.5": - version: 7.7.7 - resolution: "express-jwt@npm:7.7.7" + version: 7.7.8 + resolution: "express-jwt@npm:7.7.8" dependencies: "@types/jsonwebtoken": ^8.5.8 express-unless: ^2.1.3 - jsonwebtoken: ^8.5.1 - checksum: b3aec510ce490cd8d449604c82ce1debf9b8c215fb0220f78d07e86c555fb06ca93b4199da135c00e62bb98c67a47fac8c1fdcc6ea74f2047f4e2defbc4578fe + jsonwebtoken: ^9.0.2 + checksum: 88ea57e7c033bafd5918cdbddd67f469a3e70f9ae3c5c973b370ef0b9f86e3499ea132fb15d9ecdddcc97d8305dec1f759a1fdf4dfc8a1a9e6642e166188e28b languageName: node linkType: hard @@ -9447,70 +11285,77 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.17.1": - version: 4.19.2 - resolution: "express@npm:4.19.2" +"express@npm:^4.0.0, express@npm:^4.17.3": + version: 4.21.2 + resolution: "express@npm:4.21.2" dependencies: accepts: ~1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: ~1.0.4 - cookie: 0.6.0 + cookie: 0.7.1 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 etag: ~1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.1 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.1 + merge-descriptors: 1.0.3 methods: ~1.1.2 on-finished: 2.4.1 parseurl: ~1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.12 proxy-addr: ~2.0.7 - qs: 6.11.0 + qs: 6.13.0 range-parser: ~1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + 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 - checksum: 212dbd6c2c222a96a61bc927639c95970a53b06257080bb9e2838adb3bffdb966856551fdad1ab5dd654a217c35db94f987d0aa88d48fb04d306340f5f34dca5 - languageName: node - linkType: hard - -"ext@npm:^1.7.0": - version: 1.7.0 - resolution: "ext@npm:1.7.0" - dependencies: - type: ^2.7.2 - checksum: ef481f9ef45434d8c867cfd09d0393b60945b7c8a1798bedc4514cb35aac342ccb8d8ecb66a513e6a2b4ec1e294a338e3124c49b29736f8e7c735721af352c31 - languageName: node - linkType: hard - -"extend-shallow@npm:^2.0.1": - version: 2.0.1 - resolution: "extend-shallow@npm:2.0.1" - dependencies: - is-extendable: ^0.1.0 - checksum: 8fb58d9d7a511f4baf78d383e637bd7d2e80843bd9cd0853649108ea835208fb614da502a553acc30208e1325240bb7cc4a68473021612496bb89725483656d8 + checksum: 3aef1d355622732e20b8f3a7c112d4391d44e2131f4f449e1f273a309752a41abfad714e881f177645517cbe29b3ccdc10b35e7e25c13506114244a5b72f549d languageName: node linkType: hard -"extend-shallow@npm:^3.0.0, extend-shallow@npm:^3.0.2": - version: 3.0.2 - resolution: "extend-shallow@npm:3.0.2" - dependencies: - assign-symbols: ^1.0.0 - is-extendable: ^1.0.1 - checksum: a920b0cd5838a9995ace31dfd11ab5e79bf6e295aa566910ce53dff19f4b1c0fda2ef21f26b28586c7a2450ca2b42d97bd8c0f5cec9351a819222bf861e02461 +"express@npm:^5.0.0": + version: 5.1.0 + resolution: "express@npm:5.1.0" + dependencies: + accepts: ^2.0.0 + body-parser: ^2.2.0 + content-disposition: ^1.0.0 + content-type: ^1.0.5 + cookie: ^0.7.1 + cookie-signature: ^1.2.1 + debug: ^4.4.0 + encodeurl: ^2.0.0 + escape-html: ^1.0.3 + etag: ^1.8.1 + finalhandler: ^2.1.0 + fresh: ^2.0.0 + http-errors: ^2.0.0 + merge-descriptors: ^2.0.0 + mime-types: ^3.0.0 + on-finished: ^2.4.1 + once: ^1.4.0 + parseurl: ^1.3.3 + proxy-addr: ^2.0.7 + qs: ^6.14.0 + range-parser: ^1.2.1 + router: ^2.2.0 + send: ^1.1.0 + serve-static: ^2.2.0 + statuses: ^2.0.1 + type-is: ^2.0.1 + vary: ^1.1.2 + checksum: 06e6141780c6c4780111f971ce062c83d4cf4862c40b43caf1d95afcbb58d7422c560503b8c9d04c7271511525d09cbdbe940bcaad63970fd4c1b9f6fd713bdb languageName: node linkType: hard @@ -9521,33 +11366,6 @@ __metadata: languageName: node linkType: hard -"external-editor@npm:^3.0.3": - version: 3.1.0 - resolution: "external-editor@npm:3.1.0" - dependencies: - chardet: ^0.7.0 - iconv-lite: ^0.4.24 - tmp: ^0.0.33 - checksum: 1c2a616a73f1b3435ce04030261bed0e22d4737e14b090bb48e58865da92529c9f2b05b893de650738d55e692d071819b45e1669259b2b354bc3154d27a698c7 - languageName: node - linkType: hard - -"extglob@npm:^2.0.4": - version: 2.0.4 - resolution: "extglob@npm:2.0.4" - dependencies: - array-unique: ^0.3.2 - define-property: ^1.0.0 - expand-brackets: ^2.1.4 - extend-shallow: ^2.0.1 - fragment-cache: ^0.2.1 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: a41531b8934735b684cef5e8c5a01d0f298d7d384500ceca38793a9ce098125aab04ee73e2d75d5b2901bc5dddd2b64e1b5e3bf19139ea48bac52af4a92f1d00 - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -9562,20 +11380,27 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.1.1, fast-glob@npm:^3.2.9": - version: 3.3.2 - resolution: "fast-glob@npm:3.3.2" +"fast-equals@npm:^5.0.1": + version: 5.2.2 + resolution: "fast-equals@npm:5.2.2" + checksum: 7156bcade0be5ee4dc335969d255a5815348d57080e1876fa1584451eafd0c92588de5f5840e55f81841b6d907ade2a49a46e4ec33e6f7a283a209c0fd8f8a59 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": + version: 3.3.3 + resolution: "fast-glob@npm:3.3.3" 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 - checksum: 900e4979f4dbc3313840078419245621259f349950411ca2fa445a2f9a1a6d98c3b5e7e0660c5ccd563aa61abe133a21765c6c0dec8e57da1ba71d8000b05ec1 + micromatch: ^4.0.8 + checksum: 0704d7b85c0305fd2cef37777337dfa26230fdd072dce9fb5c82a4b03156f3ffb8ed3e636033e65d45d2a5805a4e475825369a27404c0307f2db0c8eb3366fbd languageName: node linkType: hard -"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": +"fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: b191531e36c607977e5b1c47811158733c34ccb3bfde92c44798929e9b4154884378536d26ad90dfecd32e1ffc09c545d23535ad91b3161a27ddbb8ebe0cbecb @@ -9603,23 +11428,34 @@ __metadata: languageName: node linkType: hard -"fastparse@npm:^1.1.2": - version: 1.1.2 - resolution: "fastparse@npm:1.1.2" - checksum: c4d199809dc4e8acafeb786be49481cc9144de296e2d54df4540ccfd868d0df73afc649aba70a748925eb32bbc4208b723d6288adf92382275031a8c7e10c0aa +"fast-uri@npm:^3.0.1": + version: 3.1.0 + resolution: "fast-uri@npm:3.1.0" + checksum: daab0efd3548cc53d0db38ecc764d125773f8bd70c34552ff21abdc6530f26fa4cb1771f944222ca5e61a0a1a85d01a104848ff88c61736de445d97bd616ea7e + languageName: node + linkType: hard + +"fast-xml-parser@npm:5.2.5": + version: 5.2.5 + resolution: "fast-xml-parser@npm:5.2.5" + dependencies: + strnum: ^2.1.0 + bin: + fxparser: src/cli/cli.js + checksum: b12daa933bc226bd7df1e1ecbd305e561c83fd6e4a234b5e2728901deca25a9b9522b9d3ebafde41b1f4d87ab814e3efe18c636638580795fdbe4670a556be88 languageName: node linkType: hard "fastq@npm:^1.6.0": - version: 1.17.1 - resolution: "fastq@npm:1.17.1" + version: 1.19.1 + resolution: "fastq@npm:1.19.1" dependencies: reusify: ^1.0.4 - checksum: a8c5b26788d5a1763f88bae56a8ddeee579f935a831c5fe7a8268cea5b0a91fbfe705f612209e02d639b881d7b48e461a50da4a10cfaa40da5ca7cc9da098d88 + checksum: 7691d1794fb84ad0ec2a185f10e00f0e1713b894e2c9c4d42f0bc0ba5f8c00e6e655a202074ca0b91b9c3d977aab7c30c41a8dc069fb5368576ac0054870a0e6 languageName: node linkType: hard -"faye-websocket@npm:^0.11.3, faye-websocket@npm:^0.11.4": +"faye-websocket@npm:^0.11.3": version: 0.11.4 resolution: "faye-websocket@npm:0.11.4" dependencies: @@ -9637,19 +11473,15 @@ __metadata: languageName: node linkType: hard -"figgy-pudding@npm:^3.5.1": - version: 3.5.2 - resolution: "figgy-pudding@npm:3.5.2" - checksum: 4090bd66193693dcda605e44d6b8715d8fb5c92a67acd57826e55cf816a342f550d57e5638f822b39366e1b2fdb244e99b3068a37213aa1d6c1bf602b8fde5ae - languageName: node - linkType: hard - -"figures@npm:^3.0.0": - version: 3.2.0 - resolution: "figures@npm:3.2.0" - dependencies: - escape-string-regexp: ^1.0.5 - checksum: 85a6ad29e9aca80b49b817e7c89ecc4716ff14e3779d9835af554db91bac41c0f289c418923519392a1e582b4d10482ad282021330cd045bb7b80c84152f2a2b +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: bd537daa9d3cd53887eed35efa0eab2dbb1ca408790e10e024120e7a36c6e9ae2b33710cb8381e35def01bc9c1d7eaba746f886338413e68ff6ebaee07b9a6e8 languageName: node linkType: hard @@ -9662,15 +11494,15 @@ __metadata: languageName: node linkType: hard -"file-loader@npm:6.1.1": - version: 6.1.1 - resolution: "file-loader@npm:6.1.1" +"file-loader@npm:^6.2.0": + version: 6.2.0 + resolution: "file-loader@npm:6.2.0" dependencies: loader-utils: ^2.0.0 schema-utils: ^3.0.0 peerDependencies: webpack: ^4.0.0 || ^5.0.0 - checksum: 6369da5af456b640599d7ede7a3a9a55e485138a7829c583313d5165d0984c3d337de3aebee32fdfa3295facb4a44b74a9c3c956b1e0e30e8c96152106ff4b23 + checksum: faf43eecf233f4897b0150aaa874eeeac214e4f9de49738a9e0ef734a30b5260059e85b7edadf852b98e415f875bd5f12587768a93fd52aaf2e479ecf95fab20 languageName: node linkType: hard @@ -9681,64 +11513,57 @@ __metadata: languageName: node linkType: hard -"file-uri-to-path@npm:1.0.0": - version: 1.0.0 - resolution: "file-uri-to-path@npm:1.0.0" - checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 - languageName: node - linkType: hard - -"filesize@npm:6.1.0": - version: 6.1.0 - resolution: "filesize@npm:6.1.0" - checksum: c46d644cb562fba7b7e837d5cd339394492abaa06722018b91a97d2a63b6c753ef30653de5c03bf178c631185bf55c3561c28fa9ccc4e9755f42d853c6ed4d09 +"filelist@npm:^1.0.4": + version: 1.0.4 + resolution: "filelist@npm:1.0.4" + dependencies: + minimatch: ^5.0.1 + checksum: a303573b0821e17f2d5e9783688ab6fbfce5d52aaac842790ae85e704a6f5e4e3538660a63183d6453834dedf1e0f19a9dadcebfa3e926c72397694ea11f5160 languageName: node linkType: hard -"fill-range@npm:^4.0.0": - version: 4.0.0 - resolution: "fill-range@npm:4.0.0" - dependencies: - extend-shallow: ^2.0.1 - is-number: ^3.0.0 - repeat-string: ^1.6.1 - to-regex-range: ^2.1.0 - checksum: dbb5102467786ab42bc7a3ec7380ae5d6bfd1b5177b2216de89e4a541193f8ba599a6db84651bd2c58c8921db41b8cc3d699ea83b477342d3ce404020f73c298 +"filesize@npm:^8.0.6": + version: 8.0.7 + resolution: "filesize@npm:8.0.7" + checksum: 8603d27c5287b984cb100733640645e078f5f5ad65c6d913173e01fb99e09b0747828498fd86647685ccecb69be31f3587b9739ab1e50732116b2374aff4cbf9 languageName: node linkType: hard -"fill-range@npm:^7.0.1": - version: 7.0.1 - resolution: "fill-range@npm:7.0.1" +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" dependencies: to-regex-range: ^5.0.1 - checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917 + checksum: b4abfbca3839a3d55e4ae5ec62e131e2e356bf4859ce8480c64c4876100f4df292a63e5bb1618e1d7460282ca2b305653064f01654474aa35c68000980f17798 languageName: node linkType: hard -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" +"finalhandler@npm:1.3.1": + version: 1.3.1 + resolution: "finalhandler@npm:1.3.1" dependencies: debug: 2.6.9 - encodeurl: ~1.0.2 + 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 - checksum: 92effbfd32e22a7dff2994acedbd9bcc3aa646a3e919ea6a53238090e87097f8ef07cced90aa2cc421abdf993aefbdd5b00104d55c7c5479a8d00ed105b45716 + checksum: a8c58cd97c9cd47679a870f6833a7b417043f5a288cd6af6d0f49b476c874a506100303a128b6d3b654c3d74fa4ff2ffed68a48a27e8630cda5c918f2977dcf4 languageName: node linkType: hard -"find-cache-dir@npm:^2.1.0": +"finalhandler@npm:^2.1.0": version: 2.1.0 - resolution: "find-cache-dir@npm:2.1.0" + resolution: "finalhandler@npm:2.1.0" dependencies: - commondir: ^1.0.1 - make-dir: ^2.0.0 - pkg-dir: ^3.0.0 - checksum: 60ad475a6da9f257df4e81900f78986ab367d4f65d33cf802c5b91e969c28a8762f098693d7a571b6e4dd4c15166c2da32ae2d18b6766a18e2071079448fdce4 + debug: ^4.4.0 + encodeurl: ^2.0.0 + escape-html: ^1.0.3 + on-finished: ^2.4.1 + parseurl: ^1.3.3 + statuses: ^2.0.1 + checksum: 27ca9cc83b1384ba37959eb95bc7e62bc0bf4d6f6af63f6d38821cf7499b113e34b23f96a2a031616817f73986f94deea67c2f558de9daf406790c181a2501df languageName: node linkType: hard @@ -9760,7 +11585,16 @@ __metadata: languageName: node linkType: hard -"find-up@npm:4.1.0, find-up@npm:^4.0.0, find-up@npm:^4.1.0": +"find-up@npm:^3.0.0": + version: 3.0.0 + resolution: "find-up@npm:3.0.0" + dependencies: + locate-path: ^3.0.0 + checksum: 38eba3fe7a66e4bc7f0f5a1366dc25508b7cfc349f852640e3678d26ad9a6d7e2c43eff0a472287de4a9753ef58f066a0ea892a256fa3636ad51b3fe1e17fae9 + languageName: node + linkType: hard + +"find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -9770,12 +11604,13 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^3.0.0": - version: 3.0.0 - resolution: "find-up@npm:3.0.0" +"find-up@npm:^5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" dependencies: - locate-path: ^3.0.0 - checksum: 38eba3fe7a66e4bc7f0f5a1366dc25508b7cfc349f852640e3678d26ad9a6d7e2c43eff0a472287de4a9753ef58f066a0ea892a256fa3636ad51b3fe1e17fae9 + locate-path: ^6.0.0 + path-exists: ^4.0.0 + checksum: 07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 languageName: node linkType: hard @@ -9787,21 +11622,24 @@ __metadata: "@babel/plugin-transform-object-assign": ^7.18.6 "@babel/preset-react": ^7.18.6 "@babel/preset-typescript": ^7.18.6 - "@testing-library/jest-dom": ^5.16.4 - "@types/jest": ^28.1.6 - "@types/node": 18.17.1 - "@types/nodemailer": ^6.4.7 - "@types/react-query": ^1.2.9 - "@typescript-eslint/eslint-plugin": ^4.18.0 - "@typescript-eslint/parser": ^4.18.0 - concurrently: ^5.2.0 + "@types/jest": ^29.5.14 + "@types/multer": ^1.4.12 + "@types/node": 20.0.0 + "@typescript-eslint/eslint-plugin": 8.20.0 + "@typescript-eslint/parser": 8.20.0 + concurrently: ^9.1.0 eslint: ^7.0.0 - eslint-config-prettier: ^8.5.0 - eslint-plugin-prettier: ^4.2.1 - prettier: ^2.0.5 - rimraf: ^3.0.2 + eslint-config-prettier: ^10.0.1 + eslint-config-react-app: ^7.0.1 + eslint-plugin-cypress: 4.3.0 + eslint-plugin-prettier: ^5.2.2 + mitt: ^3.0.1 + prettier: ^3.4.2 + react-hook-form-persist: ^3.0.0 + recharts: ^2.15.3 + rimraf: ^6.0.1 ts-node: ^10.9.1 - typescript: ^4.1.5 + typescript: ^5.7.3 languageName: unknown linkType: soft @@ -9817,122 +11655,107 @@ __metadata: linkType: hard "flatted@npm:^3.2.9": - version: 3.3.1 - resolution: "flatted@npm:3.3.1" - checksum: 85ae7181650bb728c221e7644cbc9f4bf28bc556f2fc89bb21266962bdf0ce1029cc7acc44bb646cd469d9baac7c317f64e841c4c4c00516afa97320cdac7f94 - languageName: node - linkType: hard - -"flatten@npm:^1.0.2": - version: 1.0.3 - resolution: "flatten@npm:1.0.3" - checksum: 5c57379816f1692aaa79fbc6390e0a0644e5e8442c5783ed57c6d315468eddbc53a659eaa03c9bb1e771b0f4a9bd8dd8a2620286bf21fd6538a7857321fdfb20 - languageName: node - linkType: hard - -"flush-write-stream@npm:^1.0.0": - version: 1.1.1 - resolution: "flush-write-stream@npm:1.1.1" - dependencies: - inherits: ^2.0.3 - readable-stream: ^2.3.6 - checksum: 42e07747f83bcd4e799da802e621d6039787749ffd41f5517f8c4f786ee967e31ba32b09f8b28a9c6f67bd4f5346772e604202df350e8d99f4141771bae31279 + version: 3.3.3 + resolution: "flatted@npm:3.3.3" + checksum: 8c96c02fbeadcf4e8ffd0fa24983241e27698b0781295622591fc13585e2f226609d95e422bcf2ef044146ffacb6b68b1f20871454eddf75ab3caa6ee5f4a1fe languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.9, follow-redirects@npm:^1.15.6": - version: 1.15.6 - resolution: "follow-redirects@npm:1.15.6" +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.6": + version: 1.15.11 + resolution: "follow-redirects@npm:1.15.11" peerDependenciesMeta: debug: optional: true - checksum: a62c378dfc8c00f60b9c80cab158ba54e99ba0239a5dd7c81245e5a5b39d10f0c35e249c3379eae719ff0285fff88c365dd446fab19dee771f1d76252df1bbf5 + checksum: 20bf55e9504f59e6cc3743ba27edb2ebf41edea1baab34799408f2c050f73f0c612728db21c691276296d2795ea8a812dc532a98e8793619fcab91abe06d017f languageName: node linkType: hard -"for-each@npm:^0.3.3": - version: 0.3.3 - resolution: "for-each@npm:0.3.3" +"for-each@npm:^0.3.3, for-each@npm:^0.3.5": + version: 0.3.5 + resolution: "for-each@npm:0.3.5" dependencies: - is-callable: ^1.1.3 - checksum: 6c48ff2bc63362319c65e2edca4a8e1e3483a2fabc72fbe7feaf8c73db94fc7861bd53bc02c8a66a0c1dd709da6b04eec42e0abdd6b40ce47305ae92a25e5d28 - languageName: node - linkType: hard - -"for-in@npm:^1.0.2": - version: 1.0.2 - resolution: "for-in@npm:1.0.2" - checksum: 09f4ae93ce785d253ac963d94c7f3432d89398bf25ac7a24ed034ca393bf74380bdeccc40e0f2d721a895e54211b07c8fad7132e8157827f6f7f059b70b4043d + is-callable: ^1.2.7 + checksum: 3c986d7e11f4381237cc98baa0a2f87eabe74719eee65ed7bed275163082b940ede19268c61d04c6260e0215983b12f8d885e3c8f9aa8c2113bf07c37051745c languageName: node linkType: hard -"foreground-child@npm:^3.1.0": - version: 3.1.1 - resolution: "foreground-child@npm:3.1.1" +"foreground-child@npm:^3.1.0, foreground-child@npm:^3.3.1": + version: 3.3.1 + resolution: "foreground-child@npm:3.3.1" dependencies: - cross-spawn: ^7.0.0 + cross-spawn: ^7.0.6 signal-exit: ^4.0.1 - checksum: 139d270bc82dc9e6f8bc045fe2aae4001dc2472157044fdfad376d0a3457f77857fa883c1c8b21b491c6caade9a926a4bed3d3d2e8d3c9202b151a4cbbd0bcd5 + checksum: b2c1a6fc0bf0233d645d9fefdfa999abf37db1b33e5dab172b3cbfb0662b88bfbd2c9e7ab853533d199050ec6b65c03fcf078fc212d26e4990220e98c6930eef languageName: node linkType: hard -"fork-ts-checker-webpack-plugin@npm:4.1.6": - version: 4.1.6 - resolution: "fork-ts-checker-webpack-plugin@npm:4.1.6" +"fork-ts-checker-webpack-plugin@npm:^6.5.0": + version: 6.5.3 + resolution: "fork-ts-checker-webpack-plugin@npm:6.5.3" dependencies: - "@babel/code-frame": ^7.5.5 - chalk: ^2.4.1 - micromatch: ^3.1.10 + "@babel/code-frame": ^7.8.3 + "@types/json-schema": ^7.0.5 + chalk: ^4.1.0 + chokidar: ^3.4.2 + cosmiconfig: ^6.0.0 + deepmerge: ^4.2.2 + fs-extra: ^9.0.0 + glob: ^7.1.6 + memfs: ^3.1.2 minimatch: ^3.0.4 - semver: ^5.6.0 - tapable: ^1.0.0 - worker-rpc: ^0.1.0 - checksum: 4cc4fa7919dd9a0d765514d064c86e3a6f9cea8e700996b3e775cfcc0280f606a2dd16203d9b7e294b64e900795b0d80eb41fc8c192857d3350e407f14ef3eed - languageName: node - linkType: hard - -"form-data@npm:^2.5.0": - version: 2.5.1 - resolution: "form-data@npm:2.5.1" - dependencies: - asynckit: ^0.4.0 - combined-stream: ^1.0.6 - mime-types: ^2.1.12 - checksum: 5134ada56cc246b293a1ac7678dba6830000603a3979cf83ff7b2f21f2e3725202237cfb89e32bcb38a1d35727efbd3c3a22e65b42321e8ade8eec01ce755d08 + schema-utils: 2.7.0 + semver: ^7.3.2 + tapable: ^1.0.0 + peerDependencies: + eslint: ">= 6" + typescript: ">= 2.7" + vue-template-compiler: "*" + webpack: ">= 4" + peerDependenciesMeta: + eslint: + optional: true + vue-template-compiler: + optional: true + checksum: 9732a49bfeed8fc23e6e8a59795fa7c238edeba91040a9b520db54b4d316dda27f9f1893d360e296fd0ad8930627d364417d28a8c7007fba60cc730ebfce4956 languageName: node linkType: hard "form-data@npm:^3.0.0": - version: 3.0.1 - resolution: "form-data@npm:3.0.1" + version: 3.0.4 + resolution: "form-data@npm:3.0.4" dependencies: asynckit: ^0.4.0 combined-stream: ^1.0.8 - mime-types: ^2.1.12 - checksum: b019e8d35c8afc14a2bd8a7a92fa4f525a4726b6d5a9740e8d2623c30e308fbb58dc8469f90415a856698933c8479b01646a9dff33c87cc4e76d72aedbbf860d + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 + mime-types: ^2.1.35 + checksum: 989005f575b9a14a30144df1745ef60c64cf901e648ae198bf63e5caeaf8dacf595a85dfd56f90a845eceb14fe1bea58b3845e8171337a4cf72781fa19867efc languageName: node linkType: hard -"form-data@npm:^4.0.0": - version: 4.0.0 - resolution: "form-data@npm:4.0.0" +"form-data@npm:^4.0.0, form-data@npm:^4.0.4": + version: 4.0.4 + resolution: "form-data@npm:4.0.4" dependencies: asynckit: ^0.4.0 combined-stream: ^1.0.8 + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 mime-types: ^2.1.12 - checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c + checksum: 9b7788836df9fa5a6999e0c02515b001946b2a868cfe53f026c69e2c537a2ff9fbfb8e9d2b678744628f3dc7a2d6e14e4e45dfaf68aa6239727f0bdb8ce0abf2 languageName: node linkType: hard "formidable@npm:^2.1.2": - version: 2.1.2 - resolution: "formidable@npm:2.1.2" + version: 2.1.5 + resolution: "formidable@npm:2.1.5" dependencies: + "@paralleldrive/cuid2": ^2.2.2 dezalgo: ^1.0.4 - hexoid: ^1.0.0 once: ^1.4.0 qs: ^6.11.0 - checksum: 81c8e5d89f5eb873e992893468f0de22c01678ca3d315db62be0560f9de1c77d4faefc9b1f4575098eb2263b3c81ba1024833a9fc3206297ddbac88a4f69b7a8 + checksum: b7a38dbf3f2d32858e9199f9e1597038d22854dc7f3120e30a05097fd538c3a5ebdfcb1b14ed3d68139f592176e64a3544aa14b5be624e26fe5b383a5c096a74 languageName: node linkType: hard @@ -9943,12 +11766,10 @@ __metadata: languageName: node linkType: hard -"fragment-cache@npm:^0.2.1": - version: 0.2.1 - resolution: "fragment-cache@npm:0.2.1" - dependencies: - map-cache: ^0.2.2 - checksum: 1cbbd0b0116b67d5790175de0038a11df23c1cd2e8dcdbade58ebba5594c2d641dade6b4f126d82a7b4a6ffc2ea12e3d387dbb64ea2ae97cf02847d436f60fdc +"fraction.js@npm:^4.3.7": + version: 4.3.7 + resolution: "fraction.js@npm:4.3.7" + checksum: e1553ae3f08e3ba0e8c06e43a3ab20b319966dfb7ddb96fd9b5d0ee11a66571af7f993229c88ebbb0d4a816eb813a24ed48207b140d442a8f76f33763b8d1f3f languageName: node linkType: hard @@ -9959,13 +11780,10 @@ __metadata: languageName: node linkType: hard -"from2@npm:^2.1.0": - version: 2.3.0 - resolution: "from2@npm:2.3.0" - dependencies: - inherits: ^2.0.1 - readable-stream: ^2.0.0 - checksum: 6080eba0793dce32f475141fb3d54cc15f84ee52e420ee22ac3ab0ad639dc95a1875bc6eb9c0e1140e94972a36a89dc5542491b85f1ab8df0c126241e0f1a61b +"fresh@npm:^2.0.0": + version: 2.0.0 + resolution: "fresh@npm:2.0.0" + checksum: 38b9828352c6271e2a0dd8bdd985d0100dbbc4eb8b6a03286071dd6f7d96cfaacd06d7735701ad9a95870eb3f4555e67c08db1dcfe24c2e7bb87383c72fae1d2 languageName: node linkType: hard @@ -9975,80 +11793,88 @@ __metadata: dependencies: "@emotion/react": ^11.10.4 "@emotion/styled": ^11.10.4 - "@hookform/resolvers": ^2.9.7 - "@mui/icons-material": ^5.10.3 - "@mui/material": ^5.10.3 - "@mui/system": ^5.10.16 + "@hello-pangea/dnd": ^17.0.0 + "@hookform/resolvers": ^3.10.0 + "@mui/icons-material": ^6.4.0 + "@mui/lab": 6.0.0-beta.10 + "@mui/material": ^6.4.0 + "@mui/system": ^6.4.0 "@mui/x-data-grid": ^5.16.0 - "@mui/x-date-pickers": ^6.19.4 - "@testing-library/dom": ^8.19.0 - "@testing-library/jest-dom": ^5.11.9 - "@testing-library/react": ^11.2.5 + "@mui/x-date-pickers": ^7.24.0 + "@react-oauth/google": ^0.12.1 + "@testing-library/dom": ^10.4.0 + "@testing-library/jest-dom": ^6.6.3 + "@testing-library/react": ^16.2.0 "@testing-library/react-hooks": ^8.0.1 - "@testing-library/user-event": ^12.6.3 + "@testing-library/user-event": ^14.6.0 "@types/file-saver": ^2.0.5 - "@types/node": 18.17.1 - "@types/react": ^18.2.15 - "@types/react-dom": ^18.2.7 + "@types/node": 20.0.0 + "@types/react": ^19.0.7 + "@types/react-dom": ^19.0.3 "@types/react-helmet": ^6.1.6 "@types/react-query": ^1.2.9 "@types/react-router-dom": ^5.1.7 + "@types/uuid": ^10.0.0 "@vitejs/plugin-react": ^4.0.0 - axios: ^0.27.2 - bootstrap: ^4.6.0 + axios: ^1.7.9 + bootstrap: ^5.3.0 + chart.js: 4.4.6 + chartjs-plugin-datalabels: ^2.2.0 classnames: ^2.3.1 - customize-cra: ^0.9.1 + customize-cra: ^1.0.0 + date-fns: ^4.1.0 dayjs: ^1.11.10 file-saver: ^2.0.5 - google-auth-library: ^8.1.1 + google-auth-library: ^9.15.0 jest-fail-on-console: ^3.0.2 - msw: ^0.44.2 + msw: ^2.7.0 pdf-lib: ^1.17.1 - react: ^18.2.0 - react-dom: ^18.2.0 - react-google-charts: ^4.0.0 - react-google-login: ^5.2.2 + react: 19.0.0 + react-archer: ^4.4.0 + react-chartjs-2: 5.2.0 + react-dom: 19.0.0 + react-draggable: ^4.4.6 + react-google-charts: ^5.2.1 react-helmet: ^6.1.0 react-hook-form: ^7.34.0 - react-markdown: ^6.0.0 + react-hook-form-persist: ^3.0.0 + react-markdown: ^9.0.3 + react-pdf: ^9.2.1 react-query: 3.17.0 react-router-dom: ^5.2.0 - react-scripts: ^4.0.1 + react-scripts: ^5.0.1 react-use-measure: ^2.1.1 sass: ^1.54.0 shared: 1.0.0 - typed-scss-modules: ^6.5.0 - typescript: ^4.1.5 - vite: ^4.4.5 - vitest: ^0.32.1 - web-vitals: ^0.2.4 - yup: ^0.32.11 + typed-scss-modules: ^8.1.1 + typescript: 5.7.3 + uuid: ^11.1.0 + vite: 6.0.7 + vitest: ^2.1.8 + web-vitals: ^4.2.4 + yup: ^1.6.1 languageName: unknown linkType: soft -"fs-extra@npm:^7.0.0": - version: 7.0.1 - resolution: "fs-extra@npm:7.0.1" - dependencies: - graceful-fs: ^4.1.2 - jsonfile: ^4.0.0 - universalify: ^0.1.0 - checksum: 141b9dccb23b66a66cefdd81f4cda959ff89282b1d721b98cea19ba08db3dcbe6f862f28841f3cf24bb299e0b7e6c42303908f65093cb7e201708e86ea5a8dcf +"fs-constants@npm:^1.0.0": + version: 1.0.0 + resolution: "fs-constants@npm:1.0.0" + checksum: 18f5b718371816155849475ac36c7d0b24d39a11d91348cfcb308b4494824413e03572c403c86d3a260e049465518c4f0d5bd00f0371cdfcad6d4f30a85b350d languageName: node linkType: hard -"fs-extra@npm:^8.1.0": - version: 8.1.0 - resolution: "fs-extra@npm:8.1.0" +"fs-extra@npm:^10.0.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" dependencies: graceful-fs: ^4.2.0 - jsonfile: ^4.0.0 - universalify: ^0.1.0 - checksum: bf44f0e6cea59d5ce071bba4c43ca76d216f89e402dc6285c128abc0902e9b8525135aa808adad72c9d5d218e9f4bcc63962815529ff2f684ad532172a284880 + jsonfile: ^6.0.1 + universalify: ^2.0.0 + checksum: dc94ab37096f813cc3ca12f0f1b5ad6744dfed9ed21e953d72530d103cea193c2f81584a39e9dee1bea36de5ee66805678c0dddc048e8af1427ac19c00fffc50 languageName: node linkType: hard -"fs-extra@npm:^9.0.1": +"fs-extra@npm:^9.0.0, fs-extra@npm:^9.0.1": version: 9.1.0 resolution: "fs-extra@npm:9.1.0" dependencies: @@ -10060,15 +11886,6 @@ __metadata: languageName: node linkType: hard -"fs-minipass@npm:^2.0.0": - version: 2.1.0 - resolution: "fs-minipass@npm:2.1.0" - dependencies: - minipass: ^3.0.0 - checksum: 1b8d128dae2ac6cc94230cc5ead341ba3e0efaef82dab46a33d171c044caaa6ca001364178d42069b2809c35a1c3c35079a32107c770e9ffab3901b59af8c8b1 - languageName: node - linkType: hard - "fs-minipass@npm:^3.0.0": version: 3.0.3 resolution: "fs-minipass@npm:3.0.3" @@ -10078,15 +11895,10 @@ __metadata: languageName: node linkType: hard -"fs-write-stream-atomic@npm:^1.0.8": - version: 1.0.10 - resolution: "fs-write-stream-atomic@npm:1.0.10" - dependencies: - graceful-fs: ^4.1.2 - iferr: ^0.1.5 - imurmurhash: ^0.1.4 - readable-stream: 1 || 2 - checksum: 43c2d6817b72127793abc811ebf87a135b03ac7cbe41cdea9eeacf59b23e6e29b595739b083e9461303d525687499a1aaefcec3e5ff9bc82b170edd3dc467ccc +"fs-monkey@npm:^1.0.4": + version: 1.1.0 + resolution: "fs-monkey@npm:1.1.0" + checksum: ebb6305a37ca4731ffe9aceae21be40992fe5384f7a25819a1d64d17c649e7eeac3fc9ad6269cad6fffc409df0f4583253c93a930549fd82d5f8aed46beb5b9b languageName: node linkType: hard @@ -10097,18 +11909,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^1.2.7": - version: 1.2.13 - resolution: "fsevents@npm:1.2.13" - dependencies: - bindings: ^1.5.0 - nan: ^2.12.1 - checksum: ae855aa737aaa2f9167e9f70417cf6e45a5cd11918e1fee9923709a0149be52416d765433b4aeff56c789b1152e718cd1b13ddec6043b78cdda68260d86383c1 - conditions: os=darwin - languageName: node - linkType: hard - -"fsevents@npm:^2.1.2, fsevents@npm:^2.1.3, fsevents@npm:~2.3.2": +"fsevents@npm:2.3.3, fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -10118,17 +11919,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@^1.2.7#~builtin": - version: 1.2.13 - resolution: "fsevents@patch:fsevents@npm%3A1.2.13#~builtin::version=1.2.13&hash=18f3a7" - dependencies: - bindings: ^1.5.0 - nan: ^2.12.1 - conditions: os=darwin - languageName: node - linkType: hard - -"fsevents@patch:fsevents@^2.1.2#~builtin, fsevents@patch:fsevents@^2.1.3#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": +"fsevents@patch:fsevents@2.3.3#~builtin, fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin, fsevents@patch:fsevents@~2.3.3#~builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=18f3a7" dependencies: @@ -10144,15 +11935,17 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.5, function.prototype.name@npm:^1.1.6": - version: 1.1.6 - resolution: "function.prototype.name@npm:1.1.6" +"function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8": + version: 1.1.8 + resolution: "function.prototype.name@npm:1.1.8" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 functions-have-names: ^1.2.3 - checksum: 7a3f9bd98adab09a07f6e1f03da03d3f7c26abbdeaeee15223f6c04a9fb5674792bdf5e689dac19b97ac71de6aad2027ba3048a9b883aa1b3173eed6ab07f479 + hasown: ^2.0.2 + is-callable: ^1.2.7 + checksum: 3a366535dc08b25f40a322efefa83b2da3cd0f6da41db7775f2339679120ef63b6c7e967266182609e655b8f0a8f65596ed21c7fd72ad8bd5621c2340edd4010 languageName: node linkType: hard @@ -10182,6 +11975,19 @@ __metadata: languageName: node linkType: hard +"gaxios@npm:^6.0.0, gaxios@npm:^6.1.1": + version: 6.7.1 + resolution: "gaxios@npm:6.7.1" + dependencies: + extend: ^3.0.2 + https-proxy-agent: ^7.0.1 + is-stream: ^2.0.0 + node-fetch: ^2.6.9 + uuid: ^9.0.1 + checksum: ed5952655339918e0868c6f4e079d6e9e55b20a242ddb1be25076cdfb0dd1ca5a2cb233da7352baa972c19f898a78fa6ba67e7d848717c9ca9877c269b5b02f7 + languageName: node + linkType: hard + "gcp-metadata@npm:^5.3.0": version: 5.3.0 resolution: "gcp-metadata@npm:5.3.0" @@ -10192,7 +11998,27 @@ __metadata: languageName: node linkType: hard -"gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2": +"gcp-metadata@npm:^6.1.0": + version: 6.1.1 + resolution: "gcp-metadata@npm:6.1.1" + dependencies: + gaxios: ^6.1.1 + google-logging-utils: ^0.0.2 + json-bigint: ^1.0.0 + checksum: 7dffe884fd718482b559a841da469dc30e766a4b86c71cda96bed42579763d58f28328238b2eb424c29ba10ef45d4bb8a6586441921734f01012b55bbea79711 + languageName: node + linkType: hard + +"generic-names@npm:^4.0.0": + version: 4.0.0 + resolution: "generic-names@npm:4.0.0" + dependencies: + loader-utils: ^3.2.0 + checksum: 8dabd2505164191501b75f2861b5e1194458a344ae2a7c9776bdd72d1f50b248dff737bcdf118fff677275edb3632f2d10662e6ac122dd7b245c5baa8d303270 + languageName: node + linkType: hard + +"gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" checksum: a7437e58c6be12aa6c90f7730eac7fa9833dc78872b4ad2963d2031b00a3367a93f98aec75f9aaac7220848e4026d67a8655e870b24f20a543d103c0d65952ec @@ -10206,23 +12032,21 @@ __metadata: languageName: node linkType: hard -"get-func-name@npm:^2.0.1, get-func-name@npm:^2.0.2": - version: 2.0.2 - resolution: "get-func-name@npm:2.0.2" - checksum: 3f62f4c23647de9d46e6f76d2b3eafe58933a9b3830c60669e4180d6c601ce1b4aa310ba8366143f55e52b139f992087a9f0647274e8745621fa2af7e0acf13b - languageName: node - linkType: hard - -"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": - version: 1.2.4 - resolution: "get-intrinsic@npm:1.2.4" +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0": + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" dependencies: + call-bind-apply-helpers: ^1.0.2 + es-define-property: ^1.0.1 es-errors: ^1.3.0 + es-object-atoms: ^1.1.1 function-bind: ^1.1.2 - has-proto: ^1.0.1 - has-symbols: ^1.0.3 - hasown: ^2.0.0 - checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951 + get-proto: ^1.0.1 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + math-intrinsics: ^1.1.0 + checksum: 301008e4482bb9a9cb49e132b88fee093bff373b4e6def8ba219b1e96b60158a6084f273ef5cafe832e42cd93462f4accb46a618d35fe59a2b507f2388c5b79d languageName: node linkType: hard @@ -10240,49 +12064,38 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^4.0.0": - version: 4.1.0 - resolution: "get-stream@npm:4.1.0" +"get-proto@npm:^1.0.0, get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" dependencies: - pump: ^3.0.0 - checksum: 443e1914170c15bd52ff8ea6eff6dfc6d712b031303e36302d2778e3de2506af9ee964d6124010f7818736dcfde05c04ba7ca6cc26883106e084357a17ae7d73 + dunder-proto: ^1.0.1 + es-object-atoms: ^1.0.0 + checksum: 4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b languageName: node linkType: hard -"get-stream@npm:^5.0.0": - version: 5.2.0 - resolution: "get-stream@npm:5.2.0" - dependencies: - pump: ^3.0.0 - checksum: 8bc1a23174a06b2b4ce600df38d6c98d2ef6d84e020c1ddad632ad75bac4e092eeb40e4c09e0761c35fc2dbc5e7fff5dab5e763a383582c4a167dd69a905bd12 +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: e04ecece32c92eebf5b8c940f51468cd53554dcbb0ea725b2748be583c9523d00128137966afce410b9b051eb2ef16d657cd2b120ca8edafcf5a65e81af63cad languageName: node linkType: hard -"get-symbol-description@npm:^1.0.2": - version: 1.0.2 - resolution: "get-symbol-description@npm:1.0.2" +"get-symbol-description@npm:^1.1.0": + version: 1.1.0 + resolution: "get-symbol-description@npm:1.1.0" dependencies: - call-bind: ^1.0.5 + call-bound: ^1.0.3 es-errors: ^1.3.0 - get-intrinsic: ^1.2.4 - checksum: e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973 - languageName: node - linkType: hard - -"get-value@npm:^2.0.3, get-value@npm:^2.0.6": - version: 2.0.6 - resolution: "get-value@npm:2.0.6" - checksum: 5c3b99cb5398ea8016bf46ff17afc5d1d286874d2ad38ca5edb6e87d75c0965b0094cb9a9dddef2c59c23d250702323539a7fbdd870620db38c7e7d7ec87c1eb + get-intrinsic: ^1.2.6 + checksum: 655ed04db48ee65ef2ddbe096540d4405e79ba0a7f54225775fef43a7e2afcb93a77d141c5f05fdef0afce2eb93bcbfb3597142189d562ac167ff183582683cd languageName: node linkType: hard -"glob-parent@npm:^3.1.0": - version: 3.1.0 - resolution: "glob-parent@npm:3.1.0" - dependencies: - is-glob: ^3.1.0 - path-dirname: ^1.0.0 - checksum: 653d559237e89a11b9934bef3f392ec42335602034c928590544d383ff5ef449f7b12f3cfa539708e74bc0a6c28ab1fe51d663cc07463cdf899ba92afd85a855 +"github-from-package@npm:0.0.0": + version: 0.0.0 + resolution: "github-from-package@npm:0.0.0" + checksum: 14e448192a35c1e42efee94c9d01a10f42fe790375891a24b25261246ce9336ab9df5d274585aedd4568f7922246c2a78b8a8cd2571bfe99c693a9718e7dd0e3 languageName: node linkType: hard @@ -10295,22 +12108,55 @@ __metadata: languageName: node linkType: hard +"glob-parent@npm:^6.0.2": + version: 6.0.2 + resolution: "glob-parent@npm:6.0.2" + dependencies: + is-glob: ^4.0.3 + checksum: c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8 + languageName: node + linkType: hard + +"glob-to-regexp@npm:^0.4.1": + version: 0.4.1 + resolution: "glob-to-regexp@npm:0.4.1" + checksum: e795f4e8f06d2a15e86f76e4d92751cf8bbfcf0157cea5c2f0f35678a8195a750b34096b1256e436f0cebc1883b5ff0888c47348443e69546a5a87f9e1eb1167 + languageName: node + linkType: hard + "glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.3.12 - resolution: "glob@npm:10.3.12" + version: 10.4.5 + resolution: "glob@npm:10.4.5" dependencies: foreground-child: ^3.1.0 - jackspeak: ^2.3.6 - minimatch: ^9.0.1 - minipass: ^7.0.4 - path-scurry: ^1.10.2 + 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 + checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a + languageName: node + linkType: hard + +"glob@npm:^11.0.0": + version: 11.0.3 + resolution: "glob@npm:11.0.3" + dependencies: + foreground-child: ^3.3.1 + jackspeak: ^4.1.1 + minimatch: ^10.0.3 + minipass: ^7.1.2 + package-json-from-dist: ^1.0.0 + path-scurry: ^2.0.0 bin: glob: dist/esm/bin.mjs - checksum: 2b0949d6363021aaa561b108ac317bf5a97271b8a5d7a5fac1a176e40e8068ecdcccc992f8a7e958593d501103ac06d673de92adc1efcbdab45edefe35f8d7c6 + checksum: 65ddc1e3c969e87999880580048763cc8b5bdd375930dd43b8100a5ba481d2e2563e4553de42875790800c602522a98aa8d3ed1c5bd4d27621609e6471eb371d languageName: node linkType: hard -"glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0": +"glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.2.0": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -10324,7 +12170,7 @@ __metadata: languageName: node linkType: hard -"global-modules@npm:2.0.0": +"global-modules@npm:^2.0.0": version: 2.0.0 resolution: "global-modules@npm:2.0.0" dependencies: @@ -10344,14 +12190,7 @@ __metadata: languageName: node linkType: hard -"globals@npm:^11.1.0": - version: 11.12.0 - resolution: "globals@npm:11.12.0" - checksum: 67051a45eca3db904aee189dfc7cd53c20c7d881679c93f6146ddd4c9f4ab2268e68a919df740d39c71f4445d2b38ee360fc234428baea1dbdfe68bbcb46979e - languageName: node - linkType: hard - -"globals@npm:^13.6.0, globals@npm:^13.9.0": +"globals@npm:^13.19.0, globals@npm:^13.6.0, globals@npm:^13.9.0": version: 13.24.0 resolution: "globals@npm:13.24.0" dependencies: @@ -10360,30 +12199,24 @@ __metadata: languageName: node linkType: hard -"globalthis@npm:^1.0.3": - version: 1.0.3 - resolution: "globalthis@npm:1.0.3" - dependencies: - define-properties: ^1.1.3 - checksum: fbd7d760dc464c886d0196166d92e5ffb4c84d0730846d6621a39fbbc068aeeb9c8d1421ad330e94b7bca4bb4ea092f5f21f3d36077812af5d098b4dc006c998 +"globals@npm:^15.15.0": + version: 15.15.0 + resolution: "globals@npm:15.15.0" + checksum: a2a92199a112db00562a2f85eeef2a7e3943e171f7f7d9b17dfa9231e35fd612588f3c199d1509ab1757273467e413b08c80424cf6e399e96acdaf93deb3ee88 languageName: node linkType: hard -"globby@npm:11.0.1": - version: 11.0.1 - resolution: "globby@npm:11.0.1" +"globalthis@npm:^1.0.4": + version: 1.0.4 + resolution: "globalthis@npm:1.0.4" dependencies: - array-union: ^2.1.0 - dir-glob: ^3.0.1 - fast-glob: ^3.1.1 - ignore: ^5.1.4 - merge2: ^1.3.0 - slash: ^3.0.0 - checksum: b0b26e580666ef8caf0b0facd585c1da46eb971207ee9f8c7b690c1372d77602dd072f047f26c3ae1c293807fdf8fb6890d9291d37bc6d2602b1f07386f983e5 + define-properties: ^1.2.1 + gopd: ^1.0.1 + checksum: 39ad667ad9f01476474633a1834a70842041f70a55571e8dcef5fb957980a92da5022db5430fca8aecc5d47704ae30618c0bc877a579c70710c904e9ef06108a languageName: node linkType: hard -"globby@npm:^11.0.3": +"globby@npm:^11.0.4, globby@npm:^11.1.0": version: 11.1.0 resolution: "globby@npm:11.1.0" dependencies: @@ -10397,19 +12230,6 @@ __metadata: languageName: node linkType: hard -"globby@npm:^6.1.0": - version: 6.1.0 - resolution: "globby@npm:6.1.0" - dependencies: - array-union: ^1.0.1 - glob: ^7.0.3 - object-assign: ^4.0.1 - pify: ^2.0.0 - pinkie-promise: ^2.0.0 - checksum: 18109d6b9d55643d2b98b59c3cfae7073ccfe39829632f353d516cc124d836c2ddebe48a23f04af63d66a621b6d86dd4cbd7e6af906f2458a7fe510ffc4bd424 - languageName: node - linkType: hard - "google-auth-library@npm:^8.0.2, google-auth-library@npm:^8.1.1": version: 8.9.0 resolution: "google-auth-library@npm:8.9.0" @@ -10427,6 +12247,27 @@ __metadata: languageName: node linkType: hard +"google-auth-library@npm:^9.15.0": + version: 9.15.1 + resolution: "google-auth-library@npm:9.15.1" + dependencies: + base64-js: ^1.3.0 + ecdsa-sig-formatter: ^1.0.11 + gaxios: ^6.1.1 + gcp-metadata: ^6.1.0 + gtoken: ^7.0.0 + jws: ^4.0.0 + checksum: 1c7660b7d21504a58b6b7780b0ca56f07a4d2b68d2ca14e5c4beaedd45cc4898baa8df1cfaf4dac15413a8db3cecc00e84662d8a327f9b9488ff2df7d8d23c84 + languageName: node + linkType: hard + +"google-logging-utils@npm:^0.0.2": + version: 0.0.2 + resolution: "google-logging-utils@npm:0.0.2" + checksum: 270de74cde8abe0a6639b4bebbb6db2c7d8a495cf14b23779450d3d010e759f3ffcb7eb200b1bcb05da1897fa63f3e336df2274f02fc69d3bb388019fa2b3134 + languageName: node + linkType: hard + "google-p12-pem@npm:^4.0.0": version: 4.0.1 resolution: "google-p12-pem@npm:4.0.1" @@ -10462,33 +12303,31 @@ __metadata: languageName: node linkType: hard -"gopd@npm:^1.0.1": - version: 1.0.1 - resolution: "gopd@npm:1.0.1" - dependencies: - get-intrinsic: ^1.1.3 - checksum: a5ccfb8806e0917a94e0b3de2af2ea4979c1da920bc381667c260e00e7cafdbe844e2cb9c5bcfef4e5412e8bf73bab837285bc35c7ba73aaaf0134d4583393a6 +"gopd@npm:^1.0.1, gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: cc6d8e655e360955bdccaca51a12a474268f95bb793fc3e1f2bdadb075f28bfd1fd988dab872daf77a61d78cbaf13744bc8727a17cfb1d150d76047d805375f3 languageName: node linkType: hard -"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 languageName: node linkType: hard -"graphql@npm:^16.3.0": - version: 16.8.1 - resolution: "graphql@npm:16.8.1" - checksum: 8d304b7b6f708c8c5cc164b06e92467dfe36aff6d4f2cf31dd19c4c2905a0e7b89edac4b7e225871131fd24e21460836b369de0c06532644d15b461d55b1ccc0 +"graphemer@npm:^1.4.0": + version: 1.4.0 + resolution: "graphemer@npm:1.4.0" + checksum: bab8f0be9b568857c7bec9fda95a89f87b783546d02951c40c33f84d05bb7da3fd10f863a9beb901463669b6583173a8c8cc6d6b306ea2b9b9d5d3d943c3a673 languageName: node linkType: hard -"growly@npm:^1.3.0": - version: 1.3.0 - resolution: "growly@npm:1.3.0" - checksum: 53cdecd4c16d7d9154a9061a9ccb87d602e957502ca69b529d7d1b2436c2c0b700ec544fc6b3e4cd115d59b81e62e44ce86bd0521403b579d3a2a97d7ce72a44 +"graphql@npm:^16.8.1": + version: 16.11.0 + resolution: "graphql@npm:16.11.0" + checksum: 65bc206edbe980f2759a8e4cf324873f75a66ab48263961472716e50127ae446739be20f926bb7f036a8d199bd4de072f684fd147c285bd6ba965d98cebb6200 languageName: node linkType: hard @@ -10503,13 +12342,22 @@ __metadata: languageName: node linkType: hard -"gzip-size@npm:5.1.1": - version: 5.1.1 - resolution: "gzip-size@npm:5.1.1" +"gtoken@npm:^7.0.0": + version: 7.1.0 + resolution: "gtoken@npm:7.1.0" + dependencies: + gaxios: ^6.0.0 + jws: ^4.0.0 + checksum: 1f338dced78f9d895ea03cd507454eb5a7b77e841ecd1d45e44483b08c1e64d16a9b0342358d37586d87462ffc2d5f5bff5dfe77ed8d4f0aafc3b5b0347d5d16 + languageName: node + linkType: hard + +"gzip-size@npm:^6.0.0": + version: 6.0.0 + resolution: "gzip-size@npm:6.0.0" dependencies: - duplexer: ^0.1.1 - pify: ^4.0.1 - checksum: 6451ba2210877368f6d9ee9b4dc0d14501671472801323bf81fbd38bdeb8525f40a78be45a59d0182895d51e6b60c6314b7d02bd6ed40e7225a01e8d038aac1b + duplexer: ^0.1.2 + checksum: 2df97f359696ad154fc171dcb55bc883fe6e833bca7a65e457b9358f3cb6312405ed70a8da24a77c1baac0639906cd52358dc0ce2ec1a937eaa631b934c94194 languageName: node linkType: hard @@ -10527,26 +12375,10 @@ __metadata: languageName: node linkType: hard -"has-ansi@npm:^2.0.0": - version: 2.0.0 - resolution: "has-ansi@npm:2.0.0" - dependencies: - ansi-regex: ^2.0.0 - checksum: 1b51daa0214440db171ff359d0a2d17bc20061164c57e76234f614c91dbd2a79ddd68dfc8ee73629366f7be45a6df5f2ea9de83f52e1ca24433f2cc78c35d8ec - languageName: node - linkType: hard - -"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": - version: 1.0.2 - resolution: "has-bigints@npm:1.0.2" - checksum: 390e31e7be7e5c6fe68b81babb73dfc35d413604d7ee5f56da101417027a4b4ce6a27e46eff97ad040c835b5d228676eae99a9b5c3bc0e23c8e81a49241ff45b - languageName: node - linkType: hard - -"has-flag@npm:^1.0.0": - version: 1.0.0 - resolution: "has-flag@npm:1.0.0" - checksum: ce3f8ae978e70f16e4bbe17d3f0f6d6c0a3dd3b62a23f97c91d0fda9ed8e305e13baf95cc5bee4463b9f25ac9f5255de113165c5fb285e01b8065b2ac079b301 +"has-bigints@npm:^1.0.2": + version: 1.1.0 + resolution: "has-bigints@npm:1.1.0" + checksum: 79730518ae02c77e4af6a1d1a0b6a2c3e1509785532771f9baf0241e83e36329542c3d7a0e723df8cbc85f74eff4f177828a2265a01ba576adbdc2d40d86538b languageName: node linkType: hard @@ -10573,21 +12405,23 @@ __metadata: languageName: node linkType: hard -"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": - version: 1.0.3 - resolution: "has-proto@npm:1.0.3" - checksum: fe7c3d50b33f50f3933a04413ed1f69441d21d2d2944f81036276d30635cad9279f6b43bc8f32036c31ebdfcf6e731150f46c1907ad90c669ffe9b066c3ba5c4 +"has-proto@npm:^1.2.0": + version: 1.2.0 + resolution: "has-proto@npm:1.2.0" + dependencies: + dunder-proto: ^1.0.0 + checksum: f55010cb94caa56308041d77967c72a02ffd71386b23f9afa8447e58bc92d49d15c19bf75173713468e92fe3fb1680b03b115da39c21c32c74886d1d50d3e7ff languageName: node linkType: hard -"has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": - version: 1.0.3 - resolution: "has-symbols@npm:1.0.3" - checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 +"has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: b2316c7302a0e8ba3aaba215f834e96c22c86f192e7310bdf689dd0e6999510c89b00fbc5742571507cebf25764d68c988b3a0da217369a73596191ac0ce694b languageName: node linkType: hard -"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": +"has-tostringtag@npm:^1.0.2": version: 1.0.2 resolution: "has-tostringtag@npm:1.0.2" dependencies: @@ -10596,84 +12430,7 @@ __metadata: languageName: node linkType: hard -"has-value@npm:^0.3.1": - version: 0.3.1 - resolution: "has-value@npm:0.3.1" - dependencies: - get-value: ^2.0.3 - has-values: ^0.1.4 - isobject: ^2.0.0 - checksum: 29e2a1e6571dad83451b769c7ce032fce6009f65bccace07c2962d3ad4d5530b6743d8f3229e4ecf3ea8e905d23a752c5f7089100c1f3162039fa6dc3976558f - languageName: node - linkType: hard - -"has-value@npm:^1.0.0": - version: 1.0.0 - resolution: "has-value@npm:1.0.0" - dependencies: - get-value: ^2.0.6 - has-values: ^1.0.0 - isobject: ^3.0.0 - checksum: b9421d354e44f03d3272ac39fd49f804f19bc1e4fa3ceef7745df43d6b402053f828445c03226b21d7d934a21ac9cf4bc569396dc312f496ddff873197bbd847 - languageName: node - linkType: hard - -"has-values@npm:^0.1.4": - version: 0.1.4 - resolution: "has-values@npm:0.1.4" - checksum: ab1c4bcaf811ccd1856c11cfe90e62fca9e2b026ebe474233a3d282d8d67e3b59ed85b622c7673bac3db198cb98bd1da2b39300a2f98e453729b115350af49bc - languageName: node - linkType: hard - -"has-values@npm:^1.0.0": - version: 1.0.0 - resolution: "has-values@npm:1.0.0" - dependencies: - is-number: ^3.0.0 - kind-of: ^4.0.0 - checksum: 77e6693f732b5e4cf6c38dfe85fdcefad0fab011af74995c3e83863fabf5e3a836f406d83565816baa0bc0a523c9410db8b990fe977074d61aeb6d8f4fcffa11 - languageName: node - linkType: hard - -"has@npm:^1.0.0": - version: 1.0.4 - resolution: "has@npm:1.0.4" - checksum: 8a11ba062e0627c9578a1d08285401e39f1d071a9692ddf793199070edb5648b21c774dd733e2a181edd635bf6862731885f476f4ccf67c998d7a5ff7cef2550 - languageName: node - linkType: hard - -"hash-base@npm:^3.0.0": - version: 3.1.0 - resolution: "hash-base@npm:3.1.0" - dependencies: - inherits: ^2.0.4 - readable-stream: ^3.6.0 - safe-buffer: ^5.2.0 - checksum: 26b7e97ac3de13cb23fc3145e7e3450b0530274a9562144fc2bf5c1e2983afd0e09ed7cc3b20974ba66039fad316db463da80eb452e7373e780cbee9a0d2f2dc - languageName: node - linkType: hard - -"hash-base@npm:~3.0": - version: 3.0.4 - resolution: "hash-base@npm:3.0.4" - dependencies: - inherits: ^2.0.1 - safe-buffer: ^5.0.1 - checksum: 878465a0dfcc33cce195c2804135352c590d6d10980adc91a9005fd377e77f2011256c2b7cfce472e3f2e92d561d1bf3228d2da06348a9017ce9a258b3b49764 - languageName: node - linkType: hard - -"hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": - version: 1.1.7 - resolution: "hash.js@npm:1.1.7" - dependencies: - inherits: ^2.0.3 - minimalistic-assert: ^1.0.1 - checksum: e350096e659c62422b85fa508e4b3669017311aa4c49b74f19f8e1bc7f3a54a584fdfd45326d4964d6011f2b2d882e38bea775a96046f2a61b7779a979629d8f - languageName: node - linkType: hard - -"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": +"hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -10682,6 +12439,38 @@ __metadata: languageName: node linkType: hard +"hast-util-to-jsx-runtime@npm:^2.0.0": + version: 2.3.6 + resolution: "hast-util-to-jsx-runtime@npm:2.3.6" + dependencies: + "@types/estree": ^1.0.0 + "@types/hast": ^3.0.0 + "@types/unist": ^3.0.0 + comma-separated-tokens: ^2.0.0 + devlop: ^1.0.0 + estree-util-is-identifier-name: ^3.0.0 + hast-util-whitespace: ^3.0.0 + mdast-util-mdx-expression: ^2.0.0 + mdast-util-mdx-jsx: ^3.0.0 + mdast-util-mdxjs-esm: ^2.0.0 + property-information: ^7.0.0 + space-separated-tokens: ^2.0.0 + style-to-js: ^1.0.0 + unist-util-position: ^5.0.0 + vfile-message: ^4.0.0 + checksum: 78c25465cf010f1004b22f0bbb3bd47793f458ead3561c779ea2b9204ceb1adc9c048592b0a15025df0c683a12ebe16a8bef008c06d9c0369f51116f64b35a2d + languageName: node + linkType: hard + +"hast-util-whitespace@npm:^3.0.0": + version: 3.0.0 + resolution: "hast-util-whitespace@npm:3.0.0" + dependencies: + "@types/hast": ^3.0.0 + checksum: 41d93ccce218ba935dc3c12acdf586193c35069489c8c8f50c2aa824c00dec94a3c78b03d1db40fa75381942a189161922e4b7bca700b3a2cc779634c351a1e4 + languageName: node + linkType: hard + "he@npm:^1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" @@ -10701,31 +12490,10 @@ __metadata: languageName: node linkType: hard -"headers-polyfill@npm:3.2.5": - version: 3.2.5 - resolution: "headers-polyfill@npm:3.2.5" - checksum: a3c4bdd661584fd39e40c0f91412abc514616edfbd20d29a75567e591f90ef5c445c8e209b7f3c2b2375d27e95e4690f33417368a168d4832484a93861ab6a3c - languageName: node - linkType: hard - -"headers-polyfill@npm:^3.0.4": - version: 3.3.0 - resolution: "headers-polyfill@npm:3.3.0" - checksum: 6dd010544b7c1a878aa612b49d9e27d273aa9e8a462e1ae05ca212fafa68e6b7cbdec4765f4e443b2fe70d2818f5d9814eab53fa2ba793bf1e5a6b6eff760474 - languageName: node - linkType: hard - -"hex-color-regex@npm:^1.1.0": - version: 1.1.0 - resolution: "hex-color-regex@npm:1.1.0" - checksum: 44fa1b7a26d745012f3bfeeab8015f60514f72d2fcf10dce33068352456b8d71a2e6bc5a17f933ab470da2c5ab1e3e04b05caf3fefe3c1cabd7e02e516fc8784 - languageName: node - linkType: hard - -"hexoid@npm:^1.0.0": - version: 1.0.0 - resolution: "hexoid@npm:1.0.0" - checksum: 27a148ca76a2358287f40445870116baaff4a0ed0acc99900bf167f0f708ffd82e044ff55e9949c71963852b580fc024146d3ac6d5d76b508b78d927fa48ae2d +"headers-polyfill@npm:^4.0.2": + version: 4.0.3 + resolution: "headers-polyfill@npm:4.0.3" + checksum: 382efe88575362f9f343f813a9df5131cec23129121111c55fb1151fb6dc87d963a820412fc95ff9cbc3016149de0714211dfa5d5914020ed92a69f014f66600 languageName: node linkType: hard @@ -10743,17 +12511,6 @@ __metadata: languageName: node linkType: hard -"hmac-drbg@npm:^1.0.1": - version: 1.0.1 - resolution: "hmac-drbg@npm:1.0.1" - dependencies: - hash.js: ^1.0.3 - minimalistic-assert: ^1.0.0 - minimalistic-crypto-utils: ^1.0.1 - checksum: bd30b6a68d7f22d63f10e1888aee497d7c2c5c0bb469e66bbdac99f143904d1dfe95f8131f95b3e86c86dd239963c9d972fcbe147e7cffa00e55d18585c43fe0 - languageName: node - linkType: hard - "hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.1": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" @@ -10770,13 +12527,6 @@ __metadata: languageName: node linkType: hard -"hosted-git-info@npm:^2.1.4": - version: 2.8.9 - resolution: "hosted-git-info@npm:2.8.9" - checksum: c955394bdab888a1e9bb10eb33029e0f7ce5a2ac7b3f158099dc8c486c99e73809dca609f5694b223920ca2174db33d32b12f9a2a47141dc59607c29da5a62dd - languageName: node - linkType: hard - "hpack.js@npm:^2.1.6": version: 2.1.6 resolution: "hpack.js@npm:2.1.6" @@ -10789,20 +12539,6 @@ __metadata: languageName: node linkType: hard -"hsl-regex@npm:^1.0.0": - version: 1.0.0 - resolution: "hsl-regex@npm:1.0.0" - checksum: de9ee1bf39de1b83cc3fa0fa1cc337f29f14911e79411d66347365c54fab6b109eea2dd741eaa02486e24de31627ad7bf4453f22224fb55a2fe2b58166fa63b8 - languageName: node - linkType: hard - -"hsla-regex@npm:^1.0.0": - version: 1.0.0 - resolution: "hsla-regex@npm:1.0.0" - checksum: 9aa6eb9ff6c102d2395435aa5d1d91eae20043c4b1497c543d8db501c05f3edacd9a07fb34a987059d7902dba415af4cb4e610f751859ae8e7525df4ffcd085f - languageName: node - linkType: hard - "html-encoding-sniffer@npm:^2.0.1": version: 2.0.1 resolution: "html-encoding-sniffer@npm:2.0.1" @@ -10812,10 +12548,10 @@ __metadata: languageName: node linkType: hard -"html-entities@npm:^1.2.1, html-entities@npm:^1.3.1": - version: 1.4.0 - resolution: "html-entities@npm:1.4.0" - checksum: 4b73ffb9eead200f99146e4fbe70acb0af2fea136901a131fc3a782e9ef876a7cbb07dec303ca1f8804232b812249dbf3643a270c9c524852065d9224a8dcdd0 +"html-entities@npm:^2.1.0, html-entities@npm:^2.3.2": + version: 2.6.0 + resolution: "html-entities@npm:2.6.0" + checksum: 720643f7954019c80911430a7df2728524c07080edfe812610bfc5d8191cd772b470bee0ee151bf7426679314ae53cf28a1c845d702123714e625a8565b26567 languageName: node linkType: hard @@ -10826,39 +12562,48 @@ __metadata: languageName: node linkType: hard -"html-minifier-terser@npm:^5.0.1": - version: 5.1.1 - resolution: "html-minifier-terser@npm:5.1.1" +"html-minifier-terser@npm:^6.0.2": + version: 6.1.0 + resolution: "html-minifier-terser@npm:6.1.0" dependencies: - camel-case: ^4.1.1 - clean-css: ^4.2.3 - commander: ^4.1.1 + camel-case: ^4.1.2 + clean-css: ^5.2.2 + commander: ^8.3.0 he: ^1.2.0 - param-case: ^3.0.3 + param-case: ^3.0.4 relateurl: ^0.2.7 - terser: ^4.6.3 + terser: ^5.10.0 bin: html-minifier-terser: cli.js - checksum: 75ff3ff886631b9ecb3035acb8e7dd98c599bb4d4618ad6f7e487ee9752987dddcf6848dc3c1ab1d7fc1ad4484337c2ce39c19eac17b0342b4b15e4294c8a904 + checksum: ac52c14006476f773204c198b64838477859dc2879490040efab8979c0207424da55d59df7348153f412efa45a0840a1ca3c757bf14767d23a15e3e389d37a93 languageName: node linkType: hard -"html-webpack-plugin@npm:4.5.0": - version: 4.5.0 - resolution: "html-webpack-plugin@npm:4.5.0" - dependencies: - "@types/html-minifier-terser": ^5.0.0 - "@types/tapable": ^1.0.5 - "@types/webpack": ^4.41.8 - html-minifier-terser: ^5.0.1 - loader-utils: ^1.2.3 - lodash: ^4.17.15 - pretty-error: ^2.1.1 - tapable: ^1.1.3 - util.promisify: 1.0.0 +"html-url-attributes@npm:^3.0.0": + version: 3.0.1 + resolution: "html-url-attributes@npm:3.0.1" + checksum: 1ecbf9cae0c438d2802386710177b7bbf7e30cc61327e9f125eb32fca7302cd1e3ab45c441859cb1e7646109be322fc1163592ad4dfde9b14d09416d101a6573 + languageName: node + linkType: hard + +"html-webpack-plugin@npm:^5.5.0": + version: 5.6.4 + resolution: "html-webpack-plugin@npm:5.6.4" + dependencies: + "@types/html-minifier-terser": ^6.0.0 + html-minifier-terser: ^6.0.2 + lodash: ^4.17.21 + pretty-error: ^4.0.0 + tapable: ^2.0.0 peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: d197db16a160ab9136a544e297c3c75d34b769d3cee12a82b9e7af7ee38ff07f4a27f2235581a9624f03996cd24997613df807341799140b4427c12bc4f496f9 + "@rspack/core": 0.x || 1.x + webpack: ^5.20.0 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: b486d99ce820d563dda215f8b6bbeb78127a738b88b419c95d577165e10dd29125e151010b5745ce933e8055f2445c2f9ad1c93024ad3b752db9ac613e84cfac languageName: node linkType: hard @@ -10875,9 +12620,9 @@ __metadata: linkType: hard "http-cache-semantics@npm:^4.1.1": - version: 4.1.1 - resolution: "http-cache-semantics@npm:4.1.1" - checksum: 83ac0bc60b17a3a36f9953e7be55e5c8f41acc61b22583060e8dedc9dd5e3607c823a88d0926f9150e571f90946835c7fe150732801010845c72cd8bbff1a236 + version: 4.2.0 + resolution: "http-cache-semantics@npm:4.2.0" + checksum: 7a7246ddfce629f96832791176fd643589d954e6f3b49548dadb4290451961237fab8fcea41cd2008fe819d95b41c1e8b97f47d088afc0a1c81705287b4ddbcc languageName: node linkType: hard @@ -10888,7 +12633,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:2.0.0": +"http-errors@npm:2.0.0, http-errors@npm:^2.0.0": version: 2.0.0 resolution: "http-errors@npm:2.0.0" dependencies: @@ -10914,9 +12659,9 @@ __metadata: linkType: hard "http-parser-js@npm:>=0.5.1": - version: 0.5.8 - resolution: "http-parser-js@npm:0.5.8" - checksum: 6bbdf2429858e8cf13c62375b0bfb6dc3955ca0f32e58237488bc86cd2378f31d31785fd3ac4ce93f1c74e0189cf8823c91f5cb061696214fd368d2452dc871d + version: 0.5.10 + resolution: "http-parser-js@npm:0.5.10" + checksum: 1038177c5f114860345ce7c19223d2cdd9a103265bd897bab13343c9eff4deef60f7956a674485f1234ffc9b19fb4b97f0c20a5848cfc9ccbf5d3c438d89ae89 languageName: node linkType: hard @@ -10941,19 +12686,25 @@ __metadata: languageName: node linkType: hard -"http-proxy-middleware@npm:0.19.1": - version: 0.19.1 - resolution: "http-proxy-middleware@npm:0.19.1" +"http-proxy-middleware@npm:^2.0.3": + version: 2.0.9 + resolution: "http-proxy-middleware@npm:2.0.9" dependencies: - http-proxy: ^1.17.0 - is-glob: ^4.0.0 - lodash: ^4.17.11 - micromatch: ^3.1.10 - checksum: 64df0438417a613bb22b3689d9652a1b7a56f10b145a463f95f4e8a9b9a351f2c63bc5fd3a9cd710baec224897733b6f299cb7f974ea82769b2a4f1e074764ac + "@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 + peerDependencies: + "@types/express": ^4.17.13 + peerDependenciesMeta: + "@types/express": + optional: true + checksum: 0ea88609b9c13fa03b89f8e6b85bd5c537027ec6990005dd81a7fbb3e73fcf8d6a6e3db2b57b1c6cddbcda80965704584dc6291d0e721b2700198c4e59ee0d0b languageName: node linkType: hard -"http-proxy@npm:^1.17.0": +"http-proxy@npm:^1.18.1": version: 1.18.1 resolution: "http-proxy@npm:1.18.1" dependencies: @@ -10964,13 +12715,6 @@ __metadata: languageName: node linkType: hard -"https-browserify@npm:^1.0.0": - version: 1.0.0 - resolution: "https-browserify@npm:1.0.0" - checksum: 09b35353e42069fde2435760d13f8a3fb7dd9105e358270e2e225b8a94f811b461edd17cb57594e5f36ec1218f121c160ddceeec6e8be2d55e01dcbbbed8cbae - languageName: node - linkType: hard - "https-proxy-agent@npm:^5.0.0": version: 5.0.1 resolution: "https-proxy-agent@npm:5.0.1" @@ -10982,23 +12726,23 @@ __metadata: linkType: hard "https-proxy-agent@npm:^7.0.1": - version: 7.0.4 - resolution: "https-proxy-agent@npm:7.0.4" + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" dependencies: - agent-base: ^7.0.2 + agent-base: ^7.1.2 debug: 4 - checksum: daaab857a967a2519ddc724f91edbbd388d766ff141b9025b629f92b9408fc83cee8a27e11a907aede392938e9c398e240d643e178408a59e4073539cde8cfe9 + checksum: b882377a120aa0544846172e5db021fa8afbf83fea2a897d397bd2ddd8095ab268c24bc462f40a15f2a8c600bf4aa05ce52927f70038d4014e68aefecfa94e8d languageName: node linkType: hard -"human-signals@npm:^1.1.1": - version: 1.1.1 - resolution: "human-signals@npm:1.1.1" - checksum: d587647c9e8ec24e02821b6be7de5a0fc37f591f6c4e319b3054b43fd4c35a70a94c46fc74d8c1a43c47fde157d23acd7421f375e1c1365b09a16835b8300205 +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: b87fd89fce72391625271454e70f67fe405277415b48bcc0117ca73d31fa23a4241787afdc8d67f5a116cf37258c052f59ea82daffa72364d61351423848e3b8 languageName: node linkType: hard -"iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24": +"iconv-lite@npm:0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" dependencies: @@ -11007,7 +12751,16 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.6.2": +"iconv-lite@npm:0.7.0": + version: 0.7.0 + resolution: "iconv-lite@npm:0.7.0" + dependencies: + safer-buffer: ">= 2.1.2 < 3.0.0" + checksum: f362a8befb95e37f29be1d1290c17e0c9d0d4ad4fa62fcfd813cc9c937ab89401abed9a011f83e10651a267abb2aa231ec7da91d843570bec873bd98489b5bf8 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -11016,23 +12769,23 @@ __metadata: languageName: node linkType: hard -"icss-replace-symbols@npm:1.1.0, icss-replace-symbols@npm:^1.1.0": - version: 1.1.0 - resolution: "icss-replace-symbols@npm:1.1.0" - checksum: 24575b2c2f7e762bfc6f4beee31be9ba98a01cad521b5aa9954090a5de2b5e1bf67814c17e22f9e51b7d798238db8215a173d6c2b4726ce634ce06b68ece8045 +"icss-utils@npm:^5.0.0, icss-utils@npm:^5.1.0": + version: 5.1.0 + resolution: "icss-utils@npm:5.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 5c324d283552b1269cfc13a503aaaa172a280f914e5b81544f3803bc6f06a3b585fb79f66f7c771a2c052db7982c18bf92d001e3b47282e3abbbb4c4cc488d68 languageName: node linkType: hard -"icss-utils@npm:^4.0.0, icss-utils@npm:^4.1.1": - version: 4.1.1 - resolution: "icss-utils@npm:4.1.1" - dependencies: - postcss: ^7.0.14 - checksum: a4ca2c6b82cb3eb879d635bd4028d74bca174edc49ee48ef5f01988489747d340a389d5a0ac6f6887a5c24ab8fc4386c781daab32a7ade5344a2edff66207635 +"idb@npm:^7.0.1": + version: 7.1.1 + resolution: "idb@npm:7.1.1" + checksum: 1973c28d53c784b177bdef9f527ec89ec239ec7cf5fcbd987dae75a16c03f5b7dfcc8c6d3285716fd0309dd57739805390bd9f98ce23b1b7d8849a3b52de8d56 languageName: node linkType: hard -"identity-obj-proxy@npm:3.0.0": +"identity-obj-proxy@npm:^3.0.0": version: 3.0.0 resolution: "identity-obj-proxy@npm:3.0.0" dependencies: @@ -11041,20 +12794,13 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.1.13, ieee754@npm:^1.1.4": +"ieee754@npm:^1.1.13": version: 1.2.1 resolution: "ieee754@npm:1.2.1" checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e languageName: node linkType: hard -"iferr@npm:^0.1.5": - version: 0.1.5 - resolution: "iferr@npm:0.1.5" - checksum: a18d19b6ad06a2d5412c0d37f6364869393ef6d1688d59d00082c1f35c92399094c031798340612458cd832f4f2e8b13bc9615934a7d8b0c53061307a3816aa1 - languageName: node - linkType: hard - "ignore-by-default@npm:^1.0.1": version: 1.0.1 resolution: "ignore-by-default@npm:1.0.1" @@ -11069,86 +12815,46 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.4, ignore@npm:^5.1.8, ignore@npm:^5.2.0": - version: 5.3.1 - resolution: "ignore@npm:5.3.1" - checksum: 71d7bb4c1dbe020f915fd881108cbe85a0db3d636a0ea3ba911393c53946711d13a9b1143c7e70db06d571a5822c0a324a6bcde5c9904e7ca5047f01f1bf8cd3 - languageName: node - linkType: hard - -"immer@npm:8.0.1": - version: 8.0.1 - resolution: "immer@npm:8.0.1" - checksum: 63d875c04882b862481a0a692816e5982975a47a57619698bc1bb52963ad3b624911991708b2b81a7af6fdac15083d408e43932d83a6a61216e5a4503efd4095 - languageName: node - linkType: hard - -"immutable@npm:^4.0.0": - version: 4.3.5 - resolution: "immutable@npm:4.3.5" - checksum: 0e25dd5c314421faede9e1122ab26cdb638cc3edc8678c4a75dee104279b12621a30c80a480fae7f68bc7e81672f1e672e454dc0fdc7e6cf0af10809348387b8 +"ignore@npm:^5.2.0, ignore@npm:^5.3.1": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 2acfd32a573260ea522ea0bfeff880af426d68f6831f973129e2ba7363f422923cf53aab62f8369cbf4667c7b25b6f8a3761b34ecdb284ea18e87a5262a865be languageName: node linkType: hard -"import-cwd@npm:^2.0.0": - version: 2.1.0 - resolution: "import-cwd@npm:2.1.0" - dependencies: - import-from: ^2.1.0 - checksum: b8786fa3578f3df55370352bf61f99c2d8e6ee9b5741a07503d5a73d99281d141330a8faf87078e67527be4558f758356791ee5efb4b0112ac5eaed0f07de544 +"immer@npm:^9.0.7": + version: 9.0.21 + resolution: "immer@npm:9.0.21" + checksum: 70e3c274165995352f6936695f0ef4723c52c92c92dd0e9afdfe008175af39fa28e76aafb3a2ca9d57d1fb8f796efc4dd1e1cc36f18d33fa5b74f3dfb0375432 languageName: node linkType: hard -"import-fresh@npm:^2.0.0": - version: 2.0.0 - resolution: "import-fresh@npm:2.0.0" - dependencies: - caller-path: ^2.0.0 - resolve-from: ^3.0.0 - checksum: 610255f9753cc6775df00be08e9f43691aa39f7703e3636c45afe22346b8b545e600ccfe100c554607546fc8e861fa149a0d1da078c8adedeea30fff326eef79 +"immutable@npm:^5.0.2": + version: 5.1.3 + resolution: "immutable@npm:5.1.3" + checksum: 63a1df5f68bbcaa7b1cb17aeaa8bc327734ad7b6936afe33b157fbdb480542c95fbab2de800b4969b5d45d51f2974aa916c78fa5c0d3a48810604268e72824cc languageName: node linkType: hard -"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": - version: 3.3.0 - resolution: "import-fresh@npm:3.3.0" +"import-fresh@npm:^3.0.0, import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1": + version: 3.3.1 + resolution: "import-fresh@npm:3.3.1" dependencies: parent-module: ^1.0.0 resolve-from: ^4.0.0 - checksum: 2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa - languageName: node - linkType: hard - -"import-from@npm:^2.1.0": - version: 2.1.0 - resolution: "import-from@npm:2.1.0" - dependencies: - resolve-from: ^3.0.0 - checksum: 91f6f89f46a07227920ef819181bb52eb93023ccc0bdf00224fdfb326f8f753e279ad06819f39a02bb88c9d3a4606adc85b0cc995285e5d65feeb59f1421a1d4 - languageName: node - linkType: hard - -"import-local@npm:^2.0.0": - version: 2.0.0 - resolution: "import-local@npm:2.0.0" - dependencies: - pkg-dir: ^3.0.0 - resolve-cwd: ^2.0.0 - bin: - import-local-fixture: fixtures/cli.js - checksum: b8469252483624379fd65d53c82f3658b32a1136f7168bfeea961a4ea7ca10a45786ea2b02e0006408f9cd22d2f33305a6f17a64e4d5a03274a50942c5e7c949 + checksum: a06b19461b4879cc654d46f8a6244eb55eb053437afd4cbb6613cad6be203811849ed3e4ea038783092879487299fda24af932b86bdfff67c9055ba3612b8c87 languageName: node linkType: hard "import-local@npm:^3.0.2": - version: 3.1.0 - resolution: "import-local@npm:3.1.0" + version: 3.2.0 + resolution: "import-local@npm:3.2.0" dependencies: pkg-dir: ^4.2.0 resolve-cwd: ^3.0.0 bin: import-local-fixture: fixtures/cli.js - checksum: bfcdb63b5e3c0e245e347f3107564035b128a414c4da1172a20dc67db2504e05ede4ac2eee1252359f78b0bfd7b19ef180aec427c2fce6493ae782d73a04cddd + checksum: 0b0b0b412b2521739fbb85eeed834a3c34de9bc67e670b3d0b86248fc460d990a7b116ad056c084b87a693ef73d1f17268d6a5be626bb43c998a8b1c8a230004 languageName: node linkType: hard @@ -11166,20 +12872,6 @@ __metadata: languageName: node linkType: hard -"indexes-of@npm:^1.0.1": - version: 1.0.1 - resolution: "indexes-of@npm:1.0.1" - checksum: 4f9799b1739a62f3e02d09f6f4162cf9673025282af7fa36e790146e7f4e216dad3e776a25b08536c093209c9fcb5ea7bd04b082d42686a45f58ff401d6da32e - languageName: node - linkType: hard - -"infer-owner@npm:^1.0.3, infer-owner@npm:^1.0.4": - version: 1.0.4 - resolution: "infer-owner@npm:1.0.4" - checksum: 181e732764e4a0611576466b4b87dac338972b839920b2a8cde43642e4ed6bd54dc1fb0b40874728f2a2df9a1b097b8ff83b56d5f8f8e3927f837fdcb47d8a89 - languageName: node - linkType: hard - "inflight@npm:^1.0.4": version: 1.0.6 resolution: "inflight@npm:1.0.6" @@ -11190,7 +12882,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -11204,152 +12896,84 @@ __metadata: languageName: node linkType: hard -"ini@npm:^1.3.5": +"ini@npm:^1.3.5, ini@npm:~1.3.0": version: 1.3.8 resolution: "ini@npm:1.3.8" checksum: dfd98b0ca3a4fc1e323e38a6c8eb8936e31a97a918d3b377649ea15bdb15d481207a0dda1021efbd86b464cae29a0d33c1d7dcaf6c5672bee17fa849bc50a1b3 languageName: node linkType: hard -"inline-style-parser@npm:0.1.1": - version: 0.1.1 - resolution: "inline-style-parser@npm:0.1.1" - checksum: 5d545056a3e1f2bf864c928a886a0e1656a3517127d36917b973de581bd54adc91b4bf1febcb0da054f204b4934763f1a4e09308b4d55002327cf1d48ac5d966 - languageName: node - linkType: hard - -"inquirer@npm:^8.2.0": - version: 8.2.6 - resolution: "inquirer@npm:8.2.6" - dependencies: - ansi-escapes: ^4.2.1 - chalk: ^4.1.1 - cli-cursor: ^3.1.0 - cli-width: ^3.0.0 - external-editor: ^3.0.3 - figures: ^3.0.0 - lodash: ^4.17.21 - mute-stream: 0.0.8 - ora: ^5.4.1 - run-async: ^2.4.0 - rxjs: ^7.5.5 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - through: ^2.3.6 - wrap-ansi: ^6.0.1 - checksum: 387ffb0a513559cc7414eb42c57556a60e302f820d6960e89d376d092e257a919961cd485a1b4de693dbb5c0de8bc58320bfd6247dfd827a873aa82a4215a240 - languageName: node - linkType: hard - -"internal-ip@npm:^4.3.0": - version: 4.3.0 - resolution: "internal-ip@npm:4.3.0" - dependencies: - default-gateway: ^4.2.0 - ipaddr.js: ^1.9.0 - checksum: c970433c84d9a6b46e2c9f5ab7785d3105b856d0a566891bf919241b5a884c5c1c9bf8e915aebb822a86c14b1b6867e58c1eaf5cd49eb023368083069d1a4a9a +"inline-style-parser@npm:0.2.4": + version: 0.2.4 + resolution: "inline-style-parser@npm:0.2.4" + checksum: 5df20a21dd8d67104faaae29774bb50dc9690c75bc5c45dac107559670a5530104ead72c4cf54f390026e617e7014c65b3d68fb0bb573a37c4d1f94e9c36e1ca languageName: node linkType: hard -"internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.7": - version: 1.0.7 - resolution: "internal-slot@npm:1.0.7" +"internal-slot@npm:^1.1.0": + version: 1.1.0 + resolution: "internal-slot@npm:1.1.0" dependencies: es-errors: ^1.3.0 - hasown: ^2.0.0 - side-channel: ^1.0.4 - checksum: cadc5eea5d7d9bc2342e93aae9f31f04c196afebb11bde97448327049f492cd7081e18623ae71388aac9cd237b692ca3a105be9c68ac39c1dec679d7409e33eb - languageName: node - linkType: hard - -"ip-address@npm:^9.0.5": - version: 9.0.5 - resolution: "ip-address@npm:9.0.5" - dependencies: - jsbn: 1.1.0 - sprintf-js: ^1.1.3 - checksum: aa15f12cfd0ef5e38349744e3654bae649a34c3b10c77a674a167e99925d1549486c5b14730eebce9fea26f6db9d5e42097b00aa4f9f612e68c79121c71652dc + hasown: ^2.0.2 + side-channel: ^1.1.0 + checksum: 8e0991c2d048cc08dab0a91f573c99f6a4215075887517ea4fa32203ce8aea60fa03f95b177977fa27eb502e5168366d0f3e02c762b799691411d49900611861 languageName: node linkType: hard -"ip-regex@npm:^2.1.0": - version: 2.1.0 - resolution: "ip-regex@npm:2.1.0" - checksum: 331d95052aa53ce245745ea0fc3a6a1e2e3c8d6da65fa8ea52bf73768c1b22a9ac50629d1d2b08c04e7b3ac4c21b536693c149ce2c2615ee4796030e5b3e3cba +"internmap@npm:1 - 2": + version: 2.0.3 + resolution: "internmap@npm:2.0.3" + checksum: 7ca41ec6aba8f0072fc32fa8a023450a9f44503e2d8e403583c55714b25efd6390c38a87161ec456bf42d7bc83aab62eb28f5aef34876b1ac4e60693d5e1d241 languageName: node linkType: hard -"ip@npm:^1.1.0, ip@npm:^1.1.5": - version: 1.1.9 - resolution: "ip@npm:1.1.9" - checksum: b6d91fd45a856e3bd6d4f601ea0619d90f3517638f6918ebd079f959a8a6308568d8db5ef4fdf037e0d9cfdcf264f46833dfeea81ca31309cf0a7eb4b1307b84 +"ip-address@npm:^10.0.1": + version: 10.0.1 + resolution: "ip-address@npm:10.0.1" + checksum: 525d5391cfd31a91f80f5857e98487aeaa8474e860a6725a0b6461ac8e436c7f8c869774dece391c8f8e7486306a34a4d1c094778c4c583a3f1f2cd905e5ed50 languageName: node linkType: hard -"ipaddr.js@npm:1.9.1, ipaddr.js@npm:^1.9.0": +"ipaddr.js@npm:1.9.1": version: 1.9.1 resolution: "ipaddr.js@npm:1.9.1" checksum: f88d3825981486f5a1942414c8d77dd6674dd71c065adcfa46f578d677edcb99fda25af42675cb59db492fdf427b34a5abfcde3982da11a8fd83a500b41cfe77 languageName: node linkType: hard -"is-absolute-url@npm:^2.0.0": - version: 2.1.0 - resolution: "is-absolute-url@npm:2.1.0" - checksum: 781e8cf8a2af54b1b7a92f269244d96c66224030d91120e734ebeebbce044c167767e1389789d8aaf82f9e429cb20ae93d6d0acfe6c4b53d2bd6ebb47a236d76 - languageName: node - linkType: hard - -"is-absolute-url@npm:^3.0.3": - version: 3.0.3 - resolution: "is-absolute-url@npm:3.0.3" - checksum: 5159b51d065d9ad29e16a2f78d6c0e41c43227caf90a45e659c54ea6fd50ef0595b1871ce392e84b1df7cfdcad9a8e66eec0813a029112188435abf115accb16 - languageName: node - linkType: hard - -"is-accessor-descriptor@npm:^1.0.1": - version: 1.0.1 - resolution: "is-accessor-descriptor@npm:1.0.1" - dependencies: - hasown: ^2.0.0 - checksum: 8db44c02230a5e9b9dec390a343178791f073d5d5556a400527d2fd67a72d93b226abab2bd4123305c268f5dc22831bfdbd38430441fda82ea9e0b95ddc6b267 - languageName: node - linkType: hard - -"is-alphabetical@npm:^1.0.0": - version: 1.0.4 - resolution: "is-alphabetical@npm:1.0.4" - checksum: 6508cce44fd348f06705d377b260974f4ce68c74000e7da4045f0d919e568226dc3ce9685c5a2af272195384df6930f748ce9213fc9f399b5d31b362c66312cb +"ipaddr.js@npm:^2.0.1": + version: 2.2.0 + resolution: "ipaddr.js@npm:2.2.0" + checksum: 770ba8451fd9bf78015e8edac0d5abd7a708cbf75f9429ca9147a9d2f3a2d60767cd5de2aab2b1e13ca6e4445bdeff42bf12ef6f151c07a5c6cf8a44328e2859 languageName: node linkType: hard -"is-alphanumerical@npm:^1.0.0": - version: 1.0.4 - resolution: "is-alphanumerical@npm:1.0.4" - dependencies: - is-alphabetical: ^1.0.0 - is-decimal: ^1.0.0 - checksum: e2e491acc16fcf5b363f7c726f666a9538dba0a043665740feb45bba1652457a73441e7c5179c6768a638ed396db3437e9905f403644ec7c468fb41f4813d03f +"is-alphabetical@npm:^2.0.0": + version: 2.0.1 + resolution: "is-alphabetical@npm:2.0.1" + checksum: 56207db8d9de0850f0cd30f4966bf731eb82cedfe496cbc2e97e7c3bacaf66fc54a972d2d08c0d93bb679cb84976a05d24c5ad63de56fabbfc60aadae312edaa languageName: node linkType: hard -"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1": - version: 1.1.1 - resolution: "is-arguments@npm:1.1.1" +"is-alphanumerical@npm:^2.0.0": + version: 2.0.1 + resolution: "is-alphanumerical@npm:2.0.1" dependencies: - call-bind: ^1.0.2 - has-tostringtag: ^1.0.0 - checksum: 7f02700ec2171b691ef3e4d0e3e6c0ba408e8434368504bb593d0d7c891c0dbfda6d19d30808b904a6cb1929bca648c061ba438c39f296c2a8ca083229c49f27 + is-alphabetical: ^2.0.0 + is-decimal: ^2.0.0 + checksum: 87acc068008d4c9c4e9f5bd5e251041d42e7a50995c77b1499cf6ed248f971aadeddb11f239cabf09f7975ee58cac7a48ffc170b7890076d8d227b24a68663c9 languageName: node linkType: hard -"is-array-buffer@npm:^3.0.2, is-array-buffer@npm:^3.0.4": - version: 3.0.4 - resolution: "is-array-buffer@npm:3.0.4" +"is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5": + version: 3.0.5 + resolution: "is-array-buffer@npm:3.0.5" dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.2.1 - checksum: e4e3e6ef0ff2239e75371d221f74bc3c26a03564a22efb39f6bb02609b598917ddeecef4e8c877df2a25888f247a98198959842a5e73236bc7f22cabdf6351a7 + call-bind: ^1.0.8 + call-bound: ^1.0.3 + get-intrinsic: ^1.2.6 + checksum: f137a2a6e77af682cdbffef1e633c140cf596f72321baf8bba0f4ef22685eb4339dde23dfe9e9ca430b5f961dee4d46577dcf12b792b68518c8449b134fb9156 languageName: node linkType: hard @@ -11360,37 +12984,25 @@ __metadata: languageName: node linkType: hard -"is-arrayish@npm:^0.3.1": - version: 0.3.2 - resolution: "is-arrayish@npm:0.3.2" - checksum: 977e64f54d91c8f169b59afcd80ff19227e9f5c791fa28fa2e5bce355cbaf6c2c356711b734656e80c9dd4a854dd7efcf7894402f1031dfc5de5d620775b4d5f - languageName: node - linkType: hard - "is-async-function@npm:^2.0.0": - version: 2.0.0 - resolution: "is-async-function@npm:2.0.0" - dependencies: - has-tostringtag: ^1.0.0 - checksum: e3471d95e6c014bf37cad8a93f2f4b6aac962178e0a5041e8903147166964fdc1c5c1d2ef87e86d77322c370ca18f2ea004fa7420581fa747bcaf7c223069dbd - languageName: node - linkType: hard - -"is-bigint@npm:^1.0.1": - version: 1.0.4 - resolution: "is-bigint@npm:1.0.4" + version: 2.1.1 + resolution: "is-async-function@npm:2.1.1" dependencies: - has-bigints: ^1.0.1 - checksum: c56edfe09b1154f8668e53ebe8252b6f185ee852a50f9b41e8d921cb2bed425652049fbe438723f6cb48a63ca1aa051e948e7e401e093477c99c84eba244f666 + async-function: ^1.0.0 + call-bound: ^1.0.3 + get-proto: ^1.0.1 + has-tostringtag: ^1.0.2 + safe-regex-test: ^1.1.0 + checksum: 9bece45133da26636488ca127d7686b85ad3ca18927e2850cff1937a650059e90be1c71a48623f8791646bb7a241b0cabf602a0b9252dcfa5ab273f2399000e6 languageName: node linkType: hard -"is-binary-path@npm:^1.0.0": - version: 1.0.1 - resolution: "is-binary-path@npm:1.0.1" +"is-bigint@npm:^1.1.0": + version: 1.1.0 + resolution: "is-bigint@npm:1.1.0" dependencies: - binary-extensions: ^1.0.0 - checksum: a803c99e9d898170c3b44a86fbdc0736d3d7fcbe737345433fb78e810b9fe30c982657782ad0e676644ba4693ddf05601a7423b5611423218663d6b533341ac9 + has-bigints: ^1.0.2 + checksum: ee1544f0e664f253306786ed1dce494b8cf242ef415d6375d8545b4d8816b0f054bd9f948a8988ae2c6325d1c28260dd02978236b2f7b8fb70dfc4838a6c9fa7 languageName: node linkType: hard @@ -11403,133 +13015,61 @@ __metadata: languageName: node linkType: hard -"is-boolean-object@npm:^1.1.0": - version: 1.1.2 - resolution: "is-boolean-object@npm:1.1.2" +"is-boolean-object@npm:^1.2.1": + version: 1.2.2 + resolution: "is-boolean-object@npm:1.2.2" dependencies: - call-bind: ^1.0.2 - has-tostringtag: ^1.0.0 - checksum: c03b23dbaacadc18940defb12c1c0e3aaece7553ef58b162a0f6bba0c2a7e1551b59f365b91e00d2dbac0522392d576ef322628cb1d036a0fe51eb466db67222 - languageName: node - linkType: hard - -"is-buffer@npm:^1.1.5": - version: 1.1.6 - resolution: "is-buffer@npm:1.1.6" - checksum: 4a186d995d8bbf9153b4bd9ff9fd04ae75068fe695d29025d25e592d9488911eeece84eefbd8fa41b8ddcc0711058a71d4c466dcf6f1f6e1d83830052d8ca707 - languageName: node - linkType: hard - -"is-buffer@npm:^2.0.0": - version: 2.0.5 - resolution: "is-buffer@npm:2.0.5" - checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42 + call-bound: ^1.0.3 + has-tostringtag: ^1.0.2 + checksum: 0415b181e8f1bfd5d3f8a20f8108e64d372a72131674eea9c2923f39d065b6ad08d654765553bdbffbd92c3746f1007986c34087db1bd89a31f71be8359ccdaa languageName: node linkType: hard -"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": +"is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" checksum: 61fd57d03b0d984e2ed3720fb1c7a897827ea174bd44402878e059542ea8c4aeedee0ea0985998aa5cc2736b2fa6e271c08587addb5b3959ac52cf665173d1ac languageName: node linkType: hard -"is-ci@npm:^2.0.0": - version: 2.0.0 - resolution: "is-ci@npm:2.0.0" - dependencies: - ci-info: ^2.0.0 - bin: - is-ci: bin.js - checksum: 77b869057510f3efa439bbb36e9be429d53b3f51abd4776eeea79ab3b221337fe1753d1e50058a9e2c650d38246108beffb15ccfd443929d77748d8c0cc90144 - languageName: node - linkType: hard - -"is-color-stop@npm:^1.0.0": - version: 1.1.0 - resolution: "is-color-stop@npm:1.1.0" - dependencies: - css-color-names: ^0.0.4 - hex-color-regex: ^1.1.0 - hsl-regex: ^1.0.0 - hsla-regex: ^1.0.0 - rgb-regex: ^1.0.1 - rgba-regex: ^1.0.0 - checksum: 778dd52a603ab8da827925aa4200fe6733b667b216495a04110f038b925dc5ef58babe759b94ffc4e44fcf439328695770873937f59d6045f676322b97f3f92d - languageName: node - linkType: hard - -"is-core-module@npm:^2.0.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1": - version: 2.13.1 - resolution: "is-core-module@npm:2.13.1" - dependencies: - hasown: ^2.0.0 - checksum: 256559ee8a9488af90e4bad16f5583c6d59e92f0742e9e8bb4331e758521ee86b810b93bae44f390766ffbc518a0488b18d9dab7da9a5ff997d499efc9403f7c - languageName: node - linkType: hard - -"is-data-descriptor@npm:^1.0.1": - version: 1.0.1 - resolution: "is-data-descriptor@npm:1.0.1" +"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1": + version: 2.16.1 + resolution: "is-core-module@npm:2.16.1" dependencies: - hasown: ^2.0.0 - checksum: fc6da5be5177149d554c5612cc382e9549418ed72f2d3ed5a3e6511b03dd119ae1b2258320ca94931df50b7e9ee012894eccd4ca45bbcadf0d5b27da6faeb15a + hasown: ^2.0.2 + checksum: 6ec5b3c42d9cbf1ac23f164b16b8a140c3cec338bf8f884c076ca89950c7cc04c33e78f02b8cae7ff4751f3247e3174b2330f1fe4de194c7210deb8b1ea316a7 languageName: node linkType: hard -"is-data-view@npm:^1.0.1": - version: 1.0.1 - resolution: "is-data-view@npm:1.0.1" +"is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2": + version: 1.0.2 + resolution: "is-data-view@npm:1.0.2" dependencies: + call-bound: ^1.0.2 + get-intrinsic: ^1.2.6 is-typed-array: ^1.1.13 - checksum: 4ba4562ac2b2ec005fefe48269d6bd0152785458cd253c746154ffb8a8ab506a29d0cfb3b74af87513843776a88e4981ae25c89457bf640a33748eab1a7216b5 - languageName: node - linkType: hard - -"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": - version: 1.0.5 - resolution: "is-date-object@npm:1.0.5" - dependencies: - has-tostringtag: ^1.0.0 - checksum: baa9077cdf15eb7b58c79398604ca57379b2fc4cf9aa7a9b9e295278648f628c9b201400c01c5e0f7afae56507d741185730307cbe7cad3b9f90a77e5ee342fc - languageName: node - linkType: hard - -"is-decimal@npm:^1.0.0": - version: 1.0.4 - resolution: "is-decimal@npm:1.0.4" - checksum: ed483a387517856dc395c68403a10201fddcc1b63dc56513fbe2fe86ab38766120090ecdbfed89223d84ca8b1cd28b0641b93cb6597b6e8f4c097a7c24e3fb96 - languageName: node - linkType: hard - -"is-descriptor@npm:^0.1.0": - version: 0.1.7 - resolution: "is-descriptor@npm:0.1.7" - dependencies: - is-accessor-descriptor: ^1.0.1 - is-data-descriptor: ^1.0.1 - checksum: 45743109f0bb03f9fa989c34d31ece87cc15792649f147b896a7c4db2906a02fca685867619f4d312e024d7bbd53b945a47c6830d01f5e73efcc6388ac211963 + checksum: 31600dd19932eae7fd304567e465709ffbfa17fa236427c9c864148e1b54eb2146357fcf3aed9b686dee13c217e1bb5a649cb3b9c479e1004c0648e9febde1b2 languageName: node linkType: hard -"is-descriptor@npm:^1.0.0, is-descriptor@npm:^1.0.2": - version: 1.0.3 - resolution: "is-descriptor@npm:1.0.3" +"is-date-object@npm:^1.0.5, is-date-object@npm:^1.1.0": + version: 1.1.0 + resolution: "is-date-object@npm:1.1.0" dependencies: - is-accessor-descriptor: ^1.0.1 - is-data-descriptor: ^1.0.1 - checksum: 316153b2fd86ac23b0a2f28b77744ae0a4e3c7a54fe52fa70b125d0971eb0a3bcfb562fa8e74537af0dad5bc405cc606726eb501fc748a241c10910deea89cfb + call-bound: ^1.0.2 + has-tostringtag: ^1.0.2 + checksum: d6c36ab9d20971d65f3fc64cef940d57a4900a2ac85fb488a46d164c2072a33da1cb51eefcc039e3e5c208acbce343d3480b84ab5ff0983f617512da2742562a languageName: node linkType: hard -"is-directory@npm:^0.3.1": - version: 0.3.1 - resolution: "is-directory@npm:0.3.1" - checksum: dce9a9d3981e38f2ded2a80848734824c50ee8680cd09aa477bef617949715cfc987197a2ca0176c58a9fb192a1a0d69b535c397140d241996a609d5906ae524 +"is-decimal@npm:^2.0.0": + version: 2.0.1 + resolution: "is-decimal@npm:2.0.1" + checksum: 97132de7acdce77caa7b797632970a2ecd649a88e715db0e4dbc00ab0708b5e7574ba5903962c860cd4894a14fd12b100c0c4ac8aed445cf6f55c6cf747a4158 languageName: node linkType: hard -"is-docker@npm:^2.0.0": +"is-docker@npm:^2.0.0, is-docker@npm:^2.1.1": version: 2.2.1 resolution: "is-docker@npm:2.2.1" bin: @@ -11545,42 +13085,19 @@ __metadata: languageName: node linkType: hard -"is-extendable@npm:^0.1.0, is-extendable@npm:^0.1.1": - version: 0.1.1 - resolution: "is-extendable@npm:0.1.1" - checksum: 3875571d20a7563772ecc7a5f36cb03167e9be31ad259041b4a8f73f33f885441f778cee1f1fe0085eb4bc71679b9d8c923690003a36a6a5fdf8023e6e3f0672 - languageName: node - linkType: hard - -"is-extendable@npm:^1.0.1": - version: 1.0.1 - resolution: "is-extendable@npm:1.0.1" - dependencies: - is-plain-object: ^2.0.4 - checksum: db07bc1e9de6170de70eff7001943691f05b9d1547730b11be01c0ebfe67362912ba743cf4be6fd20a5e03b4180c685dad80b7c509fe717037e3eee30ad8e84f - languageName: node - linkType: hard - -"is-extglob@npm:^2.1.0, is-extglob@npm:^2.1.1": +"is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 languageName: node linkType: hard -"is-finalizationregistry@npm:^1.0.2": - version: 1.0.2 - resolution: "is-finalizationregistry@npm:1.0.2" +"is-finalizationregistry@npm:^1.1.0": + version: 1.1.1 + resolution: "is-finalizationregistry@npm:1.1.1" dependencies: - call-bind: ^1.0.2 - checksum: 4f243a8e06228cd45bdab8608d2cb7abfc20f6f0189c8ac21ea8d603f1f196eabd531ce0bb8e08cbab047e9845ef2c191a3761c9a17ad5cabf8b35499c4ad35d - languageName: node - linkType: hard - -"is-fullwidth-code-point@npm:^2.0.0": - version: 2.0.0 - resolution: "is-fullwidth-code-point@npm:2.0.0" - checksum: eef9c6e15f68085fec19ff6a978a6f1b8f48018fd1265035552078ee945573594933b09bbd6f562553e2a241561439f1ef5339276eba68d272001343084cfab8 + call-bound: ^1.0.3 + checksum: 38c646c506e64ead41a36c182d91639833311970b6b6c6268634f109eef0a1a9d2f1f2e499ef4cb43c744a13443c4cdd2f0812d5afdcee5e9b65b72b28c48557 languageName: node linkType: hard @@ -11598,21 +13115,15 @@ __metadata: languageName: node linkType: hard -"is-generator-function@npm:^1.0.10, is-generator-function@npm:^1.0.7": - version: 1.0.10 - resolution: "is-generator-function@npm:1.0.10" - dependencies: - has-tostringtag: ^1.0.0 - checksum: d54644e7dbaccef15ceb1e5d91d680eb5068c9ee9f9eb0a9e04173eb5542c9b51b5ab52c5537f5703e48d5fddfd376817c1ca07a84a407b7115b769d4bdde72b - languageName: node - linkType: hard - -"is-glob@npm:^3.1.0": - version: 3.1.0 - resolution: "is-glob@npm:3.1.0" +"is-generator-function@npm:^1.0.10": + version: 1.1.0 + resolution: "is-generator-function@npm:1.1.0" dependencies: - is-extglob: ^2.1.0 - checksum: 9d483bca84f16f01230f7c7c8c63735248fe1064346f292e0f6f8c76475fd20c6f50fc19941af5bec35f85d6bf26f4b7768f39a48a5f5fdc72b408dc74e07afc + call-bound: ^1.0.3 + get-proto: ^1.0.0 + has-tostringtag: ^1.0.2 + safe-regex-test: ^1.1.0 + checksum: f7f7276131bdf7e28169b86ac55a5b080012a597f9d85a0cbef6fe202a7133fa450a3b453e394870e3cb3685c5a764c64a9f12f614684b46969b1e6f297bed6b languageName: node linkType: hard @@ -11625,28 +13136,14 @@ __metadata: languageName: node linkType: hard -"is-hexadecimal@npm:^1.0.0": - version: 1.0.4 - resolution: "is-hexadecimal@npm:1.0.4" - checksum: a452e047587b6069332d83130f54d30da4faf2f2ebaa2ce6d073c27b5703d030d58ed9e0b729c8e4e5b52c6f1dab26781bb77b7bc6c7805f14f320e328ff8cd5 - languageName: node - linkType: hard - -"is-interactive@npm:^1.0.0": - version: 1.0.0 - resolution: "is-interactive@npm:1.0.0" - checksum: 824808776e2d468b2916cdd6c16acacebce060d844c35ca6d82267da692e92c3a16fdba624c50b54a63f38bdc4016055b6f443ce57d7147240de4f8cdabaf6f9 - languageName: node - linkType: hard - -"is-lambda@npm:^1.0.1": - version: 1.0.1 - resolution: "is-lambda@npm:1.0.1" - checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 +"is-hexadecimal@npm:^2.0.0": + version: 2.0.1 + resolution: "is-hexadecimal@npm:2.0.1" + checksum: 66a2ea85994c622858f063f23eda506db29d92b52580709eb6f4c19550552d4dcf3fb81952e52f7cf972097237959e00adc7bb8c9400cd12886e15bf06145321 languageName: node linkType: hard -"is-map@npm:^2.0.2, is-map@npm:^2.0.3": +"is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" checksum: e6ce5f6380f32b141b3153e6ba9074892bbbbd655e92e7ba5ff195239777e767a976dcd4e22f864accaf30e53ebf961ab1995424aef91af68788f0591b7396cc @@ -11667,28 +13164,20 @@ __metadata: languageName: node linkType: hard -"is-node-process@npm:^1.0.1": +"is-node-process@npm:^1.2.0": version: 1.2.0 resolution: "is-node-process@npm:1.2.0" checksum: 930765cdc6d81ab8f1bbecbea4a8d35c7c6d88a3ff61f3630e0fc7f22d624d7661c1df05c58547d0eb6a639dfa9304682c8e342c4113a6ed51472b704cee2928 languageName: node linkType: hard -"is-number-object@npm:^1.0.4": - version: 1.0.7 - resolution: "is-number-object@npm:1.0.7" - dependencies: - has-tostringtag: ^1.0.0 - checksum: d1e8d01bb0a7134c74649c4e62da0c6118a0bfc6771ea3c560914d52a627873e6920dd0fd0ebc0e12ad2ff4687eac4c308f7e80320b973b2c8a2c8f97a7524f7 - languageName: node - linkType: hard - -"is-number@npm:^3.0.0": - version: 3.0.0 - resolution: "is-number@npm:3.0.0" +"is-number-object@npm:^1.1.1": + version: 1.1.1 + resolution: "is-number-object@npm:1.1.1" dependencies: - kind-of: ^3.0.2 - checksum: 0c62bf8e9d72c4dd203a74d8cfc751c746e75513380fef420cda8237e619a988ee43e678ddb23c87ac24d91ac0fe9f22e4ffb1301a50310c697e9d73ca3994e9 + call-bound: ^1.0.3 + has-tostringtag: ^1.0.2 + checksum: 6517f0a0e8c4b197a21afb45cd3053dc711e79d45d8878aa3565de38d0102b130ca8732485122c7b336e98c27dacd5236854e3e6526e0eb30cae64956535662f languageName: node linkType: hard @@ -11706,58 +13195,24 @@ __metadata: languageName: node linkType: hard -"is-obj@npm:^2.0.0": - version: 2.0.0 - resolution: "is-obj@npm:2.0.0" - checksum: c9916ac8f4621962a42f5e80e7ffdb1d79a3fab7456ceaeea394cd9e0858d04f985a9ace45be44433bf605673c8be8810540fe4cc7f4266fc7526ced95af5a08 - languageName: node - linkType: hard - -"is-path-cwd@npm:^2.0.0": - version: 2.2.0 - resolution: "is-path-cwd@npm:2.2.0" - checksum: 46a840921bb8cc0dc7b5b423a14220e7db338072a4495743a8230533ce78812dc152548c86f4b828411fe98c5451959f07cf841c6a19f611e46600bd699e8048 - languageName: node - linkType: hard - -"is-path-in-cwd@npm:^2.0.0": - version: 2.1.0 - resolution: "is-path-in-cwd@npm:2.1.0" - dependencies: - is-path-inside: ^2.1.0 - checksum: 6b01b3f8c9172e9682ea878d001836a0cc5a78cbe6236024365d478c2c9e384da2417e5f21f2ad2da2761d0465309fc5baf6e71187d2a23f0058da69790f7f48 - languageName: node - linkType: hard - -"is-path-inside@npm:^2.1.0": - version: 2.1.0 - resolution: "is-path-inside@npm:2.1.0" - dependencies: - path-is-inside: ^1.0.2 - checksum: 6ca34dbd84d5c50a3ee1547afb6ada9b06d556a4ff42da9b303797e4acc3ac086516a4833030aa570f397f8c58dacabd57ee8e6c2ce8b2396a986ad2af10fcaf - languageName: node - linkType: hard - -"is-plain-obj@npm:^1.0.0": - version: 1.1.0 - resolution: "is-plain-obj@npm:1.1.0" - checksum: 0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 +"is-path-inside@npm:^3.0.3": + version: 3.0.3 + resolution: "is-path-inside@npm:3.0.3" + checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 languageName: node linkType: hard -"is-plain-obj@npm:^2.0.0": - version: 2.1.0 - resolution: "is-plain-obj@npm:2.1.0" - checksum: cec9100678b0a9fe0248a81743041ed990c2d4c99f893d935545cfbc42876cbe86d207f3b895700c690ad2fa520e568c44afc1605044b535a7820c1d40e38daa +"is-plain-obj@npm:^3.0.0": + version: 3.0.0 + resolution: "is-plain-obj@npm:3.0.0" + checksum: a6ebdf8e12ab73f33530641972a72a4b8aed6df04f762070d823808303e4f76d87d5ea5bd76f96a7bbe83d93f04ac7764429c29413bd9049853a69cb630fb21c languageName: node linkType: hard -"is-plain-object@npm:^2.0.3, is-plain-object@npm:^2.0.4": - version: 2.0.4 - resolution: "is-plain-object@npm:2.0.4" - dependencies: - isobject: ^3.0.1 - checksum: 2a401140cfd86cabe25214956ae2cfee6fbd8186809555cd0e84574f88de7b17abacb2e477a6a658fa54c6083ecbda1e6ae404c7720244cd198903848fca70ca +"is-plain-obj@npm:^4.0.0": + version: 4.1.0 + resolution: "is-plain-obj@npm:4.1.0" + checksum: 6dc45da70d04a81f35c9310971e78a6a3c7a63547ef782e3a07ee3674695081b6ca4e977fbb8efc48dae3375e0b34558d2bcd722aec9bddfa2d7db5b041be8ce languageName: node linkType: hard @@ -11768,13 +13223,22 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.1.4": - version: 1.1.4 - resolution: "is-regex@npm:1.1.4" +"is-promise@npm:^4.0.0": + version: 4.0.0 + resolution: "is-promise@npm:4.0.0" + checksum: 0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a + languageName: node + linkType: hard + +"is-regex@npm:^1.2.1": + version: 1.2.1 + resolution: "is-regex@npm:1.2.1" dependencies: - call-bind: ^1.0.2 - has-tostringtag: ^1.0.0 - checksum: 362399b33535bc8f386d96c45c9feb04cf7f8b41c182f54174c1a45c9abbbe5e31290bbad09a458583ff6bf3b2048672cdb1881b13289569a7c548370856a652 + call-bound: ^1.0.2 + gopd: ^1.2.0 + has-tostringtag: ^1.0.2 + hasown: ^2.0.2 + checksum: 99ee0b6d30ef1bb61fa4b22fae7056c6c9b3c693803c0c284ff7a8570f83075a7d38cda53b06b7996d441215c27895ea5d1af62124562e13d91b3dbec41a5e13 languageName: node linkType: hard @@ -11785,74 +13249,63 @@ __metadata: languageName: node linkType: hard -"is-resolvable@npm:^1.0.0": - version: 1.1.0 - resolution: "is-resolvable@npm:1.1.0" - checksum: 2ddff983be0cabc2c8d60246365755f8fb322f5fb9db834740d3e694c635c1b74c1bd674cf221e072fc4bd911ef3f08f2247d390e476f7e80af9092443193c68 - languageName: node - linkType: hard - -"is-root@npm:2.1.0": +"is-root@npm:^2.1.0": version: 2.1.0 resolution: "is-root@npm:2.1.0" checksum: 37eea0822a2a9123feb58a9d101558ba276771a6d830f87005683349a9acff15958a9ca590a44e778c6b335660b83e85c744789080d734f6081a935a4880aee2 languageName: node linkType: hard -"is-set@npm:^2.0.2, is-set@npm:^2.0.3": +"is-set@npm:^2.0.3": version: 2.0.3 resolution: "is-set@npm:2.0.3" checksum: 36e3f8c44bdbe9496c9689762cc4110f6a6a12b767c5d74c0398176aa2678d4467e3bf07595556f2dba897751bde1422480212b97d973c7b08a343100b0c0dfe languageName: node linkType: hard -"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": - version: 1.0.3 - resolution: "is-shared-array-buffer@npm:1.0.3" +"is-shared-array-buffer@npm:^1.0.4": + version: 1.0.4 + resolution: "is-shared-array-buffer@npm:1.0.4" dependencies: - call-bind: ^1.0.7 - checksum: a4fff602c309e64ccaa83b859255a43bb011145a42d3f56f67d9268b55bc7e6d98a5981a1d834186ad3105d6739d21547083fe7259c76c0468483fc538e716d8 - languageName: node - linkType: hard - -"is-stream@npm:^1.1.0": - version: 1.1.0 - resolution: "is-stream@npm:1.1.0" - checksum: 063c6bec9d5647aa6d42108d4c59723d2bd4ae42135a2d4db6eadbd49b7ea05b750fd69d279e5c7c45cf9da753ad2c00d8978be354d65aa9f6bb434969c6a2ae + call-bound: ^1.0.3 + checksum: 1611fedc175796eebb88f4dfc393dd969a4a8e6c69cadaff424ee9d4464f9f026399a5f84a90f7c62d6d7ee04e3626a912149726de102b0bd6c1ee6a9868fa5a languageName: node linkType: hard -"is-stream@npm:^2.0.0": +"is-stream@npm:^2, is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 languageName: node linkType: hard -"is-string@npm:^1.0.5, is-string@npm:^1.0.7": - version: 1.0.7 - resolution: "is-string@npm:1.0.7" +"is-string@npm:^1.1.1": + version: 1.1.1 + resolution: "is-string@npm:1.1.1" dependencies: - has-tostringtag: ^1.0.0 - checksum: 323b3d04622f78d45077cf89aab783b2f49d24dc641aa89b5ad1a72114cfeff2585efc8c12ef42466dff32bde93d839ad321b26884cf75e5a7892a938b089989 + call-bound: ^1.0.3 + has-tostringtag: ^1.0.2 + checksum: 2eeaaff605250f5e836ea3500d33d1a5d3aa98d008641d9d42fb941e929ffd25972326c2ef912987e54c95b6f10416281aaf1b35cdf81992cfb7524c5de8e193 languageName: node linkType: hard -"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": - version: 1.0.4 - resolution: "is-symbol@npm:1.0.4" +"is-symbol@npm:^1.0.4, is-symbol@npm:^1.1.1": + version: 1.1.1 + resolution: "is-symbol@npm:1.1.1" dependencies: - has-symbols: ^1.0.2 - checksum: 92805812ef590738d9de49d677cd17dfd486794773fb6fa0032d16452af46e9b91bb43ffe82c983570f015b37136f4b53b28b8523bfb10b0ece7a66c31a54510 + call-bound: ^1.0.2 + has-symbols: ^1.1.0 + safe-regex-test: ^1.1.0 + checksum: bfafacf037af6f3c9d68820b74be4ae8a736a658a3344072df9642a090016e281797ba8edbeb1c83425879aae55d1cb1f30b38bf132d703692b2570367358032 languageName: node linkType: hard -"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.3": - version: 1.1.13 - resolution: "is-typed-array@npm:1.1.13" +"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15": + version: 1.1.15 + resolution: "is-typed-array@npm:1.1.15" dependencies: - which-typed-array: ^1.1.14 - checksum: 150f9ada183a61554c91e1c4290086d2c100b0dff45f60b028519be72a8db964da403c48760723bf5253979b8dffe7b544246e0e5351dcd05c5fdb1dcc1dc0f0 + which-typed-array: ^1.1.16 + checksum: ea7cfc46c282f805d19a9ab2084fd4542fed99219ee9dbfbc26284728bd713a51eac66daa74eca00ae0a43b61322920ba334793607dc39907465913e921e0892 languageName: node linkType: hard @@ -11863,13 +13316,6 @@ __metadata: languageName: node linkType: hard -"is-unicode-supported@npm:^0.1.0": - version: 0.1.0 - resolution: "is-unicode-supported@npm:0.1.0" - checksum: a2aab86ee7712f5c2f999180daaba5f361bdad1efadc9610ff5b8ab5495b86e4f627839d085c6530363c6d6d4ecbde340fb8e54bdb83da4ba8e0865ed5513c52 - languageName: node - linkType: hard - "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -11877,40 +13323,26 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2": - version: 1.0.2 - resolution: "is-weakref@npm:1.0.2" +"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1": + version: 1.1.1 + resolution: "is-weakref@npm:1.1.1" dependencies: - call-bind: ^1.0.2 - checksum: 95bd9a57cdcb58c63b1c401c60a474b0f45b94719c30f548c891860f051bc2231575c290a6b420c6bc6e7ed99459d424c652bd5bf9a1d5259505dc35b4bf83de + call-bound: ^1.0.3 + checksum: 1769b9aed5d435a3a989ffc18fc4ad1947d2acdaf530eb2bd6af844861b545047ea51102f75901f89043bed0267ed61d914ee21e6e8b9aa734ec201cdfc0726f languageName: node linkType: hard "is-weakset@npm:^2.0.3": - version: 2.0.3 - resolution: "is-weakset@npm:2.0.3" + version: 2.0.4 + resolution: "is-weakset@npm:2.0.4" dependencies: - call-bind: ^1.0.7 - get-intrinsic: ^1.2.4 - checksum: 8b6a20ee9f844613ff8f10962cfee49d981d584525f2357fee0a04dfbcde9fd607ed60cb6dab626dbcc470018ae6392e1ff74c0c1aced2d487271411ad9d85ae - languageName: node - linkType: hard - -"is-windows@npm:^1.0.2": - version: 1.0.2 - resolution: "is-windows@npm:1.0.2" - checksum: 438b7e52656fe3b9b293b180defb4e448088e7023a523ec21a91a80b9ff8cdb3377ddb5b6e60f7c7de4fa8b63ab56e121b6705fe081b3cf1b828b0a380009ad7 - languageName: node - linkType: hard - -"is-wsl@npm:^1.1.0": - version: 1.1.0 - resolution: "is-wsl@npm:1.1.0" - checksum: ea157d232351e68c92bd62fc541771096942fe72f69dff452dd26dcc31466258c570a3b04b8cda2e01cd2968255b02951b8670d08ea4ed76d6b1a646061ac4fe + call-bound: ^1.0.3 + get-intrinsic: ^1.2.6 + checksum: 5c6c8415a06065d78bdd5e3a771483aa1cd928df19138aa73c4c51333226f203f22117b4325df55cc8b3085a6716870a320c2d757efee92d7a7091a039082041 languageName: node linkType: hard -"is-wsl@npm:^2.1.1, is-wsl@npm:^2.2.0": +"is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" dependencies: @@ -11926,13 +13358,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:1.0.0, isarray@npm:^1.0.0, isarray@npm:~1.0.0": - version: 1.0.0 - resolution: "isarray@npm:1.0.0" - checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab - languageName: node - linkType: hard - "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -11940,6 +13365,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -11954,22 +13386,6 @@ __metadata: languageName: node linkType: hard -"isobject@npm:^2.0.0": - version: 2.1.0 - resolution: "isobject@npm:2.1.0" - dependencies: - isarray: 1.0.0 - checksum: 811c6f5a866877d31f0606a88af4a45f282544de886bf29f6a34c46616a1ae2ed17076cc6bf34c0128f33eecf7e1fcaa2c82cf3770560d3e26810894e96ae79f - languageName: node - linkType: hard - -"isobject@npm:^3.0.0, isobject@npm:^3.0.1": - version: 3.0.1 - resolution: "isobject@npm:3.0.1" - checksum: db85c4c970ce30693676487cca0e61da2ca34e8d4967c2e1309143ff910c207133a969f9e4ddb2dc6aba670aabce4e0e307146c310350b298e74a31f7d464703 - languageName: node - linkType: hard - "istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": version: 3.2.2 resolution: "istanbul-lib-coverage@npm:3.2.2" @@ -11977,19 +13393,7 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-instrument@npm:^4.0.3": - version: 4.0.3 - resolution: "istanbul-lib-instrument@npm:4.0.3" - dependencies: - "@babel/core": ^7.7.5 - "@istanbuljs/schema": ^0.1.2 - istanbul-lib-coverage: ^3.0.0 - semver: ^6.3.0 - checksum: fa1171d3022b1bb8f6a734042620ac5d9ee7dc80f3065a0bb12863e9f0494d0eefa3d86608fcc0254ab2765d29d7dad8bdc42e5f8df2f9a1fbe85ccc59d76cb9 - languageName: node - linkType: hard - -"istanbul-lib-instrument@npm:^5.0.4": +"istanbul-lib-instrument@npm:^5.0.4, istanbul-lib-instrument@npm:^5.1.0": version: 5.2.1 resolution: "istanbul-lib-instrument@npm:5.2.1" dependencies: @@ -12024,157 +13428,176 @@ __metadata: languageName: node linkType: hard -"istanbul-reports@npm:^3.0.2": - version: 3.1.7 - resolution: "istanbul-reports@npm:3.1.7" +"istanbul-reports@npm:^3.1.3": + version: 3.2.0 + resolution: "istanbul-reports@npm:3.2.0" dependencies: html-escaper: ^2.0.0 istanbul-lib-report: ^3.0.0 - checksum: 2072db6e07bfbb4d0eb30e2700250636182398c1af811aea5032acb219d2080f7586923c09fa194029efd6b92361afb3dcbe1ebcc3ee6651d13340f7c6c4ed95 + checksum: 72b4c8525276147908d28b0917bc675b1019836b638e50875521ca3b8ec63672681aa98dbab88a6f49ef798c08fe041d428abdcf84f4f3fcff5844eee54af65a languageName: node linkType: hard -"iterator.prototype@npm:^1.1.2": - version: 1.1.2 - resolution: "iterator.prototype@npm:1.1.2" +"iterator.prototype@npm:^1.1.4": + version: 1.1.5 + resolution: "iterator.prototype@npm:1.1.5" dependencies: - define-properties: ^1.2.1 - get-intrinsic: ^1.2.1 - has-symbols: ^1.0.3 - reflect.getprototypeof: ^1.0.4 - set-function-name: ^2.0.1 - checksum: d8a507e2ccdc2ce762e8a1d3f4438c5669160ac72b88b648e59a688eec6bc4e64b22338e74000518418d9e693faf2a092d2af21b9ec7dbf7763b037a54701168 + define-data-property: ^1.1.4 + es-object-atoms: ^1.0.0 + get-intrinsic: ^1.2.6 + get-proto: ^1.0.0 + has-symbols: ^1.1.0 + set-function-name: ^2.0.2 + checksum: 7db23c42629ba4790e6e15f78b555f41dbd08818c85af306988364bd19d86716a1187cb333444f3a0036bfc078a0e9cb7ec67fef3a61662736d16410d7f77869 languageName: node linkType: hard -"jackspeak@npm:^2.3.6": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" dependencies: "@isaacs/cliui": ^8.0.2 "@pkgjs/parseargs": ^0.11.0 dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 57d43ad11eadc98cdfe7496612f6bbb5255ea69fe51ea431162db302c2a11011642f50cfad57288bd0aea78384a0612b16e131944ad8ecd09d619041c8531b54 + checksum: be31027fc72e7cc726206b9f560395604b82e0fddb46c4cbf9f97d049bcef607491a5afc0699612eaa4213ca5be8fd3e1e7cd187b3040988b65c9489838a7c00 languageName: node linkType: hard -"jest-changed-files@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-changed-files@npm:26.6.2" +"jackspeak@npm:^4.1.1": + version: 4.1.1 + resolution: "jackspeak@npm:4.1.1" dependencies: - "@jest/types": ^26.6.2 - execa: ^4.0.0 - throat: ^5.0.0 - checksum: 8c405f5ff905ee69ace9fd39355233206e3e233badf6a3f3b27e45bbf0a46d86943430be2e080d25b1e085f4231b9b3b27c94317aa04116efb40b592184066f4 + "@isaacs/cliui": ^8.0.2 + checksum: daca714c5adebfb80932c0b0334025307b68602765098d73d52ec546bc4defdb083292893384261c052742255d0a77d8fcf96f4c669bcb4a99b498b94a74955e languageName: node linkType: hard -"jest-circus@npm:26.6.0": - version: 26.6.0 - resolution: "jest-circus@npm:26.6.0" +"jake@npm:^10.8.5": + version: 10.9.4 + resolution: "jake@npm:10.9.4" dependencies: - "@babel/traverse": ^7.1.0 - "@jest/environment": ^26.6.0 - "@jest/test-result": ^26.6.0 - "@jest/types": ^26.6.0 - "@types/babel__traverse": ^7.0.4 + async: ^3.2.6 + filelist: ^1.0.4 + picocolors: ^1.1.1 + bin: + jake: bin/cli.js + checksum: 1ca6f6a6fe1f2385ed32df82fcb71f9c7378f7fb591ed0b183e9d79a1801221cfe96f3dd9174db2d1a9705a13ae659f2af7004ad23645c910121fc7086a137ef + languageName: node + linkType: hard + +"jest-changed-files@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-changed-files@npm:27.5.1" + dependencies: + "@jest/types": ^27.5.1 + execa: ^5.0.0 + throat: ^6.0.1 + checksum: 95e9dc74c3ca688ef85cfeab270f43f8902721a6c8ade6ac2459459a77890c85977f537d6fb809056deaa6d9c3f075fa7d2699ff5f3bf7d3fda17c3760b79b15 + languageName: node + linkType: hard + +"jest-circus@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-circus@npm:27.5.1" + dependencies: + "@jest/environment": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 dedent: ^0.7.0 - expect: ^26.6.0 + expect: ^27.5.1 is-generator-fn: ^2.0.0 - jest-each: ^26.6.0 - jest-matcher-utils: ^26.6.0 - jest-message-util: ^26.6.0 - jest-runner: ^26.6.0 - jest-runtime: ^26.6.0 - jest-snapshot: ^26.6.0 - jest-util: ^26.6.0 - pretty-format: ^26.6.0 - stack-utils: ^2.0.2 - throat: ^5.0.0 - checksum: acc354223964bafd40fd1caae4099b58ccb1551bc93a394398b441274c225552f1941ce9903d126fb0adc3952a108e2994270c6a50a3e7e5af931b65b8c170f0 - languageName: node - linkType: hard - -"jest-cli@npm:^26.6.0": - version: 26.6.3 - resolution: "jest-cli@npm:26.6.3" - dependencies: - "@jest/core": ^26.6.3 - "@jest/test-result": ^26.6.2 - "@jest/types": ^26.6.2 + jest-each: ^27.5.1 + jest-matcher-utils: ^27.5.1 + jest-message-util: ^27.5.1 + jest-runtime: ^27.5.1 + jest-snapshot: ^27.5.1 + jest-util: ^27.5.1 + pretty-format: ^27.5.1 + slash: ^3.0.0 + stack-utils: ^2.0.3 + throat: ^6.0.1 + checksum: 6192dccbccb3a6acfa361cbb97bdbabe94864ccf3d885932cfd41f19534329d40698078cf9be1489415e8234255d6ea9f9aff5396b79ad842a6fca6e6fc08fd0 + languageName: node + linkType: hard + +"jest-cli@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-cli@npm:27.5.1" + dependencies: + "@jest/core": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/types": ^27.5.1 chalk: ^4.0.0 exit: ^0.1.2 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 import-local: ^3.0.2 - is-ci: ^2.0.0 - jest-config: ^26.6.3 - jest-util: ^26.6.2 - jest-validate: ^26.6.2 + jest-config: ^27.5.1 + jest-util: ^27.5.1 + jest-validate: ^27.5.1 prompts: ^2.0.1 - yargs: ^15.4.1 + yargs: ^16.2.0 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true bin: jest: bin/jest.js - checksum: c8554147be756f09f5566974f0026485f78742e8642d2723f8fbee5746f50f44fb72b17aad181226655a8446d3ecc8ad8ed0a11a8a55686fa2b9c10d85700121 + checksum: 6c0a69fb48e500241409e09ff743ed72bc6578d7769e2c994724e7ef1e5587f6c1f85dc429e93b98ae38a365222993ee70f0acc2199358992120900984f349e5 languageName: node linkType: hard -"jest-config@npm:^26.6.3": - version: 26.6.3 - resolution: "jest-config@npm:26.6.3" +"jest-config@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-config@npm:27.5.1" dependencies: - "@babel/core": ^7.1.0 - "@jest/test-sequencer": ^26.6.3 - "@jest/types": ^26.6.2 - babel-jest: ^26.6.3 + "@babel/core": ^7.8.0 + "@jest/test-sequencer": ^27.5.1 + "@jest/types": ^27.5.1 + babel-jest: ^27.5.1 chalk: ^4.0.0 + ci-info: ^3.2.0 deepmerge: ^4.2.2 glob: ^7.1.1 - graceful-fs: ^4.2.4 - jest-environment-jsdom: ^26.6.2 - jest-environment-node: ^26.6.2 - jest-get-type: ^26.3.0 - jest-jasmine2: ^26.6.3 - jest-regex-util: ^26.0.0 - jest-resolve: ^26.6.2 - jest-util: ^26.6.2 - jest-validate: ^26.6.2 - micromatch: ^4.0.2 - pretty-format: ^26.6.2 + graceful-fs: ^4.2.9 + jest-circus: ^27.5.1 + jest-environment-jsdom: ^27.5.1 + jest-environment-node: ^27.5.1 + jest-get-type: ^27.5.1 + jest-jasmine2: ^27.5.1 + jest-regex-util: ^27.5.1 + jest-resolve: ^27.5.1 + jest-runner: ^27.5.1 + jest-util: ^27.5.1 + jest-validate: ^27.5.1 + micromatch: ^4.0.4 + parse-json: ^5.2.0 + pretty-format: ^27.5.1 + slash: ^3.0.0 + strip-json-comments: ^3.1.1 peerDependencies: ts-node: ">=9.0.0" peerDependenciesMeta: ts-node: optional: true - checksum: 303c798582d3c5d4b4e6ab8a4d91a83ded28e4ebbc0bcfc1ad271f9864437ef5409b7c7773010143811bc8176b0695c096717b91419c6484b56dcc032560a74b - languageName: node - linkType: hard - -"jest-diff@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-diff@npm:26.6.2" - dependencies: - chalk: ^4.0.0 - diff-sequences: ^26.6.2 - jest-get-type: ^26.3.0 - pretty-format: ^26.6.2 - checksum: d00d297f31e1ac0252127089892432caa7a11c69bde29cf3bb6c7a839c8afdb95cf1fd401f9df16a4422745da2e6a5d94b428b30666a2540c38e1c5699915c2d + checksum: 1188fd46c0ed78cbe3175eb9ad6712ccf74a74be33d9f0d748e147c107f0889f8b701fbff1567f31836ae18597dacdc43d6a8fc30dd34ade6c9229cc6c7cb82d languageName: node linkType: hard -"jest-diff@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-diff@npm:28.1.3" +"jest-diff@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-diff@npm:27.5.1" dependencies: chalk: ^4.0.0 - diff-sequences: ^28.1.1 - jest-get-type: ^28.0.2 - pretty-format: ^28.1.3 - checksum: fa8583e0ccbe775714ce850b009be1b0f6b17a4b6759f33ff47adef27942ebc610dbbcc8a5f7cfb7f12b3b3b05afc9fb41d5f766674616025032ff1e4f9866e0 + diff-sequences: ^27.5.1 + jest-get-type: ^27.5.1 + pretty-format: ^27.5.1 + checksum: 8be27c1e1ee57b2bb2bef9c0b233c19621b4c43d53a3c26e2c00a4e805eb4ea11fe1694a06a9fb0e80ffdcfdc0d2b1cb0b85920b3f5c892327ecd1e7bd96b865 languageName: node linkType: hard @@ -12190,75 +13613,68 @@ __metadata: languageName: node linkType: hard -"jest-docblock@npm:^26.0.0": - version: 26.0.0 - resolution: "jest-docblock@npm:26.0.0" +"jest-docblock@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-docblock@npm:27.5.1" dependencies: detect-newline: ^3.0.0 - checksum: e03ef104ee8c571335e6fa394b8fc8d2bd87eec9fe8b3d7d9aac056ada7de288f37ee8ac4922bb3a4222ac304db975d8832d5abc85486092866c534a16847cd5 + checksum: c0fed6d55b229d8bffdd8d03f121dd1a3be77c88f50552d374f9e1ea3bde57bf6bea017a0add04628d98abcb1bfb48b456438eeca8a74ef0053f4dae3b95d29c languageName: node linkType: hard -"jest-each@npm:^26.6.0, jest-each@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-each@npm:26.6.2" +"jest-each@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-each@npm:27.5.1" dependencies: - "@jest/types": ^26.6.2 + "@jest/types": ^27.5.1 chalk: ^4.0.0 - jest-get-type: ^26.3.0 - jest-util: ^26.6.2 - pretty-format: ^26.6.2 - checksum: 4e00ea4667e4fe015b894dc698cce0ae695cf458e021e5da62d4a5b052cd2c0a878da93f8c97cbdde60bcecf70982e8d3a7a5d63e1588f59531cc797a18c39ef + jest-get-type: ^27.5.1 + jest-util: ^27.5.1 + pretty-format: ^27.5.1 + checksum: b5a6d8730fd938982569c9e0b42bdf3c242f97b957ed8155a6473b5f7b540970f8685524e7f53963dc1805319f4b6602abfc56605590ca19d55bd7a87e467e63 languageName: node linkType: hard -"jest-environment-jsdom@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-environment-jsdom@npm:26.6.2" +"jest-environment-jsdom@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-environment-jsdom@npm:27.5.1" dependencies: - "@jest/environment": ^26.6.2 - "@jest/fake-timers": ^26.6.2 - "@jest/types": ^26.6.2 + "@jest/environment": ^27.5.1 + "@jest/fake-timers": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" - jest-mock: ^26.6.2 - jest-util: ^26.6.2 - jsdom: ^16.4.0 - checksum: 8af9ffdf1b147362a19032bfe9ed51b709d43c74dc4b1c45e56d721808bf6cabdca8c226855b55a985ea196ce51cdb171bfe420ceec3daa2d13818d5c1915890 + jest-mock: ^27.5.1 + jest-util: ^27.5.1 + jsdom: ^16.6.0 + checksum: bc104aef7d7530d0740402aa84ac812138b6d1e51fe58adecce679f82b99340ddab73e5ec68fa079f33f50c9ddec9728fc9f0ddcca2ad6f0b351eed2762cc555 languageName: node linkType: hard -"jest-environment-node@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-environment-node@npm:26.6.2" +"jest-environment-node@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-environment-node@npm:27.5.1" dependencies: - "@jest/environment": ^26.6.2 - "@jest/fake-timers": ^26.6.2 - "@jest/types": ^26.6.2 + "@jest/environment": ^27.5.1 + "@jest/fake-timers": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" - jest-mock: ^26.6.2 - jest-util: ^26.6.2 - checksum: 0b69b481e6d6f2350ed241c2dabc70b0b1f3a00f9a410b7dad97c8ab38e88026acf7445ca663eb314f46ff50acee0133100b1006bf4ebda5298ffb02763a6861 + jest-mock: ^27.5.1 + jest-util: ^27.5.1 + checksum: 0f988330c4f3eec092e3fb37ea753b0c6f702e83cd8f4d770af9c2bf964a70bc45fbd34ec6fdb6d71ce98a778d9f54afd673e63f222e4667fff289e8069dba39 languageName: node linkType: hard "jest-fail-on-console@npm:^3.0.2": - version: 3.2.0 - resolution: "jest-fail-on-console@npm:3.2.0" - checksum: 389aa581484825a285fc27f959369a674d4a81ede7474218a27d3596cfc8ed6ea13a0f99053e5d08d7fa43b68246ab8ff51592a70fdb9b4e2b355ca9a165221a - languageName: node - linkType: hard - -"jest-get-type@npm:^26.3.0": - version: 26.3.0 - resolution: "jest-get-type@npm:26.3.0" - checksum: 1cc6465ae4f5e880be22ba52fd270fa64c21994915f81b41f8f7553a7957dd8e077cc8d03035de9412e2d739f8bad6a032ebb5dab5805692a5fb9e20dd4ea666 + version: 3.3.1 + resolution: "jest-fail-on-console@npm:3.3.1" + checksum: ca83aaf623e3772ec612e639fefca54472d38a7f4ea8119de8f12dcdb5e425e9f09d803ffd3b7db7b78fdc4edcffea3340f1ea7d160007da32f03d6ec569686b languageName: node linkType: hard -"jest-get-type@npm:^28.0.2": - version: 28.0.2 - resolution: "jest-get-type@npm:28.0.2" - checksum: 5281d7c89bc8156605f6d15784f45074f4548501195c26e9b188742768f72d40948252d13230ea905b5349038865a1a8eeff0e614cc530ff289dfc41fe843abd +"jest-get-type@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-get-type@npm:27.5.1" + checksum: 63064ab70195c21007d897c1157bf88ff94a790824a10f8c890392e7d17eda9c3900513cb291ca1c8d5722cad79169764e9a1279f7c8a9c4cd6e9109ff04bbc0 languageName: node linkType: hard @@ -12269,88 +13685,74 @@ __metadata: languageName: node linkType: hard -"jest-haste-map@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-haste-map@npm:26.6.2" +"jest-haste-map@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-haste-map@npm:27.5.1" dependencies: - "@jest/types": ^26.6.2 + "@jest/types": ^27.5.1 "@types/graceful-fs": ^4.1.2 "@types/node": "*" anymatch: ^3.0.3 fb-watchman: ^2.0.0 - fsevents: ^2.1.2 - graceful-fs: ^4.2.4 - jest-regex-util: ^26.0.0 - jest-serializer: ^26.6.2 - jest-util: ^26.6.2 - jest-worker: ^26.6.2 - micromatch: ^4.0.2 - sane: ^4.0.3 + fsevents: ^2.3.2 + graceful-fs: ^4.2.9 + jest-regex-util: ^27.5.1 + jest-serializer: ^27.5.1 + jest-util: ^27.5.1 + jest-worker: ^27.5.1 + micromatch: ^4.0.4 walker: ^1.0.7 dependenciesMeta: fsevents: optional: true - checksum: 8ad5236d5646d2388d2bd58a57ea53698923434f43d59ea9ebdc58bce4d0b8544c8de2f7acaa9a6d73171f04460388b2b6d7d6b6c256aea4ebb8780140781596 + checksum: e092a1412829a9254b4725531ee72926de530f77fda7b0d9ea18008fb7623c16f72e772d8e93be71cac9e591b2c6843a669610887dd2c89bd9eb528856e3ab47 languageName: node linkType: hard -"jest-jasmine2@npm:^26.6.3": - version: 26.6.3 - resolution: "jest-jasmine2@npm:26.6.3" +"jest-jasmine2@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-jasmine2@npm:27.5.1" dependencies: - "@babel/traverse": ^7.1.0 - "@jest/environment": ^26.6.2 - "@jest/source-map": ^26.6.2 - "@jest/test-result": ^26.6.2 - "@jest/types": ^26.6.2 + "@jest/environment": ^27.5.1 + "@jest/source-map": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 - expect: ^26.6.2 + expect: ^27.5.1 is-generator-fn: ^2.0.0 - jest-each: ^26.6.2 - jest-matcher-utils: ^26.6.2 - jest-message-util: ^26.6.2 - jest-runtime: ^26.6.3 - jest-snapshot: ^26.6.2 - jest-util: ^26.6.2 - pretty-format: ^26.6.2 - throat: ^5.0.0 - checksum: 41df0b993ae0cdeb2660fb3d8e88e2dcc83aec6b5c27d85eb233c2d507b546f8dce45fc54898ffbefa48ccc4633f225d0e023fd0979b8f7f2f1626074a69a9a3 - languageName: node - linkType: hard - -"jest-leak-detector@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-leak-detector@npm:26.6.2" - dependencies: - jest-get-type: ^26.3.0 - pretty-format: ^26.6.2 - checksum: 364dd4d021347e26c66ba9c09da8a30477f14a3a8a208d2d7d64e4c396db81b85d8cb6b6834bcfc47a61b5938e274553957d11a7de2255f058c9d55d7f8fdfe7 + jest-each: ^27.5.1 + jest-matcher-utils: ^27.5.1 + jest-message-util: ^27.5.1 + jest-runtime: ^27.5.1 + jest-snapshot: ^27.5.1 + jest-util: ^27.5.1 + pretty-format: ^27.5.1 + throat: ^6.0.1 + checksum: b716adf253ceb73db661936153394ab90d7f3a8ba56d6189b7cd4df8e4e2a4153b4e63ebb5d36e29ceb0f4c211d5a6f36ab7048c6abbd881c8646567e2ab8e6d languageName: node linkType: hard -"jest-matcher-utils@npm:^26.6.0, jest-matcher-utils@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-matcher-utils@npm:26.6.2" +"jest-leak-detector@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-leak-detector@npm:27.5.1" dependencies: - chalk: ^4.0.0 - jest-diff: ^26.6.2 - jest-get-type: ^26.3.0 - pretty-format: ^26.6.2 - checksum: 74d2165c1ac7fe98fe27cd2b5407499478e6b2fe99dd54e26d8ee5c9f5f913bdd7bdc07c7221b9b04df0c15e9be0e866ff3455b03e38cc66c480d9996d6d5405 + jest-get-type: ^27.5.1 + pretty-format: ^27.5.1 + checksum: 5c9689060960567ddaf16c570d87afa760a461885765d2c71ef4f4857bbc3af1482c34e3cce88e50beefde1bf35e33530b020480752057a7e3dbb1ca0bae359f languageName: node linkType: hard -"jest-matcher-utils@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-matcher-utils@npm:28.1.3" +"jest-matcher-utils@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-matcher-utils@npm:27.5.1" dependencies: chalk: ^4.0.0 - jest-diff: ^28.1.3 - jest-get-type: ^28.0.2 - pretty-format: ^28.1.3 - checksum: 6b34f0cf66f6781e92e3bec97bf27796bd2ba31121e5c5997218d9adba6deea38a30df5203937d6785b68023ed95cbad73663cc9aad6fb0cb59aeb5813a58daf + jest-diff: ^27.5.1 + jest-get-type: ^27.5.1 + pretty-format: ^27.5.1 + checksum: bb2135fc48889ff3fe73888f6cc7168ddab9de28b51b3148f820c89fdfd2effdcad005f18be67d0b9be80eda208ad47290f62f03d0a33f848db2dd0273c8217a languageName: node linkType: hard @@ -12366,20 +13768,20 @@ __metadata: languageName: node linkType: hard -"jest-message-util@npm:^26.6.0, jest-message-util@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-message-util@npm:26.6.2" +"jest-message-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-message-util@npm:27.5.1" dependencies: - "@babel/code-frame": ^7.0.0 - "@jest/types": ^26.6.2 + "@babel/code-frame": ^7.12.13 + "@jest/types": ^27.5.1 "@types/stack-utils": ^2.0.0 chalk: ^4.0.0 - graceful-fs: ^4.2.4 - micromatch: ^4.0.2 - pretty-format: ^26.6.2 + graceful-fs: ^4.2.9 + micromatch: ^4.0.4 + pretty-format: ^27.5.1 slash: ^3.0.0 - stack-utils: ^2.0.2 - checksum: ffe5a715591c41240b9ed4092faf10f3eaf9ddfdf25d257a0c9f903aaa8d9eed5baa7e38016d2ec4f610fd29225e0f5231a91153e087a043e62824972c83d015 + stack-utils: ^2.0.3 + checksum: eb6d637d1411c71646de578c49826b6da8e33dd293e501967011de9d1916d53d845afbfb52a5b661ff1c495be7c13f751c48c7f30781fd94fbd64842e8195796 languageName: node linkType: hard @@ -12417,13 +13819,13 @@ __metadata: languageName: node linkType: hard -"jest-mock@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-mock@npm:26.6.2" +"jest-mock@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-mock@npm:27.5.1" dependencies: - "@jest/types": ^26.6.2 + "@jest/types": ^27.5.1 "@types/node": "*" - checksum: 6c0fe028ff0cdc87b5d63b9ca749af04cae6c5577aaab234f602e546cae3f4b932adac9d77e6de2abb24955ee00978e1e5d5a861725654e2f9a42317d91fbc1f + checksum: f5b5904bb1741b4a1687a5f492535b7b1758dc26534c72a5423305f8711292e96a601dec966df81bb313269fb52d47227e29f9c2e08324d79529172f67311be0 languageName: node linkType: hard @@ -12439,166 +13841,159 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^26.0.0": - version: 26.0.0 - resolution: "jest-regex-util@npm:26.0.0" - checksum: 930a00665e8dfbedc29140678b4a54f021b41b895cf35050f76f557c1da3ac48ff42dd7b18ba2ccba6f4e518c6445d6753730d03ec7049901b93992db1ef0483 +"jest-regex-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-regex-util@npm:27.5.1" + checksum: d45ca7a9543616a34f7f3079337439cf07566e677a096472baa2810e274b9808b76767c97b0a4029b8a5b82b9d256dee28ef9ad4138b2b9e5933f6fac106c418 languageName: node linkType: hard -"jest-resolve-dependencies@npm:^26.6.3": - version: 26.6.3 - resolution: "jest-resolve-dependencies@npm:26.6.3" - dependencies: - "@jest/types": ^26.6.2 - jest-regex-util: ^26.0.0 - jest-snapshot: ^26.6.2 - checksum: 533ea1e271426006ff02c03c9802b108fcd68f2144615b6110ae59f3a0a2cc4a7abb3f44c3c65299c76b3a725d5d8220aaed9c58b79c8c8c508c18699a96e3f7 +"jest-regex-util@npm:^28.0.0": + version: 28.0.2 + resolution: "jest-regex-util@npm:28.0.2" + checksum: 0ea8c5c82ec88bc85e273c0ec82e0c0f35f7a1e2d055070e50f0cc2a2177f848eec55f73e37ae0d045c3db5014c42b2f90ac62c1ab3fdb354d2abd66a9e08add languageName: node linkType: hard -"jest-resolve@npm:26.6.0": - version: 26.6.0 - resolution: "jest-resolve@npm:26.6.0" +"jest-resolve-dependencies@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-resolve-dependencies@npm:27.5.1" dependencies: - "@jest/types": ^26.6.0 - chalk: ^4.0.0 - graceful-fs: ^4.2.4 - jest-pnp-resolver: ^1.2.2 - jest-util: ^26.6.0 - read-pkg-up: ^7.0.1 - resolve: ^1.17.0 - slash: ^3.0.0 - checksum: c5d0277d4aa22f9f38693ba3e5d6176edf2e367af2f0c38e16c88e9b80b2292ee4d9df9b3675607f5d0c0b2652b4e3f69d8155f9fedd83ddd0ef937cfb6230c0 + "@jest/types": ^27.5.1 + jest-regex-util: ^27.5.1 + jest-snapshot: ^27.5.1 + checksum: c67af97afad1da88f5530317c732bbd1262d1225f6cd7f4e4740a5db48f90ab0bd8564738ac70d1a43934894f9aef62205c1b8f8ee89e5c7a737e6a121ee4c25 languageName: node linkType: hard -"jest-resolve@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-resolve@npm:26.6.2" +"jest-resolve@npm:^27.4.2, jest-resolve@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-resolve@npm:27.5.1" dependencies: - "@jest/types": ^26.6.2 + "@jest/types": ^27.5.1 chalk: ^4.0.0 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 + jest-haste-map: ^27.5.1 jest-pnp-resolver: ^1.2.2 - jest-util: ^26.6.2 - read-pkg-up: ^7.0.1 - resolve: ^1.18.1 + jest-util: ^27.5.1 + jest-validate: ^27.5.1 + resolve: ^1.20.0 + resolve.exports: ^1.1.0 slash: ^3.0.0 - checksum: d6264d3f39b098753802a237c8c54f3109f5f3b3b7fa6f8d7aec7dca01b357ddf518ce1c33a68454357c15f48fb3c6026a92b9c4f5d72f07e24e80f04bcc8d58 + checksum: 735830e7265b20a348029738680bb2f6e37f80ecea86cda869a4c318ba3a45d39c7a3a873a22f7f746d86258c50ead6e7f501de043e201c095d7ba628a1c440f languageName: node linkType: hard -"jest-runner@npm:^26.6.0, jest-runner@npm:^26.6.3": - version: 26.6.3 - resolution: "jest-runner@npm:26.6.3" +"jest-runner@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-runner@npm:27.5.1" dependencies: - "@jest/console": ^26.6.2 - "@jest/environment": ^26.6.2 - "@jest/test-result": ^26.6.2 - "@jest/types": ^26.6.2 + "@jest/console": ^27.5.1 + "@jest/environment": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 - emittery: ^0.7.1 - exit: ^0.1.2 - graceful-fs: ^4.2.4 - jest-config: ^26.6.3 - jest-docblock: ^26.0.0 - jest-haste-map: ^26.6.2 - jest-leak-detector: ^26.6.2 - jest-message-util: ^26.6.2 - jest-resolve: ^26.6.2 - jest-runtime: ^26.6.3 - jest-util: ^26.6.2 - jest-worker: ^26.6.2 + emittery: ^0.8.1 + graceful-fs: ^4.2.9 + jest-docblock: ^27.5.1 + jest-environment-jsdom: ^27.5.1 + jest-environment-node: ^27.5.1 + jest-haste-map: ^27.5.1 + jest-leak-detector: ^27.5.1 + jest-message-util: ^27.5.1 + jest-resolve: ^27.5.1 + jest-runtime: ^27.5.1 + jest-util: ^27.5.1 + jest-worker: ^27.5.1 source-map-support: ^0.5.6 - throat: ^5.0.0 - checksum: ccd69918baa49a5efa45985cf60cfa1fbb1686b32d7a86296b7b55f89684e36d1f08e62598c4b7be7e81f2cf2e245d1a65146ea7bdcaedfa6ed176d3e645d7e2 + throat: ^6.0.1 + checksum: 5bbe6cf847dd322b3332ec9d6977b54f91bd5f72ff620bc1a0192f0f129deda8aa7ca74c98922187a7aa87d8e0ce4f6c50e99a7ccb2a310bf4d94be2e0c3ce8e languageName: node linkType: hard -"jest-runtime@npm:^26.6.0, jest-runtime@npm:^26.6.3": - version: 26.6.3 - resolution: "jest-runtime@npm:26.6.3" - dependencies: - "@jest/console": ^26.6.2 - "@jest/environment": ^26.6.2 - "@jest/fake-timers": ^26.6.2 - "@jest/globals": ^26.6.2 - "@jest/source-map": ^26.6.2 - "@jest/test-result": ^26.6.2 - "@jest/transform": ^26.6.2 - "@jest/types": ^26.6.2 - "@types/yargs": ^15.0.0 +"jest-runtime@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-runtime@npm:27.5.1" + dependencies: + "@jest/environment": ^27.5.1 + "@jest/fake-timers": ^27.5.1 + "@jest/globals": ^27.5.1 + "@jest/source-map": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 chalk: ^4.0.0 - cjs-module-lexer: ^0.6.0 + cjs-module-lexer: ^1.0.0 collect-v8-coverage: ^1.0.0 - exit: ^0.1.2 + execa: ^5.0.0 glob: ^7.1.3 - graceful-fs: ^4.2.4 - jest-config: ^26.6.3 - jest-haste-map: ^26.6.2 - jest-message-util: ^26.6.2 - jest-mock: ^26.6.2 - jest-regex-util: ^26.0.0 - jest-resolve: ^26.6.2 - jest-snapshot: ^26.6.2 - jest-util: ^26.6.2 - jest-validate: ^26.6.2 + graceful-fs: ^4.2.9 + jest-haste-map: ^27.5.1 + jest-message-util: ^27.5.1 + jest-mock: ^27.5.1 + jest-regex-util: ^27.5.1 + jest-resolve: ^27.5.1 + jest-snapshot: ^27.5.1 + jest-util: ^27.5.1 slash: ^3.0.0 strip-bom: ^4.0.0 - yargs: ^15.4.1 - bin: - jest-runtime: bin/jest-runtime.js - checksum: 867922b49f9ab4cf2f5f1356ac3d9962c4477c7a2ff696cc841ea4c600ea389e7d6dfcbf945fec6849e606f81980addf31e4f34d63eaa3d3415f4901de2f605a + checksum: 929e3df0c53dab43f831f2af4e2996b22aa8cb2d6d483919d6b0426cbc100098fd5b777b998c6568b77f8c4d860b2e83127514292ff61416064f5ef926492386 languageName: node linkType: hard -"jest-serializer@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-serializer@npm:26.6.2" +"jest-serializer@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-serializer@npm:27.5.1" dependencies: "@types/node": "*" - graceful-fs: ^4.2.4 - checksum: dbecfb0d01462fe486a0932cf1680cf6abb204c059db2a8f72c6c2a7c9842a82f6d256874112774cea700764ed8f38fc9e3db982456c138d87353e3390e746fe + graceful-fs: ^4.2.9 + checksum: 803e03a552278610edc6753c0dd9fa5bb5cd3ca47414a7b2918106efb62b79fd5e9ae785d0a21f12a299fa599fea8acc1fa6dd41283328cee43962cf7df9bb44 languageName: node linkType: hard -"jest-snapshot@npm:^26.6.0, jest-snapshot@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-snapshot@npm:26.6.2" +"jest-snapshot@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-snapshot@npm:27.5.1" dependencies: + "@babel/core": ^7.7.2 + "@babel/generator": ^7.7.2 + "@babel/plugin-syntax-typescript": ^7.7.2 + "@babel/traverse": ^7.7.2 "@babel/types": ^7.0.0 - "@jest/types": ^26.6.2 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 "@types/babel__traverse": ^7.0.4 - "@types/prettier": ^2.0.0 + "@types/prettier": ^2.1.5 + babel-preset-current-node-syntax: ^1.0.0 chalk: ^4.0.0 - expect: ^26.6.2 - graceful-fs: ^4.2.4 - jest-diff: ^26.6.2 - jest-get-type: ^26.3.0 - jest-haste-map: ^26.6.2 - jest-matcher-utils: ^26.6.2 - jest-message-util: ^26.6.2 - jest-resolve: ^26.6.2 + expect: ^27.5.1 + graceful-fs: ^4.2.9 + jest-diff: ^27.5.1 + jest-get-type: ^27.5.1 + jest-haste-map: ^27.5.1 + jest-matcher-utils: ^27.5.1 + jest-message-util: ^27.5.1 + jest-util: ^27.5.1 natural-compare: ^1.4.0 - pretty-format: ^26.6.2 + pretty-format: ^27.5.1 semver: ^7.3.2 - checksum: 53f1de055b1d3840bc6e851fd674d5991b844d4695dadbd07354c93bf191048d8767b8606999847e97c4214a485b9afb45c1d2411772befa1870414ac973b3e2 + checksum: a5cfadf0d21cd76063925d1434bc076443ed6d87847d0e248f0b245f11db3d98ff13e45cc03b15404027dabecd712d925f47b6eae4f64986f688640a7d362514 languageName: node linkType: hard -"jest-util@npm:^26.1.0, jest-util@npm:^26.6.0, jest-util@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-util@npm:26.6.2" +"jest-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-util@npm:27.5.1" dependencies: - "@jest/types": ^26.6.2 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 - graceful-fs: ^4.2.4 - is-ci: ^2.0.0 - micromatch: ^4.0.2 - checksum: 3c6a5fba05c4c6892cd3a9f66196ea8867087b77a5aa1a3f6cd349c785c3f1ca24abfd454664983aed1a165cab7846688e44fe8630652d666ba326b08625bc3d + ci-info: ^3.2.0 + graceful-fs: ^4.2.9 + picomatch: ^2.2.3 + checksum: ac8d122f6daf7a035dcea156641fd3701aeba245417c40836a77e35b3341b9c02ddc5d904cfcd4ddbaa00ab854da76d3b911870cafdcdbaff90ea471de26c7d7 languageName: node linkType: hard @@ -12630,63 +14025,69 @@ __metadata: languageName: node linkType: hard -"jest-validate@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-validate@npm:26.6.2" +"jest-validate@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-validate@npm:27.5.1" dependencies: - "@jest/types": ^26.6.2 - camelcase: ^6.0.0 + "@jest/types": ^27.5.1 + camelcase: ^6.2.0 chalk: ^4.0.0 - jest-get-type: ^26.3.0 + jest-get-type: ^27.5.1 leven: ^3.1.0 - pretty-format: ^26.6.2 - checksum: bac11d6586d9b8885328a4a66eec45b692e45ac23034a5c09eb0ee32de324f2d3d52b073e0c34e9c222b3642b083d1152a736cf24c52109e4957537d731ca62b + pretty-format: ^27.5.1 + checksum: 82e870f8ee7e4fb949652711b1567f05ae31c54be346b0899e8353e5c20fad7692b511905b37966945e90af8dc0383eb41a74f3ffefb16140ea4f9164d841412 languageName: node linkType: hard -"jest-watch-typeahead@npm:0.6.1": - version: 0.6.1 - resolution: "jest-watch-typeahead@npm:0.6.1" +"jest-watch-typeahead@npm:^1.0.0": + version: 1.1.0 + resolution: "jest-watch-typeahead@npm:1.1.0" dependencies: ansi-escapes: ^4.3.1 chalk: ^4.0.0 - jest-regex-util: ^26.0.0 - jest-watcher: ^26.3.0 - slash: ^3.0.0 - string-length: ^4.0.1 - strip-ansi: ^6.0.0 + jest-regex-util: ^28.0.0 + jest-watcher: ^28.0.0 + slash: ^4.0.0 + string-length: ^5.0.1 + strip-ansi: ^7.0.1 peerDependencies: - jest: ^26.0.0 - checksum: a65dfd080e68b79ce7c861ec07791a0768820049a1d6a471d01f3fc41ee88723db29b434e19c917421e7f34ec567bcade368f3671e234c557288e206f7fd4257 + jest: ^27.0.0 || ^28.0.0 + checksum: 59b0a494ac01e3801c9ec586de3209153eedb024b981e25443111c5703711d23b67ebc71b072986c1758307e0bfb5bf1c92bd323f73f58602d6f4f609dce6a0c languageName: node linkType: hard -"jest-watcher@npm:^26.3.0, jest-watcher@npm:^26.6.2": - version: 26.6.2 - resolution: "jest-watcher@npm:26.6.2" +"jest-watcher@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-watcher@npm:27.5.1" dependencies: - "@jest/test-result": ^26.6.2 - "@jest/types": ^26.6.2 + "@jest/test-result": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" ansi-escapes: ^4.2.1 chalk: ^4.0.0 - jest-util: ^26.6.2 + jest-util: ^27.5.1 string-length: ^4.0.1 - checksum: 401137f1a73bf23cdf390019ebffb3f6f89c53ca49d48252d1dd6daf17a68787fef75cc55a623de28b63d87d0e8f13d8972d7dd06740f2f64f7b2a0409d119d2 + checksum: 191c4e9c278c0902ade1a8a80883ac244963ba3e6e78607a3d5f729ccca9c6e71fb3b316f87883658132641c5d818aa84202585c76752e03c539e6cbecb820bd languageName: node linkType: hard -"jest-worker@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-worker@npm:24.9.0" +"jest-watcher@npm:^28.0.0": + version: 28.1.3 + resolution: "jest-watcher@npm:28.1.3" dependencies: - merge-stream: ^2.0.0 - supports-color: ^6.1.0 - checksum: bd23b6c8728dcf3bad0d84543ea1bc4a95ccd3b5a40f9e2796d527ab0e87dc6afa6c30cc7b67845dce1cfe7894753812d19793de605db1976b7ac08930671bff + "@jest/test-result": ^28.1.3 + "@jest/types": ^28.1.3 + "@types/node": "*" + ansi-escapes: ^4.2.1 + chalk: ^4.0.0 + emittery: ^0.10.2 + jest-util: ^28.1.3 + string-length: ^4.0.1 + checksum: 8f6d674a4865e7df251f71544f1b51f06fd36b5a3a61f2ac81aeb81fa2a196be354fba51d0f97911c88f67cd254583b3a22ee124bf2c5b6ee2fadec27356c207 languageName: node linkType: hard -"jest-worker@npm:^26.5.0, jest-worker@npm:^26.6.2": +"jest-worker@npm:^26.2.1": version: 26.6.2 resolution: "jest-worker@npm:26.6.2" dependencies: @@ -12697,7 +14098,7 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^27.5.1": +"jest-worker@npm:^27.0.2, jest-worker@npm:^27.4.5, jest-worker@npm:^27.5.1": version: 27.5.1 resolution: "jest-worker@npm:27.5.1" dependencies: @@ -12708,16 +14109,41 @@ __metadata: languageName: node linkType: hard -"jest@npm:26.6.0": - version: 26.6.0 - resolution: "jest@npm:26.6.0" - dependencies: - "@jest/core": ^26.6.0 - import-local: ^3.0.2 - jest-cli: ^26.6.0 +"jest-worker@npm:^28.0.2": + version: 28.1.3 + resolution: "jest-worker@npm:28.1.3" + dependencies: + "@types/node": "*" + merge-stream: ^2.0.0 + supports-color: ^8.0.0 + checksum: e921c9a1b8f0909da9ea07dbf3592f95b653aef3a8bb0cbcd20fc7f9a795a1304adecac31eecb308992c167e8d7e75c522061fec38a5928ace0f9571c90169ca + languageName: node + linkType: hard + +"jest@npm:^27.4.3": + version: 27.5.1 + resolution: "jest@npm:27.5.1" + dependencies: + "@jest/core": ^27.5.1 + import-local: ^3.0.2 + jest-cli: ^27.5.1 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: bin/jest.js + checksum: 96f1d69042b3c6dfc695f2a4e4b0db38af6fb78582ad1a02beaa57cfcd77cbd31567d7d865c1c85709b7c3e176eefa3b2035ffecd646005f15d8ef528eccf205 + languageName: node + linkType: hard + +"jiti@npm:^1.21.6": + version: 1.21.7 + resolution: "jiti@npm:1.21.7" bin: - jest: bin/jest.js - checksum: e0d3efff0dc2a31c453a3f7d87586e5d6c0f008c9b827bb9204edde09288f922ddfb3a8917480bf68f4ac0298be28637daef98ebaaac65ea23d3cb754a6620c4 + jiti: bin/jiti.js + checksum: 9cd20dabf82e3a4cceecb746a69381da7acda93d34eed0cdb9c9bdff3bce07e4f2f4a016ca89924392c935297d9aedc58ff9f7d3281bc5293319ad244926e0b7 languageName: node linkType: hard @@ -12728,13 +14154,6 @@ __metadata: languageName: node linkType: hard -"js-levenshtein@npm:^1.1.6": - version: 1.1.6 - resolution: "js-levenshtein@npm:1.1.6" - checksum: 409f052a7f1141be4058d97da7860e08efd97fc588b7a4c5cfa0548bc04f6d576644dae65ab630266dff685d56fb90d494e03d4d79cb484c287746b4f1bf0694 - languageName: node - linkType: hard - "js-sha3@npm:0.8.0": version: 0.8.0 resolution: "js-sha3@npm:0.8.0" @@ -12749,6 +14168,13 @@ __metadata: languageName: node linkType: hard +"js-tokens@npm:^9.0.1": + version: 9.0.1 + resolution: "js-tokens@npm:9.0.1" + checksum: 8b604020b1a550e575404bfdde4d12c11a7991ffe0c58a2cf3515b9a512992dc7010af788f0d8b7485e403d462d9e3d3b96c4ff03201550fdbb09e17c811e054 + languageName: node + linkType: hard + "js-yaml@npm:^3.13.1": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" @@ -12761,14 +14187,18 @@ __metadata: languageName: node linkType: hard -"jsbn@npm:1.1.0": - version: 1.1.0 - resolution: "jsbn@npm:1.1.0" - checksum: 944f924f2bd67ad533b3850eee47603eed0f6ae425fd1ee8c760f477e8c34a05f144c1bd4f5a5dd1963141dc79a2c55f89ccc5ab77d039e7077f3ad196b64965 +"js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: ^2.0.1 + bin: + js-yaml: bin/js-yaml.js + checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a languageName: node linkType: hard -"jsdom@npm:^16.4.0": +"jsdom@npm:^16.6.0": version: 16.7.0 resolution: "jsdom@npm:16.7.0" dependencies: @@ -12808,21 +14238,21 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^2.5.1": - version: 2.5.2 - resolution: "jsesc@npm:2.5.2" +"jsesc@npm:^3.0.2": + version: 3.1.0 + resolution: "jsesc@npm:3.1.0" bin: jsesc: bin/jsesc - checksum: 4dc190771129e12023f729ce20e1e0bfceac84d73a85bc3119f7f938843fe25a4aeccb54b6494dce26fcf263d815f5f31acdefac7cc9329efb8422a4f4d9fa9d + checksum: 19c94095ea026725540c0d29da33ab03144f6bcf2d4159e4833d534976e99e0c09c38cefa9a575279a51fc36b31166f8d6d05c9fe2645d5f15851d690b41f17f languageName: node linkType: hard -"jsesc@npm:~0.5.0": - version: 0.5.0 - resolution: "jsesc@npm:0.5.0" +"jsesc@npm:~3.0.2": + version: 3.0.2 + resolution: "jsesc@npm:3.0.2" bin: jsesc: bin/jsesc - checksum: b8b44cbfc92f198ad972fba706ee6a1dfa7485321ee8c0b25f5cedd538dcb20cde3197de16a7265430fce8277a12db066219369e3d51055038946039f6e20e17 + checksum: a36d3ca40574a974d9c2063bf68c2b6141c20da8f2a36bd3279fc802563f35f0527a6c828801295bdfb2803952cf2cf387786c2c90ed564f88d5782475abfe3c languageName: node linkType: hard @@ -12842,14 +14272,7 @@ __metadata: languageName: node linkType: hard -"json-parse-better-errors@npm:^1.0.1, json-parse-better-errors@npm:^1.0.2": - version: 1.0.2 - resolution: "json-parse-better-errors@npm:1.0.2" - checksum: ff2b5ba2a70e88fd97a3cb28c1840144c5ce8fae9cbeeddba15afa333a5c407cf0e42300cd0a2885dbb055227fe68d405070faad941beeffbfde9cf3b2c78c5d - languageName: node - linkType: hard - -"json-parse-even-better-errors@npm:^2.3.0": +"json-parse-even-better-errors@npm:^2.3.0, json-parse-even-better-errors@npm:^2.3.1": version: 2.3.1 resolution: "json-parse-even-better-errors@npm:2.3.1" checksum: 798ed4cf3354a2d9ccd78e86d2169515a0097a5c133337807cdf7f1fc32e1391d207ccfc276518cc1d7d8d4db93288b8a50ba4293d212ad1336e52a8ec0a941f @@ -12870,6 +14293,13 @@ __metadata: languageName: node linkType: hard +"json-schema@npm:^0.4.0": + version: 0.4.0 + resolution: "json-schema@npm:0.4.0" + checksum: 66389434c3469e698da0df2e7ac5a3281bcff75e797a5c127db7c5b56270e01ae13d9afa3c03344f76e32e81678337a8c912bdbb75101c62e487dc3778461d72 + languageName: node + linkType: hard + "json-stable-stringify-without-jsonify@npm:^1.0.1": version: 1.0.1 resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" @@ -12877,16 +14307,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:2.x, json5@npm:^2.1.2, json5@npm:^2.2.3": - version: 2.2.3 - resolution: "json5@npm:2.2.3" - bin: - json5: lib/cli.js - checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349 - languageName: node - linkType: hard - -"json5@npm:^1.0.1, json5@npm:^1.0.2": +"json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" dependencies: @@ -12897,28 +14318,25 @@ __metadata: languageName: node linkType: hard -"jsonfile@npm:^4.0.0": - version: 4.0.0 - resolution: "jsonfile@npm:4.0.0" - dependencies: - graceful-fs: ^4.1.6 - dependenciesMeta: - graceful-fs: - optional: true - checksum: 6447d6224f0d31623eef9b51185af03ac328a7553efcee30fa423d98a9e276ca08db87d71e17f2310b0263fd3ffa6c2a90a6308367f661dc21580f9469897c9e +"json5@npm:^2.1.2, json5@npm:^2.2.0, json5@npm:^2.2.3": + version: 2.2.3 + resolution: "json5@npm:2.2.3" + bin: + json5: lib/cli.js + checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349 languageName: node linkType: hard "jsonfile@npm:^6.0.1": - version: 6.1.0 - resolution: "jsonfile@npm:6.1.0" + version: 6.2.0 + resolution: "jsonfile@npm:6.2.0" dependencies: graceful-fs: ^4.1.6 universalify: ^2.0.0 dependenciesMeta: graceful-fs: optional: true - checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354 + checksum: c3028ec5c770bb41290c9bb9ca04bdd0a1b698ddbdf6517c9453d3f90fc9e000c9675959fb46891d317690a93c62de03ff1735d8dbe02be83e51168ce85815d3 languageName: node linkType: hard @@ -12933,6 +14351,13 @@ __metadata: languageName: node linkType: hard +"jsonpointer@npm:^5.0.0": + version: 5.0.1 + resolution: "jsonpointer@npm:5.0.1" + checksum: 0b40f712900ad0c846681ea2db23b6684b9d5eedf55807b4708c656f5894b63507d0e28ae10aa1bddbea551241035afe62b6df0800fc94c2e2806a7f3adecd7c + languageName: node + linkType: hard + "jsonwebtoken@npm:^8.5.1": version: 8.5.1 resolution: "jsonwebtoken@npm:8.5.1" @@ -12951,6 +14376,24 @@ __metadata: languageName: node linkType: hard +"jsonwebtoken@npm:^9.0.2": + version: 9.0.2 + resolution: "jsonwebtoken@npm:9.0.2" + dependencies: + jws: ^3.2.2 + lodash.includes: ^4.3.0 + lodash.isboolean: ^3.0.3 + lodash.isinteger: ^4.0.4 + lodash.isnumber: ^3.0.3 + lodash.isplainobject: ^4.0.6 + lodash.isstring: ^4.0.1 + lodash.once: ^4.0.0 + ms: ^2.1.1 + semver: ^7.5.4 + checksum: fc739a6a8b33f1974f9772dca7f8493ca8df4cc31c5a09dcfdb7cff77447dcf22f4236fb2774ef3fe50df0abeb8e1c6f4c41eba82f500a804ab101e2fbc9d61a + languageName: node + linkType: hard + "jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" @@ -12964,24 +14407,24 @@ __metadata: linkType: hard "jwa@npm:^1.4.1": - version: 1.4.1 - resolution: "jwa@npm:1.4.1" + version: 1.4.2 + resolution: "jwa@npm:1.4.2" dependencies: - buffer-equal-constant-time: 1.0.1 + buffer-equal-constant-time: ^1.0.1 ecdsa-sig-formatter: 1.0.11 safe-buffer: ^5.0.1 - checksum: ff30ea7c2dcc61f3ed2098d868bf89d43701605090c5b21b5544b512843ec6fd9e028381a4dda466cbcdb885c2d1150f7c62e7168394ee07941b4098e1035e2f + checksum: fd1a6de6c649a4b16f0775439ac9173e4bc9aa0162c7f3836699af47736ae000fafe89f232a2345170de6c14021029cb94b488f7882c6caf61e6afef5fce6494 languageName: node linkType: hard "jwa@npm:^2.0.0": - version: 2.0.0 - resolution: "jwa@npm:2.0.0" + version: 2.0.1 + resolution: "jwa@npm:2.0.1" dependencies: - buffer-equal-constant-time: 1.0.1 + buffer-equal-constant-time: ^1.0.1 ecdsa-sig-formatter: 1.0.11 safe-buffer: ^5.0.1 - checksum: 8f00b71ad5fe94cb55006d0d19202f8f56889109caada2f7eeb63ca81755769ce87f4f48101967f398462e3b8ae4faebfbd5a0269cb755dead5d63c77ba4d2f1 + checksum: 6a9828c054c407f6718057089bd3d46dfcb1394e1553e3867abd4579dbec7728b4b0759e7253422ab7d824d95615a86427b35c43f94b83fc3a76470ca4bd2037 languageName: node linkType: hard @@ -13014,31 +14457,6 @@ __metadata: languageName: node linkType: hard -"killable@npm:^1.0.1": - version: 1.0.1 - resolution: "killable@npm:1.0.1" - checksum: 911a85c6e390c19d72c4e3149347cf44042cbd7d18c3c6c5e4f706fdde6e0ed532473392e282c7ef27f518407e6cb7d2a0e71a2ae8d8d8f8ffdb68891a29a68a - languageName: node - linkType: hard - -"kind-of@npm:^3.0.2, kind-of@npm:^3.0.3, kind-of@npm:^3.2.0": - version: 3.2.2 - resolution: "kind-of@npm:3.2.2" - dependencies: - is-buffer: ^1.1.5 - checksum: e898df8ca2f31038f27d24f0b8080da7be274f986bc6ed176f37c77c454d76627619e1681f6f9d2e8d2fd7557a18ecc419a6bb54e422abcbb8da8f1a75e4b386 - languageName: node - linkType: hard - -"kind-of@npm:^4.0.0": - version: 4.0.0 - resolution: "kind-of@npm:4.0.0" - dependencies: - is-buffer: ^1.1.5 - checksum: 1b9e7624a8771b5a2489026e820f3bbbcc67893e1345804a56b23a91e9069965854d2a223a7c6ee563c45be9d8c6ff1ef87f28ed5f0d1a8d00d9dcbb067c529f - languageName: node - linkType: hard - "kind-of@npm:^6.0.2": version: 6.0.3 resolution: "kind-of@npm:6.0.3" @@ -13053,7 +14471,7 @@ __metadata: languageName: node linkType: hard -"klona@npm:^2.0.4": +"klona@npm:^2.0.4, klona@npm:^2.0.5": version: 2.0.6 resolution: "klona@npm:2.0.6" checksum: ac9ee3732e42b96feb67faae4d27cf49494e8a3bf3fa7115ce242fe04786788e0aff4741a07a45a2462e2079aa983d73d38519c85d65b70ef11447bbc3c58ce7 @@ -13061,9 +14479,9 @@ __metadata: linkType: hard "language-subtag-registry@npm:^0.3.20": - version: 0.3.22 - resolution: "language-subtag-registry@npm:0.3.22" - checksum: 8ab70a7e0e055fe977ac16ea4c261faec7205ac43db5e806f72e5b59606939a3b972c4bd1e10e323b35d6ffa97c3e1c4c99f6553069dad2dfdd22020fa3eb56a + version: 0.3.23 + resolution: "language-subtag-registry@npm:0.3.23" + checksum: 0b64c1a6c5431c8df648a6d25594ff280613c886f4a1a542d9b864e5472fb93e5c7856b9c41595c38fac31370328fc79fcc521712e89ea6d6866cbb8e0995d81 languageName: node linkType: hard @@ -13076,13 +14494,13 @@ __metadata: languageName: node linkType: hard -"last-call-webpack-plugin@npm:^3.0.0": - version: 3.0.0 - resolution: "last-call-webpack-plugin@npm:3.0.0" +"launch-editor@npm:^2.6.0": + version: 2.11.1 + resolution: "launch-editor@npm:2.11.1" dependencies: - lodash: ^4.17.5 - webpack-sources: ^1.1.0 - checksum: 23c25a2397c9f75b769b5238ab798873e857baf2363d471d186c9f05212457943f0de16181f33aeecbfd42116b72a0f343fe8910d5d8010f24956d95d536c743 + picocolors: ^1.1.1 + shell-quote: ^1.8.3 + checksum: 95a2e0a50ce15425a87fd035bdef2de37e13c2aee9cd62756783efb286a6e36a341cfcbaecb0d578131a5411c6a1c74c422f9c5b6cb6f4c8284d6078967e08b4 languageName: node linkType: hard @@ -13113,6 +14531,20 @@ __metadata: languageName: node linkType: hard +"lilconfig@npm:^2.0.3": + version: 2.1.0 + resolution: "lilconfig@npm:2.1.0" + checksum: 8549bb352b8192375fed4a74694cd61ad293904eee33f9d4866c2192865c44c4eb35d10782966242634e0cbc1e91fe62b1247f148dc5514918e3a966da7ea117 + languageName: node + linkType: hard + +"lilconfig@npm:^3.0.0, lilconfig@npm:^3.1.3": + version: 3.1.3 + resolution: "lilconfig@npm:3.1.3" + checksum: 644eb10830350f9cdc88610f71a921f510574ed02424b57b0b3abb66ea725d7a082559552524a842f4e0272c196b88dfe1ff7d35ffcc6f45736777185cd67c9a + languageName: node + linkType: hard + "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" @@ -13120,43 +14552,21 @@ __metadata: languageName: node linkType: hard -"load-tsconfig@npm:^0.2.0": +"load-tsconfig@npm:^0.2.3": version: 0.2.5 resolution: "load-tsconfig@npm:0.2.5" checksum: 631740833c4a7157bb7b6eeae6e1afb6a6fac7416b7ba91bd0944d5c5198270af2d68bf8347af3cc2ba821adc4d83ef98f66278bd263bc284c863a09ec441503 languageName: node linkType: hard -"loader-runner@npm:^2.4.0": - version: 2.4.0 - resolution: "loader-runner@npm:2.4.0" - checksum: e27eebbca5347a03f6b1d1bce5b2736a4984fb742f872c0a4d68e62de10f7637613e79a464d3bcd77c246d9c70fcac112bb4a3123010eb527e8b203a614647db - languageName: node - linkType: hard - -"loader-utils@npm:2.0.0": - version: 2.0.0 - resolution: "loader-utils@npm:2.0.0" - dependencies: - big.js: ^5.2.2 - emojis-list: ^3.0.0 - json5: ^2.1.2 - checksum: 6856423131b50b6f5f259da36f498cfd7fc3c3f8bb17777cf87fdd9159e797d4ba4288d9a96415fd8da62c2906960e88f74711dee72d03a9003bddcd0d364a51 - languageName: node - linkType: hard - -"loader-utils@npm:^1.1.0, loader-utils@npm:^1.2.3, loader-utils@npm:^1.4.0": - version: 1.4.2 - resolution: "loader-utils@npm:1.4.2" - dependencies: - big.js: ^5.2.2 - emojis-list: ^3.0.0 - json5: ^1.0.1 - checksum: eb6fb622efc0ffd1abdf68a2022f9eac62bef8ec599cf8adb75e94d1d338381780be6278534170e99edc03380a6d29bc7eb1563c89ce17c5fed3a0b17f1ad804 +"loader-runner@npm:^4.2.0": + version: 4.3.0 + resolution: "loader-runner@npm:4.3.0" + checksum: a90e00dee9a16be118ea43fec3192d0b491fe03a32ed48a4132eb61d498f5536a03a1315531c19d284392a8726a4ecad71d82044c28d7f22ef62e029bf761569 languageName: node linkType: hard -"loader-utils@npm:^2.0.0": +"loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.4": version: 2.0.4 resolution: "loader-utils@npm:2.0.4" dependencies: @@ -13167,10 +14577,10 @@ __metadata: languageName: node linkType: hard -"local-pkg@npm:^0.4.3": - version: 0.4.3 - resolution: "local-pkg@npm:0.4.3" - checksum: 7825aca531dd6afa3a3712a0208697aa4a5cd009065f32e3fb732aafcc42ed11f277b5ac67229222e96f4def55197171cdf3d5522d0381b489d2e5547b407d55 +"loader-utils@npm:^3.2.0": + version: 3.3.1 + resolution: "loader-utils@npm:3.3.1" + checksum: d35808e081635e5bc50228a52ed79f83e2c82bd8f7578818c12b1b4cf0b7f409d72d9b93a683ec36b9eaa93346693d3f3c8380183ba2ff81599b0829d685de39 languageName: node linkType: hard @@ -13193,17 +14603,19 @@ __metadata: languageName: node linkType: hard -"lodash-es@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash-es@npm:4.17.21" - checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2 +"locate-path@npm:^6.0.0": + version: 6.0.0 + resolution: "locate-path@npm:6.0.0" + dependencies: + p-locate: ^5.0.0 + checksum: 72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a languageName: node linkType: hard -"lodash._reinterpolate@npm:^3.0.0": - version: 3.0.0 - resolution: "lodash._reinterpolate@npm:3.0.0" - checksum: 06d2d5f33169604fa5e9f27b6067ed9fb85d51a84202a656901e5ffb63b426781a601508466f039c720af111b0c685d12f1a5c14ff8df5d5f27e491e562784b2 +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1 languageName: node linkType: hard @@ -13284,22 +14696,10 @@ __metadata: languageName: node linkType: hard -"lodash.template@npm:^4.5.0": - version: 4.5.0 - resolution: "lodash.template@npm:4.5.0" - dependencies: - lodash._reinterpolate: ^3.0.0 - lodash.templatesettings: ^4.0.0 - checksum: ca64e5f07b6646c9d3dbc0fe3aaa995cb227c4918abd1cef7a9024cd9c924f2fa389a0ec4296aa6634667e029bc81d4bbdb8efbfde11df76d66085e6c529b450 - languageName: node - linkType: hard - -"lodash.templatesettings@npm:^4.0.0": - version: 4.2.0 - resolution: "lodash.templatesettings@npm:4.2.0" - dependencies: - lodash._reinterpolate: ^3.0.0 - checksum: 863e025478b092997e11a04e9d9e735875eeff1ffcd6c61742aa8272e3c2cddc89ce795eb9726c4e74cef5991f722897ff37df7738a125895f23fc7d12a7bb59 +"lodash.sortby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.sortby@npm:4.7.0" + checksum: db170c9396d29d11fe9a9f25668c4993e0c1331bcb941ddbd48fb76f492e732add7f2a47cfdf8e9d740fa59ac41bbfaf931d268bc72aab3ab49e9f89354d718c languageName: node linkType: hard @@ -13317,31 +14717,21 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.x, lodash@npm:>=3.5 <5, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.5, lodash@npm:^4.7.0": +"lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.7.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 languageName: node linkType: hard -"log-symbols@npm:^4.1.0": - version: 4.1.0 - resolution: "log-symbols@npm:4.1.0" - dependencies: - chalk: ^4.1.0 - is-unicode-supported: ^0.1.0 - checksum: fce1497b3135a0198803f9f07464165e9eb83ed02ceb2273930a6f8a508951178d8cf4f0378e9d28300a2ed2bc49050995d2bd5f53ab716bb15ac84d58c6ef74 - languageName: node - linkType: hard - -"loglevel@npm:^1.6.8": - version: 1.9.1 - resolution: "loglevel@npm:1.9.1" - checksum: e1c8586108c4d566122e91f8a79c8df728920e3a714875affa5120566761a24077ec8ec9e5fc388b022e39fc411ec6e090cde1b5775871241b045139771eeb06 +"longest-streak@npm:^3.0.0": + version: 3.1.0 + resolution: "longest-streak@npm:3.1.0" + checksum: d7f952ed004cbdb5c8bcfc4f7f5c3d65449e6c5a9e9be4505a656e3df5a57ee125f284286b4bf8ecea0c21a7b3bf2b8f9001ad506c319b9815ad6a63a47d0fd0 languageName: node linkType: hard -"loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -13352,12 +14742,10 @@ __metadata: languageName: node linkType: hard -"loupe@npm:^2.3.6": - version: 2.3.7 - resolution: "loupe@npm:2.3.7" - dependencies: - get-func-name: ^2.0.1 - checksum: 96c058ec7167598e238bb7fb9def2f9339215e97d6685d9c1e3e4bdb33d14600e11fe7a812cf0c003dfb73ca2df374f146280b2287cae9e8d989e9d7a69a203b +"loupe@npm:^3.1.0, loupe@npm:^3.1.2, loupe@npm:^3.1.4": + version: 3.2.1 + resolution: "loupe@npm:3.2.1" + checksum: 3ce9ecc5b2c56ffc073bf065ad3a4644cccce3eac81e61a8732e9c8ebfe05513ed478592d25f9dba24cfe82766913be045ab384c04711c7c6447deaf800ad94c languageName: node linkType: hard @@ -13371,9 +14759,16 @@ __metadata: linkType: hard "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": - version: 10.2.0 - resolution: "lru-cache@npm:10.2.0" - checksum: eee7ddda4a7475deac51ac81d7dd78709095c6fa46e8350dc2d22462559a1faa3b81ed931d5464b13d48cbd7e08b46100b6f768c76833912bc444b99c37e25db + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 6476138d2125387a6d20f100608c2583d415a4f64a0fecf30c9e2dda976614f09cad4baa0842447bd37dd459a7bd27f57d9d8f8ce558805abd487c583f3d774a + languageName: node + linkType: hard + +"lru-cache@npm:^11.0.0": + version: 11.2.1 + resolution: "lru-cache@npm:11.2.1" + checksum: d54584b6f03e6de64c9e9f01e48abce5a9bc04318874d5204cee9e4275719544624d51eea6a167672576794af8bba3a7cfc23455d28b270a278cc387d1965131 languageName: node linkType: hard @@ -13395,7 +14790,7 @@ __metadata: languageName: node linkType: hard -"lz-string@npm:^1.4.4, lz-string@npm:^1.5.0": +"lz-string@npm:^1.5.0": version: 1.5.0 resolution: "lz-string@npm:1.5.0" bin: @@ -13413,26 +14808,23 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.0": - version: 0.30.10 - resolution: "magic-string@npm:0.30.10" +"magic-string@npm:^0.30.12, magic-string@npm:^0.30.17": + version: 0.30.19 + resolution: "magic-string@npm:0.30.19" dependencies: - "@jridgewell/sourcemap-codec": ^1.4.15 - checksum: 456fd47c39b296c47dff967e1965121ace35417eab7f45a99e681e725b8661b48e1573c366ee67a27715025b3740773c46b088f115421c7365ea4ea6fa10d399 + "@jridgewell/sourcemap-codec": ^1.5.5 + checksum: f360b87febeceddb35238e55963b70ef68381688c1aada6d842833a7be440a08cb0a8776e23b5e4e34785edc6b42b92dc08c829f43ecdb58547122f3fd79fdc7 languageName: node linkType: hard -"make-dir@npm:^2.0.0": - version: 2.1.0 - resolution: "make-dir@npm:2.1.0" - dependencies: - pify: ^4.0.1 - semver: ^5.6.0 - checksum: 043548886bfaf1820323c6a2997e6d2fa51ccc2586ac14e6f14634f7458b4db2daf15f8c310e2a0abd3e0cddc64df1890d8fc7263033602c47bb12cbfcf86aab +"make-cancellable-promise@npm:^1.3.1": + version: 1.3.2 + resolution: "make-cancellable-promise@npm:1.3.2" + checksum: d4dcad8211272a4d6ef979747a3d7085cdefb92cf50e096ab6a3ea8295e7578b82edaac261c7c4e3d656eadfac285f05b98856b3cf1fd14390ec2708328a9b35 languageName: node linkType: hard -"make-dir@npm:^3.0.2": +"make-dir@npm:^3.0.2, make-dir@npm:^3.1.0": version: 3.1.0 resolution: "make-dir@npm:3.1.0" dependencies: @@ -13450,244 +14842,520 @@ __metadata: languageName: node linkType: hard -"make-error@npm:1.x, make-error@npm:^1.1.1": +"make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" checksum: b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 languageName: node linkType: hard -"make-fetch-happen@npm:^13.0.0": - version: 13.0.0 - resolution: "make-fetch-happen@npm:13.0.0" - 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 - promise-retry: ^2.0.1 - ssri: ^10.0.0 - checksum: 7c7a6d381ce919dd83af398b66459a10e2fe8f4504f340d1d090d3fa3d1b0c93750220e1d898114c64467223504bd258612ba83efbc16f31b075cd56de24b4af +"make-event-props@npm:^1.6.0": + version: 1.6.2 + resolution: "make-event-props@npm:1.6.2" + checksum: ded823d8b73926d94513416c75585be2cea9d9408b085eed31c20a1005147661a50852f869e1779990ddd04c8e07e1f24c766453cc9b4870bcef8d79c533a5fc + languageName: node + linkType: hard + +"make-fetch-happen@npm:^14.0.3": + version: 14.0.3 + resolution: "make-fetch-happen@npm:14.0.3" + 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 + checksum: 6fb2fee6da3d98f1953b03d315826b5c5a4ea1f908481afc113782d8027e19f080c85ae998454de4e5f27a681d3ec58d57278f0868d4e0b736f51d396b661691 + languageName: node + linkType: hard + +"makeerror@npm:1.0.12": + version: 1.0.12 + resolution: "makeerror@npm:1.0.12" + dependencies: + tmpl: 1.0.5 + checksum: b38a025a12c8146d6eeea5a7f2bf27d51d8ad6064da8ca9405fcf7bf9b54acd43e3b30ddd7abb9b1bfa4ddb266019133313482570ddb207de568f71ecfcf6060 + languageName: node + linkType: hard + +"match-sorter@npm:^6.0.2": + version: 6.3.4 + resolution: "match-sorter@npm:6.3.4" + dependencies: + "@babel/runtime": ^7.23.8 + remove-accents: 0.5.0 + checksum: 950c1600173a639e216947559a389b64258d52f33aea3a6ddb97500589888b83c976a028f731f40bc08d9d8af20de7916992fabb403f38330183a1df44c7634b + languageName: node + linkType: hard + +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 0e513b29d120f478c85a70f49da0b8b19bc638975eca466f2eeae0071f3ad00454c621bf66e16dd435896c208e719fc91ad79bbfba4e400fe0b372e7c1c9c9a2 + languageName: node + linkType: hard + +"mdast-util-from-markdown@npm:^2.0.0": + version: 2.0.2 + resolution: "mdast-util-from-markdown@npm:2.0.2" + dependencies: + "@types/mdast": ^4.0.0 + "@types/unist": ^3.0.0 + decode-named-character-reference: ^1.0.0 + devlop: ^1.0.0 + mdast-util-to-string: ^4.0.0 + micromark: ^4.0.0 + micromark-util-decode-numeric-character-reference: ^2.0.0 + micromark-util-decode-string: ^2.0.0 + micromark-util-normalize-identifier: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + unist-util-stringify-position: ^4.0.0 + checksum: 1ad19f48b30ac6e0cb756070c210c78ad93c26876edfb3f75127783bc6df8b9402016d8f3e9964f3d1d5430503138ec65c145e869438727e1aa7f3cebf228fba + languageName: node + linkType: hard + +"mdast-util-mdx-expression@npm:^2.0.0": + version: 2.0.1 + resolution: "mdast-util-mdx-expression@npm:2.0.1" + dependencies: + "@types/estree-jsx": ^1.0.0 + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + devlop: ^1.0.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: 6af56b06bde3ab971129db9855dcf0d31806c70b3b052d7a90a5499a366b57ffd0c2efca67d281c448c557298ba7e3e61bd07133733b735440840dd339b28e19 + languageName: node + linkType: hard + +"mdast-util-mdx-jsx@npm:^3.0.0": + version: 3.2.0 + resolution: "mdast-util-mdx-jsx@npm:3.2.0" + dependencies: + "@types/estree-jsx": ^1.0.0 + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + "@types/unist": ^3.0.0 + ccount: ^2.0.0 + devlop: ^1.1.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + parse-entities: ^4.0.0 + stringify-entities: ^4.0.0 + unist-util-stringify-position: ^4.0.0 + vfile-message: ^4.0.0 + checksum: 224f5f6ad247f0f2622ee36c82ac7a4c6a60c31850de4056bf95f531bd2f7ec8943ef34dfe8a8375851f65c07e4913c4f33045d703df4ff4d11b2de5a088f7f9 + languageName: node + linkType: hard + +"mdast-util-mdxjs-esm@npm:^2.0.0": + version: 2.0.1 + resolution: "mdast-util-mdxjs-esm@npm:2.0.1" + dependencies: + "@types/estree-jsx": ^1.0.0 + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + devlop: ^1.0.0 + mdast-util-from-markdown: ^2.0.0 + mdast-util-to-markdown: ^2.0.0 + checksum: 1f9dad04d31d59005332e9157ea9510dc1d03092aadbc607a10475c7eec1c158b475aa0601a3a4f74e13097ca735deb8c2d9d37928ddef25d3029fd7c9e14dc3 + languageName: node + linkType: hard + +"mdast-util-phrasing@npm:^4.0.0": + version: 4.1.0 + resolution: "mdast-util-phrasing@npm:4.1.0" + dependencies: + "@types/mdast": ^4.0.0 + unist-util-is: ^6.0.0 + checksum: 3a97533e8ad104a422f8bebb34b3dde4f17167b8ed3a721cf9263c7416bd3447d2364e6d012a594aada40cac9e949db28a060bb71a982231693609034ed5324e + languageName: node + linkType: hard + +"mdast-util-to-hast@npm:^13.0.0": + version: 13.2.0 + resolution: "mdast-util-to-hast@npm:13.2.0" + dependencies: + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + "@ungap/structured-clone": ^1.0.0 + devlop: ^1.0.0 + micromark-util-sanitize-uri: ^2.0.0 + trim-lines: ^3.0.0 + unist-util-position: ^5.0.0 + unist-util-visit: ^5.0.0 + vfile: ^6.0.0 + checksum: 7e5231ff3d4e35e1421908437577fd5098141f64918ff5cc8a0f7a8a76c5407f7a3ee88d75f7a1f7afb763989c9f357475fa0ba8296c00aaff1e940098fe86a6 + languageName: node + linkType: hard + +"mdast-util-to-markdown@npm:^2.0.0": + version: 2.1.2 + resolution: "mdast-util-to-markdown@npm:2.1.2" + dependencies: + "@types/mdast": ^4.0.0 + "@types/unist": ^3.0.0 + longest-streak: ^3.0.0 + mdast-util-phrasing: ^4.0.0 + mdast-util-to-string: ^4.0.0 + micromark-util-classify-character: ^2.0.0 + micromark-util-decode-string: ^2.0.0 + unist-util-visit: ^5.0.0 + zwitch: ^2.0.0 + checksum: 288d152bd50c00632e6e01c610bb904a220d1e226c8086c40627877959746f83ab0b872f4150cb7d910198953b1bf756e384ac3fee3e7b0ddb4517f9084c5803 + languageName: node + linkType: hard + +"mdast-util-to-string@npm:^4.0.0": + version: 4.0.0 + resolution: "mdast-util-to-string@npm:4.0.0" + dependencies: + "@types/mdast": ^4.0.0 + checksum: 35489fb5710d58cbc2d6c8b6547df161a3f81e0f28f320dfb3548a9393555daf07c310c0c497708e67ed4dfea4a06e5655799e7d631ca91420c288b4525d6c29 + languageName: node + linkType: hard + +"mdn-data@npm:2.0.14": + version: 2.0.14 + resolution: "mdn-data@npm:2.0.14" + checksum: 9d0128ed425a89f4cba8f787dca27ad9408b5cb1b220af2d938e2a0629d17d879a34d2cb19318bdb26c3f14c77dd5dfbae67211f5caaf07b61b1f2c5c8c7dc16 + languageName: node + linkType: hard + +"mdn-data@npm:2.0.4": + version: 2.0.4 + resolution: "mdn-data@npm:2.0.4" + checksum: add3c95e6d03d301b8a8bcfee3de33f4d07e4c5eee5b79f18d6d737de717e22472deadf67c1a8563983c0b603e10d7df40aa8e5fddf18884dfe118ccec7ae329 + languageName: node + linkType: hard + +"media-typer@npm:0.3.0": + version: 0.3.0 + resolution: "media-typer@npm:0.3.0" + checksum: af1b38516c28ec95d6b0826f6c8f276c58aec391f76be42aa07646b4e39d317723e869700933ca6995b056db4b09a78c92d5440dc23657e6764be5d28874bba1 + languageName: node + linkType: hard + +"media-typer@npm:^1.1.0": + version: 1.1.0 + resolution: "media-typer@npm:1.1.0" + checksum: a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd + languageName: node + linkType: hard + +"memfs@npm:^3.1.2, memfs@npm:^3.4.3": + version: 3.5.3 + resolution: "memfs@npm:3.5.3" + dependencies: + fs-monkey: ^1.0.4 + checksum: 18dfdeacad7c8047b976a6ccd58bc98ba76e122ad3ca0e50a21837fe2075fc0d9aafc58ab9cf2576c2b6889da1dd2503083f2364191b695273f40969db2ecc44 + languageName: node + linkType: hard + +"memoize-one@npm:^6.0.0": + version: 6.0.0 + resolution: "memoize-one@npm:6.0.0" + checksum: f185ea69f7cceae5d1cb596266dcffccf545e8e7b4106ec6aa93b71ab9d16460dd118ac8b12982c55f6d6322fcc1485de139df07eacffaae94888b9b3ad7675f + languageName: node + linkType: hard + +"merge-descriptors@npm:1.0.3": + version: 1.0.3 + resolution: "merge-descriptors@npm:1.0.3" + checksum: 52117adbe0313d5defa771c9993fe081e2d2df9b840597e966aadafde04ae8d0e3da46bac7ca4efc37d4d2b839436582659cd49c6a43eacb3fe3050896a105d1 + languageName: node + linkType: hard + +"merge-descriptors@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-descriptors@npm:2.0.0" + checksum: e383332e700a94682d0125a36c8be761142a1320fc9feeb18e6e36647c9edf064271645f5669b2c21cf352116e561914fd8aa831b651f34db15ef4038c86696a languageName: node linkType: hard -"makeerror@npm:1.0.12": - version: 1.0.12 - resolution: "makeerror@npm:1.0.12" - dependencies: - tmpl: 1.0.5 - checksum: b38a025a12c8146d6eeea5a7f2bf27d51d8ad6064da8ca9405fcf7bf9b54acd43e3b30ddd7abb9b1bfa4ddb266019133313482570ddb207de568f71ecfcf6060 +"merge-refs@npm:^1.3.0": + version: 1.3.0 + resolution: "merge-refs@npm:1.3.0" + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 8400f716a77857dac6b5d49cd5ef69cec7bff6c5555785c5e91a5142fbb5f3e6fe81282bc5be1f01c0c0843ed29f5b4169bfa9838ec69c459b4538f3fef3e79c languageName: node linkType: hard -"map-cache@npm:^0.2.2": - version: 0.2.2 - resolution: "map-cache@npm:0.2.2" - checksum: 3067cea54285c43848bb4539f978a15dedc63c03022abeec6ef05c8cb6829f920f13b94bcaf04142fc6a088318e564c4785704072910d120d55dbc2e0c421969 +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 languageName: node linkType: hard -"map-visit@npm:^1.0.0": - version: 1.0.0 - resolution: "map-visit@npm:1.0.0" - dependencies: - object-visit: ^1.0.0 - checksum: c27045a5021c344fc19b9132eb30313e441863b2951029f8f8b66f79d3d8c1e7e5091578075a996f74e417479506fe9ede28c44ca7bc351a61c9d8073daec36a +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 languageName: node linkType: hard -"match-sorter@npm:^6.0.2": - version: 6.3.4 - resolution: "match-sorter@npm:6.3.4" - dependencies: - "@babel/runtime": ^7.23.8 - remove-accents: 0.5.0 - checksum: 950c1600173a639e216947559a389b64258d52f33aea3a6ddb97500589888b83c976a028f731f40bc08d9d8af20de7916992fabb403f38330183a1df44c7634b +"methods@npm:^1.1.2, methods@npm:~1.1.2": + version: 1.1.2 + resolution: "methods@npm:1.1.2" + checksum: 0917ff4041fa8e2f2fda5425a955fe16ca411591fbd123c0d722fcf02b73971ed6f764d85f0a6f547ce49ee0221ce2c19a5fa692157931cecb422984f1dcd13a languageName: node linkType: hard -"md5.js@npm:^1.3.4": - version: 1.3.5 - resolution: "md5.js@npm:1.3.5" +"micromark-core-commonmark@npm:^2.0.0": + version: 2.0.3 + resolution: "micromark-core-commonmark@npm:2.0.3" + dependencies: + decode-named-character-reference: ^1.0.0 + devlop: ^1.0.0 + micromark-factory-destination: ^2.0.0 + micromark-factory-label: ^2.0.0 + micromark-factory-space: ^2.0.0 + micromark-factory-title: ^2.0.0 + micromark-factory-whitespace: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-chunked: ^2.0.0 + micromark-util-classify-character: ^2.0.0 + micromark-util-html-tag-name: ^2.0.0 + micromark-util-normalize-identifier: ^2.0.0 + micromark-util-resolve-all: ^2.0.0 + micromark-util-subtokenize: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: cfb0fd9c895f86a4e9344f7f0344fe6bd1018945798222835248146a42430b8c7bc0b2857af574cf4e1b4ce4e5c1a35a1479942421492e37baddde8de85814dc + languageName: node + linkType: hard + +"micromark-factory-destination@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-factory-destination@npm:2.0.1" dependencies: - hash-base: ^3.0.0 - inherits: ^2.0.1 - safe-buffer: ^5.1.2 - checksum: 098494d885684bcc4f92294b18ba61b7bd353c23147fbc4688c75b45cb8590f5a95fd4584d742415dcc52487f7a1ef6ea611cfa1543b0dc4492fe026357f3f0c + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 9c4baa9ca2ed43c061bbf40ddd3d85154c2a0f1f485de9dea41d7dd2ad994ebb02034a003b2c1dbe228ba83a0576d591f0e90e0bf978713f84ee7d7f3aa98320 languageName: node linkType: hard -"mdast-util-definitions@npm:^4.0.0": - version: 4.0.0 - resolution: "mdast-util-definitions@npm:4.0.0" +"micromark-factory-label@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-factory-label@npm:2.0.1" dependencies: - unist-util-visit: ^2.0.0 - checksum: 2325f20b82b3fb8cb5fda77038ee0bbdd44f82cfca7c48a854724b58bc1fe5919630a3ce7c45e210726df59d46c881d020b2da7a493bfd1ee36eb2bbfef5d78e + devlop: ^1.0.0 + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: bd03f5a75f27cdbf03b894ddc5c4480fc0763061fecf9eb927d6429233c930394f223969a99472df142d570c831236134de3dc23245d23d9f046f9d0b623b5c2 languageName: node linkType: hard -"mdast-util-from-markdown@npm:^0.8.0": - version: 0.8.5 - resolution: "mdast-util-from-markdown@npm:0.8.5" +"micromark-factory-space@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-factory-space@npm:2.0.1" dependencies: - "@types/mdast": ^3.0.0 - mdast-util-to-string: ^2.0.0 - micromark: ~2.11.0 - parse-entities: ^2.0.0 - unist-util-stringify-position: ^2.0.0 - checksum: 5a9d0d753a42db763761e874c22365d0c7c9934a5a18b5ff76a0643610108a208a041ffdb2f3d3dd1863d3d915225a4020a0aade282af0facfd0df110601eee6 + micromark-util-character: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 1bd68a017c1a66f4787506660c1e1c5019169aac3b1cb075d49ac5e360e0b2065e984d4e1d6e9e52a9d44000f2fa1c98e66a743d7aae78b4b05616bf3242ed71 languageName: node linkType: hard -"mdast-util-to-hast@npm:^10.2.0": - version: 10.2.0 - resolution: "mdast-util-to-hast@npm:10.2.0" +"micromark-factory-title@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-factory-title@npm:2.0.1" dependencies: - "@types/mdast": ^3.0.0 - "@types/unist": ^2.0.0 - mdast-util-definitions: ^4.0.0 - mdurl: ^1.0.0 - unist-builder: ^2.0.0 - unist-util-generated: ^1.0.0 - unist-util-position: ^3.0.0 - unist-util-visit: ^2.0.0 - checksum: 72df2dd9bfa2d07b4750a333444f82e0f3752dae75b6e300cf0a716407a185eb75095a54ecad90cbd6f6d133b20dea8844ff76c1ea78612550de170b43d4fa85 + micromark-factory-space: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: b4d2e4850a8ba0dff25ce54e55a3eb0d43dda88a16293f53953153288f9d84bcdfa8ca4606b2cfbb4f132ea79587bbb478a73092a349f893f5264fbcdbce2ee1 languageName: node linkType: hard -"mdast-util-to-string@npm:^2.0.0": - version: 2.0.0 - resolution: "mdast-util-to-string@npm:2.0.0" - checksum: 0b2113ada10e002fbccb014170506dabe2f2ddacaacbe4bc1045c33f986652c5a162732a2c057c5335cdb58419e2ad23e368e5be226855d4d4e280b81c4e9ec2 +"micromark-factory-whitespace@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-factory-whitespace@npm:2.0.1" + dependencies: + micromark-factory-space: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 67b3944d012a42fee9e10e99178254a04d48af762b54c10a50fcab988688799993efb038daf9f5dbc04001a97b9c1b673fc6f00e6a56997877ab25449f0c8650 languageName: node linkType: hard -"mdn-data@npm:2.0.14": - version: 2.0.14 - resolution: "mdn-data@npm:2.0.14" - checksum: 9d0128ed425a89f4cba8f787dca27ad9408b5cb1b220af2d938e2a0629d17d879a34d2cb19318bdb26c3f14c77dd5dfbae67211f5caaf07b61b1f2c5c8c7dc16 +"micromark-util-character@npm:^2.0.0": + version: 2.1.1 + resolution: "micromark-util-character@npm:2.1.1" + dependencies: + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: e9e409efe4f2596acd44587e8591b722bfc041c1577e8fe0d9c007a4776fb800f9b3637a22862ad2ba9489f4bdf72bb547fce5767dbbfe0a5e6760e2a21c6495 languageName: node linkType: hard -"mdn-data@npm:2.0.4": - version: 2.0.4 - resolution: "mdn-data@npm:2.0.4" - checksum: add3c95e6d03d301b8a8bcfee3de33f4d07e4c5eee5b79f18d6d737de717e22472deadf67c1a8563983c0b603e10d7df40aa8e5fddf18884dfe118ccec7ae329 +"micromark-util-chunked@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-chunked@npm:2.0.1" + dependencies: + micromark-util-symbol: ^2.0.0 + checksum: f8cb2a67bcefe4bd2846d838c97b777101f0043b9f1de4f69baf3e26bb1f9885948444e3c3aec66db7595cad8173bd4567a000eb933576c233d54631f6323fe4 languageName: node linkType: hard -"mdurl@npm:^1.0.0": - version: 1.0.1 - resolution: "mdurl@npm:1.0.1" - checksum: 71731ecba943926bfbf9f9b51e28b5945f9411c4eda80894221b47cc105afa43ba2da820732b436f0798fd3edbbffcd1fc1415843c41a87fea08a41cc1e3d02b +"micromark-util-classify-character@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-classify-character@npm:2.0.1" + dependencies: + micromark-util-character: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 4d8bbe3a6dbf69ac0fc43516866b5bab019fe3f4568edc525d4feaaaf78423fa54e6b6732b5bccbeed924455279a3758ffc9556954aafb903982598a95a02704 languageName: node linkType: hard -"media-typer@npm:0.3.0": - version: 0.3.0 - resolution: "media-typer@npm:0.3.0" - checksum: af1b38516c28ec95d6b0826f6c8f276c58aec391f76be42aa07646b4e39d317723e869700933ca6995b056db4b09a78c92d5440dc23657e6764be5d28874bba1 +"micromark-util-combine-extensions@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-combine-extensions@npm:2.0.1" + dependencies: + micromark-util-chunked: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 5d22fb9ee37e8143adfe128a72b50fa09568c2cc553b3c76160486c96dbbb298c5802a177a10a215144a604b381796071b5d35be1f2c2b2ee17995eda92f0c8e languageName: node linkType: hard -"memory-fs@npm:^0.4.1": - version: 0.4.1 - resolution: "memory-fs@npm:0.4.1" +"micromark-util-decode-numeric-character-reference@npm:^2.0.0": + version: 2.0.2 + resolution: "micromark-util-decode-numeric-character-reference@npm:2.0.2" dependencies: - errno: ^0.1.3 - readable-stream: ^2.0.1 - checksum: 6db6c8682eff836664ca9b5b6052ae38d21713dda9d0ef4700fa5c0599a8bc16b2093bee75ac3dedbe59fb2222d368f25bafaa62ba143c41051359cbcb005044 + micromark-util-symbol: ^2.0.0 + checksum: ee11c8bde51e250e302050474c4a2adca094bca05c69f6cdd241af12df285c48c88d19ee6e022b9728281c280be16328904adca994605680c43af56019f4b0b6 languageName: node linkType: hard -"memory-fs@npm:^0.5.0": - version: 0.5.0 - resolution: "memory-fs@npm:0.5.0" +"micromark-util-decode-string@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-decode-string@npm:2.0.1" dependencies: - errno: ^0.1.3 - readable-stream: ^2.0.1 - checksum: a9f25b0a8ecfb7324277393f19ef68e6ba53b9e6e4b526bbf2ba23055c5440fbf61acc7bf66bfd980e9eb4951a4790f6f777a9a3abd36603f22c87e8a64d3d6b + decode-named-character-reference: ^1.0.0 + micromark-util-character: ^2.0.0 + micromark-util-decode-numeric-character-reference: ^2.0.0 + micromark-util-symbol: ^2.0.0 + checksum: e9546ae53f9b5a4f9aa6aaf3e750087100d3429485ca80dbacec99ff2bb15a406fa7d93784a0fc2fe05ad7296b9295e75160ef71faec9e90110b7be2ae66241a languageName: node linkType: hard -"merge-descriptors@npm:1.0.1": - version: 1.0.1 - resolution: "merge-descriptors@npm:1.0.1" - checksum: 5abc259d2ae25bb06d19ce2b94a21632583c74e2a9109ee1ba7fd147aa7362b380d971e0251069f8b3eb7d48c21ac839e21fa177b335e82c76ec172e30c31a26 +"micromark-util-encode@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-encode@npm:2.0.1" + checksum: be890b98e78dd0cdd953a313f4148c4692cc2fb05533e56fef5f421287d3c08feee38ca679f318e740530791fc251bfe8c80efa926fcceb4419b269c9343d226 languageName: node linkType: hard -"merge-stream@npm:^2.0.0": - version: 2.0.0 - resolution: "merge-stream@npm:2.0.0" - checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 +"micromark-util-html-tag-name@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-html-tag-name@npm:2.0.1" + checksum: dea365f5ad28ad74ff29fcb581f7b74fc1f80271c5141b3b2bc91c454cbb6dfca753f28ae03730d657874fcbd89d0494d0e3965dfdca06d9855f467c576afa9d languageName: node linkType: hard -"merge2@npm:^1.3.0, merge2@npm:^1.4.1": - version: 1.4.1 - resolution: "merge2@npm:1.4.1" - checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 +"micromark-util-normalize-identifier@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-normalize-identifier@npm:2.0.1" + dependencies: + micromark-util-symbol: ^2.0.0 + checksum: 1eb9a289d7da067323df9fdc78bfa90ca3207ad8fd893ca02f3133e973adcb3743b233393d23d95c84ccaf5d220ae7f5a28402a644f135dcd4b8cfa60a7b5f84 languageName: node linkType: hard -"methods@npm:^1.1.2, methods@npm:~1.1.2": - version: 1.1.2 - resolution: "methods@npm:1.1.2" - checksum: 0917ff4041fa8e2f2fda5425a955fe16ca411591fbd123c0d722fcf02b73971ed6f764d85f0a6f547ce49ee0221ce2c19a5fa692157931cecb422984f1dcd13a +"micromark-util-resolve-all@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-resolve-all@npm:2.0.1" + dependencies: + micromark-util-types: ^2.0.0 + checksum: 9275f3ddb6c26f254dd2158e66215d050454b279707a7d9ce5a3cd0eba23201021cedcb78ae1a746c1b23227dcc418ee40dd074ade195359506797a5493550cc languageName: node linkType: hard -"microevent.ts@npm:~0.1.1": - version: 0.1.1 - resolution: "microevent.ts@npm:0.1.1" - checksum: 7874fcdb3f0dfa4e996d3ea63b3b9882874ae7d22be28d51ae20da24c712e9e28e5011d988095c27dd2b32e37c0ad7425342a71b89adb8e808ec7194fadf4a7a +"micromark-util-sanitize-uri@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-sanitize-uri@npm:2.0.1" + dependencies: + micromark-util-character: ^2.0.0 + micromark-util-encode: ^2.0.0 + micromark-util-symbol: ^2.0.0 + checksum: d01517840c17de67aaa0b0f03bfe05fac8a41d99723cd8ce16c62f6810e99cd3695364a34c335485018e5e2c00e69031744630a1b85c6868aa2f2ca1b36daa2f languageName: node linkType: hard -"micromark@npm:~2.11.0": - version: 2.11.4 - resolution: "micromark@npm:2.11.4" +"micromark-util-subtokenize@npm:^2.0.0": + version: 2.1.0 + resolution: "micromark-util-subtokenize@npm:2.1.0" dependencies: - debug: ^4.0.0 - parse-entities: ^2.0.0 - checksum: f8a5477d394908a5d770227aea71657a76423d420227c67ea0699e659a5f62eb39d504c1f7d69ec525a6af5aaeb6a7bffcdba95614968c03d41d3851edecb0d6 + devlop: ^1.0.0 + micromark-util-chunked: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 2e194bc8a5279d256582020500e5072a95c1094571be49043704343032e1fffbe09c862ef9c131cf5c762e296ddb54ff8bc767b3786a798524a68d1db6942934 languageName: node linkType: hard -"micromatch@npm:^3.1.10, micromatch@npm:^3.1.4": - version: 3.1.10 - resolution: "micromatch@npm:3.1.10" - dependencies: - arr-diff: ^4.0.0 - array-unique: ^0.3.2 - braces: ^2.3.1 - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - extglob: ^2.0.4 - fragment-cache: ^0.2.1 - kind-of: ^6.0.2 - nanomatch: ^1.2.9 - object.pick: ^1.3.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.2 - checksum: ad226cba4daa95b4eaf47b2ca331c8d2e038d7b41ae7ed0697cde27f3f1d6142881ab03d4da51b65d9d315eceb5e4cdddb3fbb55f5f72cfa19cf3ea469d054dc +"micromark-util-symbol@npm:^2.0.0": + version: 2.0.1 + resolution: "micromark-util-symbol@npm:2.0.1" + checksum: fb7346950550bc85a55793dda94a8b3cb3abc068dbd7570d1162db7aee803411d06c0a5de4ae59cd945f46143bdeadd4bba02a02248fa0d18cc577babaa00044 + languageName: node + linkType: hard + +"micromark-util-types@npm:^2.0.0": + version: 2.0.2 + resolution: "micromark-util-types@npm:2.0.2" + checksum: 884f7974839e4bc6d2bd662e57c973a9164fd5c0d8fe16cddf07472b86a7e6726747c00674952c0321d17685d700cd3295e9f58a842a53acdf6c6d55ab051aab languageName: node linkType: hard -"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": - version: 4.0.5 - resolution: "micromatch@npm:4.0.5" +"micromark@npm:^4.0.0": + version: 4.0.2 + resolution: "micromark@npm:4.0.2" + dependencies: + "@types/debug": ^4.0.0 + debug: ^4.0.0 + decode-named-character-reference: ^1.0.0 + devlop: ^1.0.0 + micromark-core-commonmark: ^2.0.0 + micromark-factory-space: ^2.0.0 + micromark-util-character: ^2.0.0 + micromark-util-chunked: ^2.0.0 + micromark-util-combine-extensions: ^2.0.0 + micromark-util-decode-numeric-character-reference: ^2.0.0 + micromark-util-encode: ^2.0.0 + micromark-util-normalize-identifier: ^2.0.0 + micromark-util-resolve-all: ^2.0.0 + micromark-util-sanitize-uri: ^2.0.0 + micromark-util-subtokenize: ^2.0.0 + micromark-util-symbol: ^2.0.0 + micromark-util-types: ^2.0.0 + checksum: 5306c15dd12f543755bc627fc361d4255dfc430e7af6069a07ac0eacc338fbd761fe8e93f02a8bfab6097bab12ee903192fe31389222459d5029242a5aaba3b8 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5, micromatch@npm:^4.0.8": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" dependencies: - braces: ^3.0.2 + braces: ^3.0.3 picomatch: ^2.3.1 - checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc + checksum: 79920eb634e6f400b464a954fcfa589c4e7c7143209488e44baf627f9affc8b1e306f41f4f0deedde97e69cb725920879462d3e750ab3bd3c1aed675bb3a8966 languageName: node linkType: hard @@ -13698,26 +15366,21 @@ __metadata: languageName: node linkType: hard -"miller-rabin@npm:^4.0.0": - version: 4.0.1 - resolution: "miller-rabin@npm:4.0.1" - dependencies: - bn.js: ^4.0.0 - brorand: ^1.0.1 - bin: - miller-rabin: bin/miller-rabin - checksum: 00cd1ab838ac49b03f236cc32a14d29d7d28637a53096bf5c6246a032a37749c9bd9ce7360cbf55b41b89b7d649824949ff12bc8eee29ac77c6b38eada619ece - languageName: node - linkType: hard - -"mime-db@npm:1.52.0, mime-db@npm:>= 1.43.0 < 2": +"mime-db@npm:1.52.0": version: 1.52.0 resolution: "mime-db@npm:1.52.0" checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.54.0": + version: 1.54.0 + resolution: "mime-db@npm:1.54.0" + checksum: e99aaf2f23f5bd607deb08c83faba5dd25cf2fec90a7cc5b92d8260867ee08dab65312e1a589e60093dc7796d41e5fae013268418482f1db4c7d52d0a0960ac9 + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:^2.1.35, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -13726,6 +15389,15 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:^3.0.0, mime-types@npm:^3.0.1": + version: 3.0.1 + resolution: "mime-types@npm:3.0.1" + dependencies: + mime-db: ^1.54.0 + checksum: 8d497ad5cb2dd1210ac7d049b5de94af0b24b45a314961e145b44389344604d54752f03bc00bf880c0da60a214be6fb6d423d318104f02c28d95dd8ebeea4fb4 + languageName: node + linkType: hard + "mime@npm:1.6.0": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -13735,7 +15407,7 @@ __metadata: languageName: node linkType: hard -"mime@npm:2.6.0, mime@npm:^2.4.4": +"mime@npm:2.6.0": version: 2.6.0 resolution: "mime@npm:2.6.0" bin: @@ -13751,6 +15423,13 @@ __metadata: languageName: node linkType: hard +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 25739fee32c17f433626bf19f016df9036b75b3d84a3046c7d156e72ec963dd29d7fc8a302f55a3d6c5a4ff24259676b15d915aad6480815a969ff2ec0836867 + languageName: node + linkType: hard + "min-indent@npm:^1.0.0": version: 1.0.1 resolution: "min-indent@npm:1.0.1" @@ -13758,44 +15437,35 @@ __metadata: languageName: node linkType: hard -"mini-css-extract-plugin@npm:0.11.3": - version: 0.11.3 - resolution: "mini-css-extract-plugin@npm:0.11.3" +"mini-css-extract-plugin@npm:^2.4.5": + version: 2.9.4 + resolution: "mini-css-extract-plugin@npm:2.9.4" dependencies: - loader-utils: ^1.1.0 - normalize-url: 1.9.1 - schema-utils: ^1.0.0 - webpack-sources: ^1.1.0 + schema-utils: ^4.0.0 + tapable: ^2.2.1 peerDependencies: - webpack: ^4.4.0 || ^5.0.0 - checksum: 14fbdf1338fe0264a2f7f87b3fc640809b7443f6434c6532bdbec1c5ab113502325fec958e9cf0667c3790087dc1e83c02e1f4d7463c10c956b0d6ebe56ea99e + webpack: ^5.0.0 + checksum: 4ec46ebdcb5dae4b1c012debca90fea27b1e8e7790d408154232d77d25f56f839e7b1ec5401a962d6356e7b9301c760d2ef62e1cb0d4d7b6ec8209f812733dda languageName: node linkType: hard -"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": +"minimalistic-assert@npm:^1.0.0": version: 1.0.1 resolution: "minimalistic-assert@npm:1.0.1" checksum: cc7974a9268fbf130fb055aff76700d7e2d8be5f761fb5c60318d0ed010d839ab3661a533ad29a5d37653133385204c503bfac995aaa4236f4e847461ea32ba7 languageName: node linkType: hard -"minimalistic-crypto-utils@npm:^1.0.1": - version: 1.0.1 - resolution: "minimalistic-crypto-utils@npm:1.0.1" - checksum: 6e8a0422b30039406efd4c440829ea8f988845db02a3299f372fceba56ffa94994a9c0f2fd70c17f9969eedfbd72f34b5070ead9656a34d3f71c0bd72583a0ed - languageName: node - linkType: hard - -"minimatch@npm:3.0.4": - version: 3.0.4 - resolution: "minimatch@npm:3.0.4" +"minimatch@npm:^10.0.3": + version: 10.0.3 + resolution: "minimatch@npm:10.0.3" dependencies: - brace-expansion: ^1.1.7 - checksum: 66ac295f8a7b59788000ea3749938b0970344c841750abd96694f80269b926ebcafad3deeb3f1da2522978b119e6ae3a5869b63b13a7859a456b3408bd18a078 + "@isaacs/brace-expansion": ^5.0.0 + checksum: 20bfb708095a321cb43c20b78254e484cb7d23aad992e15ca3234a3331a70fa9cd7a50bc1a7c7b2b9c9890c37ff0685f8380028fcc28ea5e6de75b1d4f9374aa languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -13804,28 +15474,28 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1": - version: 9.0.4 - resolution: "minimatch@npm:9.0.4" +"minimatch@npm:^5.0.1": + version: 5.1.6 + resolution: "minimatch@npm:5.1.6" dependencies: brace-expansion: ^2.0.1 - checksum: cf717f597ec3eed7dabc33153482a2e8d49f4fd3c26e58fd9c71a94c5029a0838728841b93f46bf1263b65a8010e2ee800d0dc9b004ab8ba8b6d1ec07cc115b5 + checksum: 7564208ef81d7065a370f788d337cd80a689e981042cb9a1d0e6580b6c6a8c9279eba80010516e258835a988363f99f54a6f711a315089b8b42694f5da9d0d77 languageName: node linkType: hard -"minimist@npm:^1.1.1, minimist@npm:^1.2.0, minimist@npm:^1.2.6": - version: 1.2.8 - resolution: "minimist@npm:1.2.8" - checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 +"minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: ^2.0.1 + checksum: 2c035575eda1e50623c731ec6c14f65a85296268f749b9337005210bb2b34e2705f8ef1a358b188f69892286ab99dc42c8fb98a57bde55c8d81b3023c19cea28 languageName: node linkType: hard -"minipass-collect@npm:^1.0.2": - version: 1.0.2 - resolution: "minipass-collect@npm:1.0.2" - dependencies: - minipass: ^3.0.0 - checksum: 14df761028f3e47293aee72888f2657695ec66bd7d09cae7ad558da30415fdc4752bbfee66287dcc6fd5e6a2fa3466d6c484dc1cbd986525d9393b9523d97f10 +"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 languageName: node linkType: hard @@ -13838,18 +15508,18 @@ __metadata: languageName: node linkType: hard -"minipass-fetch@npm:^3.0.0": - version: 3.0.4 - resolution: "minipass-fetch@npm:3.0.4" +"minipass-fetch@npm:^4.0.0": + version: 4.0.1 + resolution: "minipass-fetch@npm:4.0.1" dependencies: encoding: ^0.1.13 minipass: ^7.0.3 minipass-sized: ^1.0.3 - minizlib: ^2.1.2 + minizlib: ^3.0.1 dependenciesMeta: encoding: optional: true - checksum: af7aad15d5c128ab1ebe52e043bdf7d62c3c6f0cecb9285b40d7b395e1375b45dcdfd40e63e93d26a0e8249c9efd5c325c65575aceee192883970ff8cb11364a + checksum: 3dfca705ce887ca9ff14d73e8d8593996dea1a1ecd8101fdbb9c10549d1f9670bc8fb66ad0192769ead4c2dc01b4f9ca1cf567ded365adff17827a303b948140 languageName: node linkType: hard @@ -13862,7 +15532,7 @@ __metadata: languageName: node linkType: hard -"minipass-pipeline@npm:^1.2.2, minipass-pipeline@npm:^1.2.4": +"minipass-pipeline@npm:^1.2.4": version: 1.2.4 resolution: "minipass-pipeline@npm:1.2.4" dependencies: @@ -13880,7 +15550,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^3.0.0, minipass@npm:^3.1.1": +"minipass@npm:^3.0.0": version: 3.3.6 resolution: "minipass@npm:3.3.6" dependencies: @@ -13889,68 +15559,37 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0": - version: 5.0.0 - resolution: "minipass@npm:5.0.0" - checksum: 425dab288738853fded43da3314a0b5c035844d6f3097a8e3b5b29b328da8f3c1af6fc70618b32c29ff906284cf6406b6841376f21caaadd0793c1d5a6a620ea - languageName: node - linkType: hard - -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": - version: 7.0.4 - resolution: "minipass@npm:7.0.4" - checksum: 87585e258b9488caf2e7acea242fd7856bbe9a2c84a7807643513a338d66f368c7d518200ad7b70a508664d408aa000517647b2930c259a8b1f9f0984f344a21 - languageName: node - linkType: hard - -"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": - version: 2.1.2 - resolution: "minizlib@npm:2.1.2" - dependencies: - minipass: ^3.0.0 - yallist: ^4.0.0 - checksum: f1fdeac0b07cf8f30fcf12f4b586795b97be856edea22b5e9072707be51fc95d41487faec3f265b42973a304fe3a64acd91a44a3826a963e37b37bafde0212c3 +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 2bfd325b95c555f2b4d2814d49325691c7bee937d753814861b0b49d5edcda55cbbf22b6b6a60bb91eddac8668771f03c5ff647dcd9d0f798e9548b9cdc46ee3 languageName: node linkType: hard -"mississippi@npm:^3.0.0": - version: 3.0.0 - resolution: "mississippi@npm:3.0.0" +"minizlib@npm:^3.0.1": + version: 3.0.2 + resolution: "minizlib@npm:3.0.2" dependencies: - concat-stream: ^1.5.0 - duplexify: ^3.4.2 - end-of-stream: ^1.1.0 - flush-write-stream: ^1.0.0 - from2: ^2.1.0 - parallel-transform: ^1.1.0 - pump: ^3.0.0 - pumpify: ^1.3.3 - stream-each: ^1.1.0 - through2: ^2.0.0 - checksum: 84b3d9889621d293f9a596bafe60df863b330c88fc19215ced8f603c605fc7e1bf06f8e036edf301bd630a03fd5d9d7d23d5d6b9a4802c30ca864d800f0bd9f8 + minipass: ^7.1.2 + checksum: 493bed14dcb6118da7f8af356a8947cf1473289c09658e5aabd69a737800a8c3b1736fb7d7931b722268a9c9bc038a6d53c049b6a6af24b34a121823bb709996 languageName: node linkType: hard -"mixin-deep@npm:^1.2.0": - version: 1.3.2 - resolution: "mixin-deep@npm:1.3.2" - dependencies: - for-in: ^1.0.2 - is-extendable: ^1.0.1 - checksum: 820d5a51fcb7479f2926b97f2c3bb223546bc915e6b3a3eb5d906dda871bba569863595424a76682f2b15718252954644f3891437cb7e3f220949bed54b1750d +"mitt@npm:^3.0.1": + version: 3.0.1 + resolution: "mitt@npm:3.0.1" + checksum: b55a489ac9c2949ab166b7f060601d3b6d893a852515ae9eca4e11df01c013876df777ea109317622b5c1c60e8aae252558e33c8c94e14124db38f64a39614b1 languageName: node linkType: hard -"mkdirp@npm:1.x, mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": - version: 1.0.4 - resolution: "mkdirp@npm:1.0.4" - bin: - mkdirp: bin/cmd.js - checksum: a96865108c6c3b1b8e1d5e9f11843de1e077e57737602de1b82030815f311be11f96f09cce59bd5b903d0b29834733e5313f9301e3ed6d6f6fba2eae0df4298f +"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": + version: 0.5.3 + resolution: "mkdirp-classic@npm:0.5.3" + checksum: 3f4e088208270bbcc148d53b73e9a5bd9eef05ad2cbf3b3d0ff8795278d50dd1d11a8ef1875ff5aea3fa888931f95bfcb2ad5b7c1061cfefd6284d199e6776ac languageName: node linkType: hard -"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.3, mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.6, mkdirp@npm:~0.5.1": +"mkdirp@npm:^0.5.4, mkdirp@npm:~0.5.1": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" dependencies: @@ -13961,29 +15600,12 @@ __metadata: languageName: node linkType: hard -"mlly@npm:^1.4.0, mlly@npm:^1.6.1": - version: 1.6.1 - resolution: "mlly@npm:1.6.1" - dependencies: - acorn: ^8.11.3 - pathe: ^1.1.2 - pkg-types: ^1.0.3 - ufo: ^1.3.2 - checksum: c40a547dba8f6b2a5a840899d49f4c9550c233d47fd7bd75f4ac27f388047bad655ad86684329809c1640df4373b45bec77304f73530ca4354bc1199700e2a46 - languageName: node - linkType: hard - -"move-concurrently@npm:^1.0.1": - version: 1.0.1 - resolution: "move-concurrently@npm:1.0.1" - dependencies: - aproba: ^1.1.1 - copy-concurrently: ^1.0.0 - fs-write-stream-atomic: ^1.0.8 - mkdirp: ^0.5.1 - rimraf: ^2.5.4 - run-queue: ^1.0.3 - checksum: 4ea3296c150b09e798177847f673eb5783f8ca417ba806668d2c631739f653e1a735f19fb9b6e2f5e25ee2e4c0a6224732237a8e4f84c764e99d7462d258209e +"mkdirp@npm:^3.0.1": + version: 3.0.1 + resolution: "mkdirp@npm:3.0.1" + bin: + mkdirp: dist/cjs/src/bin.js + checksum: 972deb188e8fb55547f1e58d66bd6b4a3623bf0c7137802582602d73e6480c1c2268dcbafbfb1be466e00cc7e56ac514d7fd9334b7cf33e3e2ab547c16f83a8d languageName: node linkType: hard @@ -13994,58 +15616,50 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.2": - version: 2.1.2 - resolution: "ms@npm:2.1.2" - checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f - languageName: node - linkType: hard - -"ms@npm:2.1.3, ms@npm:^2.1.1": +"ms@npm:2.1.3, ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d languageName: node linkType: hard -"msw@npm:^0.44.2": - version: 0.44.2 - resolution: "msw@npm:0.44.2" - dependencies: - "@mswjs/cookies": ^0.2.2 - "@mswjs/interceptors": ^0.17.2 - "@open-draft/until": ^1.0.3 - "@types/cookie": ^0.4.1 - "@types/js-levenshtein": ^1.1.1 - chalk: 4.1.1 - chokidar: ^3.4.2 - cookie: ^0.4.2 - graphql: ^16.3.0 - headers-polyfill: ^3.0.4 - inquirer: ^8.2.0 - is-node-process: ^1.0.1 - js-levenshtein: ^1.1.6 - node-fetch: ^2.6.7 - outvariant: ^1.3.0 - path-to-regexp: ^6.2.0 - statuses: ^2.0.0 - strict-event-emitter: ^0.2.0 - type-fest: ^1.2.2 - yargs: ^17.3.1 +"msw@npm:^2.7.0": + version: 2.11.2 + resolution: "msw@npm:2.11.2" + dependencies: + "@bundled-es-modules/cookie": ^2.0.1 + "@bundled-es-modules/statuses": ^1.0.1 + "@inquirer/confirm": ^5.0.0 + "@mswjs/interceptors": ^0.39.1 + "@open-draft/deferred-promise": ^2.2.0 + "@open-draft/until": ^2.1.0 + "@types/cookie": ^0.6.0 + "@types/statuses": ^2.0.4 + graphql: ^16.8.1 + headers-polyfill: ^4.0.2 + is-node-process: ^1.2.0 + outvariant: ^1.4.3 + path-to-regexp: ^6.3.0 + picocolors: ^1.1.1 + rettime: ^0.7.0 + strict-event-emitter: ^0.5.1 + tough-cookie: ^6.0.0 + type-fest: ^4.26.1 + yargs: ^17.7.2 peerDependencies: - typescript: ">= 4.2.x <= 4.7.x" + typescript: ">= 4.8.x" peerDependenciesMeta: typescript: optional: true bin: msw: cli/index.js - checksum: 739d536ee09d1c0a2cbc9dbe917f167c42115a6548f99780850ce9a63a5e7c377cf9b5f1a3b497e85ce7304025ab22966e997fe73adbd8d2ab968b8685f15a24 + checksum: 599aa3ed6e5043479bef473fa427a7aaf343d32aedba301ec62cac1a30c50b2a2898c4b9fe11b939ab03768807860eff64ce2fbdd28f78d0c6be4f4318d8b276 languageName: node linkType: hard "multer@npm:^1.4.5-lts.1": - version: 1.4.5-lts.1 - resolution: "multer@npm:1.4.5-lts.1" + version: 1.4.5-lts.2 + resolution: "multer@npm:1.4.5-lts.2" dependencies: append-field: ^1.0.0 busboy: ^1.0.0 @@ -14054,42 +15668,37 @@ __metadata: object-assign: ^4.1.1 type-is: ^1.6.4 xtend: ^4.0.0 - checksum: d6dfa78a6ec592b74890412f8962da8a87a3dcfe20f612e039b735b8e0faa72c735516c447f7de694ee0d981eb0a1b892fb9e2402a0348dc6091d18c38d89ecc - languageName: node - linkType: hard - -"multicast-dns-service-types@npm:^1.1.0": - version: 1.1.0 - resolution: "multicast-dns-service-types@npm:1.1.0" - checksum: 0979fca1cce85484d256e4db3af591d941b41a61f134da3607213d2624c12ed5b8a246565cb19a9b3cb542819e8fbc71a90b07e77023ee6a9515540fe1d371f7 + checksum: b6f76a24c8fbc4d3ed5696ff8c98e126e7831d26f85e0ce17ab8d77e33a9ec14e33e4d05ea5e4e748e63a1b695cf450c2b05d8eee58484a74a1c13f459429713 languageName: node linkType: hard -"multicast-dns@npm:^6.0.1": - version: 6.2.3 - resolution: "multicast-dns@npm:6.2.3" +"multicast-dns@npm:^7.2.5": + version: 7.2.5 + resolution: "multicast-dns@npm:7.2.5" dependencies: - dns-packet: ^1.3.1 + dns-packet: ^5.2.2 thunky: ^1.0.2 bin: multicast-dns: cli.js - checksum: f515b49ca964429ab48a4ac8041fcf969c927aeb49ab65288bd982e52c849a870fc3b03565780b0d194a1a02da8821f28b6425e48e95b8107bc9fcc92f571a6f + checksum: 00b8a57df152d4cd0297946320a94b7c3cdf75a46a2247f32f958a8927dea42958177f9b7fdae69fab2e4e033fb3416881af1f5e9055a3e1542888767139e2fb languageName: node linkType: hard -"mute-stream@npm:0.0.8": - version: 0.0.8 - resolution: "mute-stream@npm:0.0.8" - checksum: ff48d251fc3f827e5b1206cda0ffdaec885e56057ee86a3155e1951bc940fd5f33531774b1cc8414d7668c10a8907f863f6561875ee6e8768931a62121a531a1 +"mute-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "mute-stream@npm:2.0.0" + checksum: d2e4fd2f5aa342b89b98134a8d899d8ef9b0a6d69274c4af9df46faa2d97aeb1f2ce83d867880d6de63643c52386579b99139801e24e7526c3b9b0a6d1e18d6c languageName: node linkType: hard -"nan@npm:^2.12.1": - version: 2.19.0 - resolution: "nan@npm:2.19.0" +"mz@npm:^2.7.0": + version: 2.7.0 + resolution: "mz@npm:2.7.0" dependencies: - node-gyp: latest - checksum: 29a894a003c1954c250d690768c30e69cd91017e2e5eb21b294380f7cace425559508f5ffe3e329a751307140b0bd02f83af040740fa4def1a3869be6af39600 + any-promise: ^1.0.0 + object-assign: ^4.0.1 + thenify-all: ^1.0.0 + checksum: 8427de0ece99a07e9faed3c0c6778820d7543e3776f9a84d22cf0ec0a8eb65f6e9aee9c9d353ff9a105ff62d33a9463c6ca638974cc652ee8140cd1e35951c87 languageName: node linkType: hard @@ -14102,47 +15711,26 @@ __metadata: languageName: node linkType: hard -"nanoclone@npm:^0.2.1": - version: 0.2.1 - resolution: "nanoclone@npm:0.2.1" - checksum: 96b2954e22f70561f41e20d69856266c65583c2a441dae108f1dc71b716785d2c8038dac5f1d5e92b117aed3825f526b53139e2e5d6e6db8a77cfa35b3b8bf40 - languageName: node - linkType: hard - -"nanoid@npm:^3.3.7": - version: 3.3.7 - resolution: "nanoid@npm:3.3.7" +"nanoid@npm:^3.3.11": + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" bin: nanoid: bin/nanoid.cjs - checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2 + checksum: 3be20d8866a57a6b6d218e82549711c8352ed969f9ab3c45379da28f405363ad4c9aeb0b39e9abc101a529ca65a72ff9502b00bf74a912c4b64a9d62dfd26c29 languageName: node linkType: hard -"nanomatch@npm:^1.2.9": - version: 1.2.13 - resolution: "nanomatch@npm:1.2.13" - dependencies: - arr-diff: ^4.0.0 - array-unique: ^0.3.2 - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - fragment-cache: ^0.2.1 - is-windows: ^1.0.2 - kind-of: ^6.0.2 - object.pick: ^1.3.0 - regex-not: ^1.0.0 - snapdragon: ^0.8.1 - to-regex: ^3.0.1 - checksum: 54d4166d6ef08db41252eb4e96d4109ebcb8029f0374f9db873bd91a1f896c32ec780d2a2ea65c0b2d7caf1f28d5e1ea33746a470f32146ac8bba821d80d38d8 +"napi-build-utils@npm:^2.0.0": + version: 2.0.0 + resolution: "napi-build-utils@npm:2.0.0" + checksum: 532121efd2dd2272595580bca48859e404bdd4ed455a72a28432ba44868c38d0e64fac3026a8f82bf8563d2a18b32eb9a1d59e601a9da4e84ba4d45b922297f5 languageName: node linkType: hard -"native-url@npm:^0.2.6": - version: 0.2.6 - resolution: "native-url@npm:0.2.6" - dependencies: - querystring: ^0.2.0 - checksum: d56a67b32e635c4944985f551a9976dfe609a3947810791c50f5c37cff1d9dd5fe040184989d104be8752582b79dc4e726f2a9c075d691ecce86b31ae9387f1b +"natural-compare-lite@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare-lite@npm:1.4.0" + checksum: 5222ac3986a2b78dd6069ac62cbb52a7bf8ffc90d972ab76dfe7b01892485d229530ed20d0c62e79a6b363a663b273db3bde195a1358ce9e5f779d4453887225 languageName: node linkType: hard @@ -14153,31 +15741,31 @@ __metadata: languageName: node linkType: hard -"negotiator@npm:0.6.3, negotiator@npm:^0.6.3": +"negotiator@npm:0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" checksum: b8ffeb1e262eff7968fc90a2b6767b04cfd9842582a9d0ece0af7049537266e7b2506dfb1d107a32f06dd849ab2aea834d5830f7f4d0e5cb7d36e1ae55d021d9 languageName: node linkType: hard -"neo-async@npm:^2.5.0, neo-async@npm:^2.6.1, neo-async@npm:^2.6.2": - version: 2.6.2 - resolution: "neo-async@npm:2.6.2" - checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 20ebfe79b2d2e7cf9cbc8239a72662b584f71164096e6e8896c8325055497c96f6b80cd22c258e8a2f2aa382a787795ec3ee8b37b422a302c7d4381b0d5ecfbb languageName: node linkType: hard -"next-tick@npm:^1.1.0": - version: 1.1.0 - resolution: "next-tick@npm:1.1.0" - checksum: 83b5cf36027a53ee6d8b7f9c0782f2ba87f4858d977342bfc3c20c21629290a2111f8374d13a81221179603ffc4364f38374b5655d17b6a8f8a8c77bdea4fe8b +"negotiator@npm:~0.6.4": + version: 0.6.4 + resolution: "negotiator@npm:0.6.4" + checksum: 7ded10aa02a0707d1d12a9973fdb5954f98547ca7beb60e31cb3a403cc6e8f11138db7a3b0128425cf836fc85d145ec4ce983b2bdf83dca436af879c2d683510 languageName: node linkType: hard -"nice-try@npm:^1.0.4": - version: 1.0.5 - resolution: "nice-try@npm:1.0.5" - checksum: 0b4af3b5bb5d86c289f7a026303d192a7eb4417231fe47245c460baeabae7277bcd8fd9c728fb6bd62c30b3e15cd6620373e2cf33353b095d8b403d3e8a15aff +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 languageName: node linkType: hard @@ -14191,7 +15779,25 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9": +"node-abi@npm:^3.3.0": + version: 3.77.0 + resolution: "node-abi@npm:3.77.0" + dependencies: + semver: ^7.3.5 + checksum: 62ab12fe90e2c2081c1e0dfc3819d60dc181aff36c5dd2ca99cece3f1f19efb284be90353bd0cb911c44f77a23ce111635937e8c6b48dd8cfaa24e34221d4a9f + languageName: node + linkType: hard + +"node-addon-api@npm:^7.0.0": + version: 7.1.1 + resolution: "node-addon-api@npm:7.1.1" + dependencies: + node-gyp: latest + checksum: 46051999e3289f205799dfaf6bcb017055d7569090f0004811110312e2db94cb4f8654602c7eb77a60a1a05142cc2b96e1b5c56ca4622c41a5c6370787faaf30 + languageName: node + linkType: hard + +"node-fetch@npm:^2.6.9": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -14205,14 +15811,7 @@ __metadata: languageName: node linkType: hard -"node-forge@npm:^0.10.0": - version: 0.10.0 - resolution: "node-forge@npm:0.10.0" - checksum: 5aa6dc9922e424a20ef101d2f517418e2bc9cfc0255dd22e0701c0fad1568445f510ee67f6f3fcdf085812c4ca1b847b8ba45683b34776828e41f5c1794e42e1 - languageName: node - linkType: hard - -"node-forge@npm:^1.3.1": +"node-forge@npm:^1, node-forge@npm:^1.3.1": version: 1.3.1 resolution: "node-forge@npm:1.3.1" checksum: 08fb072d3d670599c89a1704b3e9c649ff1b998256737f0e06fbd1a5bf41cae4457ccaee32d95052d80bbafd9ffe01284e078c8071f0267dc9744e51c5ed42a9 @@ -14220,95 +15819,43 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 10.1.0 - resolution: "node-gyp@npm:10.1.0" + version: 11.4.2 + resolution: "node-gyp@npm:11.4.2" 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: ^3.0.0 + make-fetch-happen: ^14.0.3 + nopt: ^8.0.0 + proc-log: ^5.0.0 semver: ^7.3.5 - tar: ^6.1.2 - which: ^4.0.0 + tar: ^7.4.3 + tinyglobby: ^0.2.12 + which: ^5.0.0 bin: - node-gyp: bin/node-gyp.js - checksum: 72e2ab4b23fc32007a763da94018f58069fc0694bf36115d49a2b195c8831e12cf5dd1e7a3718fa85c06969aedf8fc126722d3b672ec1cb27e06ed33caee3c60 - languageName: node - linkType: hard - -"node-int64@npm:^0.4.0": - version: 0.4.0 - resolution: "node-int64@npm:0.4.0" - checksum: d0b30b1ee6d961851c60d5eaa745d30b5c95d94bc0e74b81e5292f7c42a49e3af87f1eb9e89f59456f80645d679202537de751b7d72e9e40ceea40c5e449057e - languageName: node - linkType: hard - -"node-libs-browser@npm:^2.2.1": - version: 2.2.1 - resolution: "node-libs-browser@npm:2.2.1" - dependencies: - assert: ^1.1.1 - browserify-zlib: ^0.2.0 - buffer: ^4.3.0 - console-browserify: ^1.1.0 - constants-browserify: ^1.0.0 - crypto-browserify: ^3.11.0 - domain-browser: ^1.1.1 - events: ^3.0.0 - https-browserify: ^1.0.0 - os-browserify: ^0.3.0 - path-browserify: 0.0.1 - process: ^0.11.10 - punycode: ^1.2.4 - querystring-es3: ^0.2.0 - readable-stream: ^2.3.3 - stream-browserify: ^2.0.1 - stream-http: ^2.7.2 - string_decoder: ^1.0.0 - timers-browserify: ^2.0.4 - tty-browserify: 0.0.0 - url: ^0.11.0 - util: ^0.11.0 - vm-browserify: ^1.0.1 - checksum: 41fa7927378edc0cb98a8cc784d3f4a47e43378d3b42ec57a23f81125baa7287c4b54d6d26d062072226160a3ce4d8b7a62e873d2fb637aceaddf71f5a26eca0 - languageName: node - linkType: hard - -"node-notifier@npm:^8.0.0": - version: 8.0.2 - resolution: "node-notifier@npm:8.0.2" - dependencies: - growly: ^1.3.0 - is-wsl: ^2.2.0 - semver: ^7.3.2 - shellwords: ^0.1.1 - uuid: ^8.3.0 - which: ^2.0.2 - checksum: 7db1683003f6aaa4324959dfa663cd56e301ccc0165977a9e7737989ffe3b4763297f9fc85f44d0662b63a4fd85516eda43411b492a4d2fae207afb23773f912 + node-gyp: bin/node-gyp.js + checksum: d8041cee7ec60c86fb2961d77c12a2d083a481fb28b08e6d9583153186c0e7766044dc30bdb1f3ac01ddc5763b83caeed3d1ea35787ec4ffd8cc4aeedfc34f2b languageName: node linkType: hard -"node-releases@npm:^1.1.61": - version: 1.1.77 - resolution: "node-releases@npm:1.1.77" - checksum: eb2fcb45310e7d77f82bfdadeca546a698d258e011f15d88ad9a452a5e838a672ec532906581096ca19c66284a788330c3b09227ffc540e67228730f41b9c2e2 +"node-int64@npm:^0.4.0": + version: 0.4.0 + resolution: "node-int64@npm:0.4.0" + checksum: d0b30b1ee6d961851c60d5eaa745d30b5c95d94bc0e74b81e5292f7c42a49e3af87f1eb9e89f59456f80645d679202537de751b7d72e9e40ceea40c5e449057e languageName: node linkType: hard -"node-releases@npm:^2.0.14": - version: 2.0.14 - resolution: "node-releases@npm:2.0.14" - checksum: 59443a2f77acac854c42d321bf1b43dea0aef55cd544c6a686e9816a697300458d4e82239e2d794ea05f7bbbc8a94500332e2d3ac3f11f52e4b16cbe638b3c41 +"node-releases@npm:^2.0.21": + version: 2.0.21 + resolution: "node-releases@npm:2.0.21" + checksum: 191f8245e18272971650eb45151c5891313bca27507a8f634085bd8c98a9cb9492686ef6182176866ceebff049646ef6cd5fb5ca46d5b5ca00ce2c69185d84c4 languageName: node linkType: hard "nodemailer@npm:^6.9.1": - version: 6.9.13 - resolution: "nodemailer@npm:6.9.13" - checksum: 1b591ef480be2ff69480127cbff819e6593b1ef263b6f920e1a4e83e40280582daf7a14a809ef92f9828e2a70bdb3ce22b11924e209f2afe4975f9ff37e08e9d + version: 6.10.1 + resolution: "nodemailer@npm:6.10.1" + checksum: 39e9208e13c40b58c59242205bce855e74def25d953070ab6a5b1c23b0bf37df0725b3c6dea52d4220e2e60dd1fffcd486a697dece79afdf98842aae6395d393 languageName: node linkType: hard @@ -14332,46 +15879,14 @@ __metadata: languageName: node linkType: hard -"nopt@npm:^7.0.0": - version: 7.2.0 - resolution: "nopt@npm:7.2.0" +"nopt@npm:^8.0.0": + version: 8.1.0 + resolution: "nopt@npm:8.1.0" dependencies: - abbrev: ^2.0.0 + abbrev: ^3.0.0 bin: nopt: bin/nopt.js - checksum: a9c0f57fb8cb9cc82ae47192ca2b7ef00e199b9480eed202482c962d61b59a7fbe7541920b2a5839a97b42ee39e288c0aed770e38057a608d7f579389dfde410 - languageName: node - linkType: hard - -"nopt@npm:~1.0.10": - version: 1.0.10 - resolution: "nopt@npm:1.0.10" - dependencies: - abbrev: 1 - bin: - nopt: ./bin/nopt.js - checksum: f62575aceaa3be43f365bf37a596b89bbac2e796b001b6d2e2a85c2140a4e378ff919e2753ccba959c4fd344776fc88c29b393bc167fa939fb1513f126f4cd45 - languageName: node - linkType: hard - -"normalize-package-data@npm:^2.3.2, normalize-package-data@npm:^2.5.0": - version: 2.5.0 - resolution: "normalize-package-data@npm:2.5.0" - dependencies: - hosted-git-info: ^2.1.4 - resolve: ^1.10.0 - semver: 2 || 3 || 4 || 5 - validate-npm-package-license: ^3.0.1 - checksum: 7999112efc35a6259bc22db460540cae06564aa65d0271e3bdfa86876d08b0e578b7b5b0028ee61b23f1cae9fc0e7847e4edc0948d3068a39a2a82853efc8499 - languageName: node - linkType: hard - -"normalize-path@npm:^2.1.1": - version: 2.1.1 - resolution: "normalize-path@npm:2.1.1" - dependencies: - remove-trailing-separator: ^1.0.1 - checksum: 7e9cbdcf7f5b8da7aa191fbfe33daf290cdcd8c038f422faf1b8a83c972bf7a6d94c5be34c4326cb00fb63bc0fd97d9fbcfaf2e5d6142332c2cd36d2e1b86cea + checksum: 49cfd3eb6f565e292bf61f2ff1373a457238804d5a5a63a8d786c923007498cba89f3648e3b952bc10203e3e7285752abf5b14eaf012edb821e84f24e881a92a languageName: node linkType: hard @@ -14389,35 +15904,14 @@ __metadata: languageName: node linkType: hard -"normalize-url@npm:1.9.1": - version: 1.9.1 - resolution: "normalize-url@npm:1.9.1" - dependencies: - object-assign: ^4.0.1 - prepend-http: ^1.0.0 - query-string: ^4.1.0 - sort-keys: ^1.0.0 - checksum: 4b03c22bebbb822874ce3b9204367ad1f27c314ae09b13aa201de730b3cf95f00dadf378277a56062322968c95c06e5764d01474d26af8b43d20bc4c8c491f84 - languageName: node - linkType: hard - -"normalize-url@npm:^3.0.0": - version: 3.3.0 - resolution: "normalize-url@npm:3.3.0" - checksum: f6aa4a1a94c3b799812f3e7fc987fb4599d869bfa8e9a160b6f2c5a2b4e62ada998d64dca30d9e20769d8bd95d3da1da3d4841dba2cc3c4d85364e1eb46219a2 - languageName: node - linkType: hard - -"npm-run-path@npm:^2.0.0": - version: 2.0.2 - resolution: "npm-run-path@npm:2.0.2" - dependencies: - path-key: ^2.0.0 - checksum: acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 4a4944631173e7d521d6b80e4c85ccaeceb2870f315584fa30121f505a6dfd86439c5e3fdd8cd9e0e291290c41d0c3599f0cb12ab356722ed242584c30348e50 languageName: node linkType: hard -"npm-run-path@npm:^4.0.0": +"npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" dependencies: @@ -14444,52 +15938,31 @@ __metadata: languageName: node linkType: hard -"num2fraction@npm:^1.2.2": - version: 1.2.2 - resolution: "num2fraction@npm:1.2.2" - checksum: 1da9c6797b505d3f5b17c7f694c4fa31565bdd5c0e5d669553253aed848a580804cd285280e8a73148bd9628839267daee4967f24b53d4e893e44b563e412635 - languageName: node - linkType: hard - "nwsapi@npm:^2.2.0": - version: 2.2.9 - resolution: "nwsapi@npm:2.2.9" - checksum: 3ab2bc47d5507a76e2fdee5aae7ea2875c6def912d0401126cad3e39825a7decb7a02622810c855a7902bd31e917e606b37882dca12b0ae54b4d3b70275de927 + version: 2.2.22 + resolution: "nwsapi@npm:2.2.22" + checksum: 9491f0396d8aaf7fd1f9ebbbbff5d9bb9090e5d200263cf31b117bbaad7eb79da86b4c9b9bcd64c4b35f6d7e1630d14ee21c0959c01131e89c1c5e22d72530bf languageName: node linkType: hard -"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": +"object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f languageName: node linkType: hard -"object-copy@npm:^0.1.0": - version: 0.1.0 - resolution: "object-copy@npm:0.1.0" - dependencies: - copy-descriptor: ^0.1.0 - define-property: ^0.2.5 - kind-of: ^3.0.3 - checksum: a9e35f07e3a2c882a7e979090360d1a20ab51d1fa19dfdac3aa8873b328a7c4c7683946ee97c824ae40079d848d6740a3788fa14f2185155dab7ed970a72c783 - languageName: node - linkType: hard - -"object-inspect@npm:^1.13.1": - version: 1.13.1 - resolution: "object-inspect@npm:1.13.1" - checksum: 7d9fa9221de3311dcb5c7c307ee5dc011cdd31dc43624b7c184b3840514e118e05ef0002be5388304c416c0eb592feb46e983db12577fc47e47d5752fbbfb61f +"object-hash@npm:^3.0.0": + version: 3.0.0 + resolution: "object-hash@npm:3.0.0" + checksum: 80b4904bb3857c52cc1bfd0b52c0352532ca12ed3b8a6ff06a90cd209dfda1b95cee059a7625eb9da29537027f68ac4619363491eedb2f5d3dddbba97494fd6c languageName: node linkType: hard -"object-is@npm:^1.1.5": - version: 1.1.6 - resolution: "object-is@npm:1.1.6" - dependencies: - call-bind: ^1.0.7 - define-properties: ^1.2.1 - checksum: 3ea22759967e6f2380a2cbbd0f737b42dc9ddb2dfefdb159a1b927fea57335e1b058b564bfa94417db8ad58cddab33621a035de6f5e5ad56d89f2dd03e66c6a1 +"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": + version: 1.13.4 + resolution: "object-inspect@npm:1.13.4" + checksum: 582810c6a8d2ef988ea0a39e69e115a138dad8f42dd445383b394877e5816eb4268489f316a6f74ee9c4e0a984b3eab1028e3e79d62b1ed67c726661d55c7a8b languageName: node linkType: hard @@ -14500,39 +15973,33 @@ __metadata: languageName: node linkType: hard -"object-visit@npm:^1.0.0": - version: 1.0.1 - resolution: "object-visit@npm:1.0.1" - dependencies: - isobject: ^3.0.0 - checksum: b0ee07f5bf3bb881b881ff53b467ebbde2b37ebb38649d6944a6cd7681b32eedd99da9bd1e01c55facf81f54ed06b13af61aba6ad87f0052982995e09333f790 - languageName: node - linkType: hard - -"object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": - version: 4.1.5 - resolution: "object.assign@npm:4.1.5" +"object.assign@npm:^4.1.4, object.assign@npm:^4.1.7": + version: 4.1.7 + resolution: "object.assign@npm:4.1.7" dependencies: - call-bind: ^1.0.5 + call-bind: ^1.0.8 + call-bound: ^1.0.3 define-properties: ^1.2.1 - has-symbols: ^1.0.3 + es-object-atoms: ^1.0.0 + has-symbols: ^1.1.0 object-keys: ^1.1.1 - checksum: f9aeac0541661370a1fc86e6a8065eb1668d3e771f7dbb33ee54578201336c057b21ee61207a186dd42db0c62201d91aac703d20d12a79fc79c353eed44d4e25 + checksum: 60e07d2651cf4f5528c485f1aa4dbded9b384c47d80e8187cefd11320abb1aebebf78df5483451dfa549059f8281c21f7b4bf7d19e9e5e97d8d617df0df298de languageName: node linkType: hard -"object.entries@npm:^1.1.0, object.entries@npm:^1.1.7": - version: 1.1.8 - resolution: "object.entries@npm:1.1.8" +"object.entries@npm:^1.1.9": + version: 1.1.9 + resolution: "object.entries@npm:1.1.9" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.4 define-properties: ^1.2.1 - es-object-atoms: ^1.0.0 - checksum: 5314877cb637ef3437a30bba61d9bacdb3ce74bf73ac101518be0633c37840c8cc67407edb341f766e8093b3d7516d5c3358f25adfee4a2c697c0ec4c8491907 + es-object-atoms: ^1.1.1 + checksum: 0ab2ef331c4d6a53ff600a5d69182948d453107c3a1f7fd91bc29d387538c2aba21d04949a74f57c21907208b1f6fb175567fd1f39f1a7a4046ba1bca762fb41 languageName: node linkType: hard -"object.fromentries@npm:^2.0.7": +"object.fromentries@npm:^2.0.8": version: 2.0.8 resolution: "object.fromentries@npm:2.0.8" dependencies: @@ -14544,7 +16011,7 @@ __metadata: languageName: node linkType: hard -"object.getownpropertydescriptors@npm:^2.0.3, object.getownpropertydescriptors@npm:^2.1.0": +"object.getownpropertydescriptors@npm:^2.1.0": version: 2.1.8 resolution: "object.getownpropertydescriptors@npm:2.1.8" dependencies: @@ -14559,7 +16026,7 @@ __metadata: languageName: node linkType: hard -"object.groupby@npm:^1.0.1": +"object.groupby@npm:^1.0.3": version: 1.0.3 resolution: "object.groupby@npm:1.0.3" dependencies: @@ -14570,34 +16037,15 @@ __metadata: languageName: node linkType: hard -"object.hasown@npm:^1.1.3": - version: 1.1.4 - resolution: "object.hasown@npm:1.1.4" - dependencies: - define-properties: ^1.2.1 - es-abstract: ^1.23.2 - es-object-atoms: ^1.0.0 - checksum: bc46eb5ca22106fcd07aab1411508c2c68b7565fe8fb272f166fb9bf203972e8b5c86a5a4b2c86204beead0626a7a4119d32cefbaf7c5dd57b400bf9e6363cb6 - languageName: node - linkType: hard - -"object.pick@npm:^1.3.0": - version: 1.3.0 - resolution: "object.pick@npm:1.3.0" - dependencies: - isobject: ^3.0.1 - checksum: 77fb6eed57c67adf75e9901187e37af39f052ef601cb4480386436561357eb9e459e820762f01fd02c5c1b42ece839ad393717a6d1850d848ee11fbabb3e580a - languageName: node - linkType: hard - -"object.values@npm:^1.1.0, object.values@npm:^1.1.6, object.values@npm:^1.1.7": - version: 1.2.0 - resolution: "object.values@npm:1.2.0" +"object.values@npm:^1.1.0, object.values@npm:^1.1.6, object.values@npm:^1.2.1": + version: 1.2.1 + resolution: "object.values@npm:1.2.1" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.3 define-properties: ^1.2.1 es-object-atoms: ^1.0.0 - checksum: 51fef456c2a544275cb1766897f34ded968b22adfc13ba13b5e4815fdaf4304a90d42a3aee114b1f1ede048a4890381d47a5594d84296f2767c6a0364b9da8fa + checksum: f9b9a2a125ccf8ded29414d7c056ae0d187b833ee74919821fc60d7e216626db220d9cb3cf33f965c84aaaa96133626ca13b80f3c158b673976dc8cfcfcd26bb languageName: node linkType: hard @@ -14615,7 +16063,7 @@ __metadata: languageName: node linkType: hard -"on-finished@npm:2.4.1": +"on-finished@npm:2.4.1, on-finished@npm:^2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -14624,10 +16072,10 @@ __metadata: languageName: node linkType: hard -"on-headers@npm:~1.0.2": - version: 1.0.2 - resolution: "on-headers@npm:1.0.2" - checksum: 2bf13467215d1e540a62a75021e8b318a6cfc5d4fc53af8e8f84ad98dbcea02d506c6d24180cd62e1d769c44721ba542f3154effc1f7579a8288c9f7873ed8e5 +"on-headers@npm:~1.1.0": + version: 1.1.0 + resolution: "on-headers@npm:1.1.0" + checksum: 98aa64629f986fb8cc4517dd8bede73c980e31208cba97f4442c330959f60ced3dc6214b83420491f5111fc7c4f4343abe2ea62c85f505cf041d67850f238776 languageName: node linkType: hard @@ -14640,7 +16088,7 @@ __metadata: languageName: node linkType: hard -"onetime@npm:^5.1.0": +"onetime@npm:^5.1.2": version: 5.1.2 resolution: "onetime@npm:5.1.2" dependencies: @@ -14649,34 +16097,14 @@ __metadata: languageName: node linkType: hard -"open@npm:^7.0.2": - version: 7.4.2 - resolution: "open@npm:7.4.2" - dependencies: - is-docker: ^2.0.0 - is-wsl: ^2.1.1 - checksum: 3333900ec0e420d64c23b831bc3467e57031461d843c801f569b2204a1acc3cd7b3ec3c7897afc9dde86491dfa289708eb92bba164093d8bd88fb2c231843c91 - languageName: node - linkType: hard - -"opn@npm:^5.5.0": - version: 5.5.0 - resolution: "opn@npm:5.5.0" - dependencies: - is-wsl: ^1.1.0 - checksum: 35b677b5a1fd6c8cb1996b0607671ba79f7ce9fa029217d54eafaf6bee13eb7e700691c6a415009140fd02a435fffdfd143875f3b233b60f3f9d631c6f6b81a0 - languageName: node - linkType: hard - -"optimize-css-assets-webpack-plugin@npm:5.0.4": - version: 5.0.4 - resolution: "optimize-css-assets-webpack-plugin@npm:5.0.4" +"open@npm:^8.0.9, open@npm:^8.4.0": + version: 8.4.2 + resolution: "open@npm:8.4.2" dependencies: - cssnano: ^4.1.10 - last-call-webpack-plugin: ^3.0.0 - peerDependencies: - webpack: ^4.0.0 - checksum: bcd509eaab2a6f0ed8396fe847f4f0da73655a54f4c418fa30dc1fc4a0b1b620f38e2fcd6bcb369e2a6cf4530995b371e9d12011566ac7ffe6ac6aec2ab0a4fb + define-lazy-prop: ^2.0.0 + is-docker: ^2.1.1 + is-wsl: ^2.2.0 + checksum: 6388bfff21b40cb9bd8f913f9130d107f2ed4724ea81a8fd29798ee322b361ca31fa2cdfb491a5c31e43a3996cfe9566741238c7a741ada8d7af1cb78d85cf26 languageName: node linkType: hard @@ -14694,62 +16122,35 @@ __metadata: languageName: node linkType: hard -"optionator@npm:^0.9.1": - version: 0.9.3 - resolution: "optionator@npm:0.9.3" +"optionator@npm:^0.9.1, optionator@npm:^0.9.3": + version: 0.9.4 + resolution: "optionator@npm:0.9.4" dependencies: - "@aashutoshrathi/word-wrap": ^1.2.3 deep-is: ^0.1.3 fast-levenshtein: ^2.0.6 levn: ^0.4.1 prelude-ls: ^1.2.1 type-check: ^0.4.0 - checksum: 09281999441f2fe9c33a5eeab76700795365a061563d66b098923eb719251a42bdbe432790d35064d0816ead9296dbeb1ad51a733edf4167c96bd5d0882e428a - languageName: node - linkType: hard - -"ora@npm:^5.4.1": - version: 5.4.1 - resolution: "ora@npm:5.4.1" - 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 - checksum: 28d476ee6c1049d68368c0dc922e7225e3b5600c3ede88fade8052837f9ed342625fdaa84a6209302587c8ddd9b664f71f0759833cbdb3a4cf81344057e63c63 - languageName: node - linkType: hard - -"os-browserify@npm:^0.3.0": - version: 0.3.0 - resolution: "os-browserify@npm:0.3.0" - checksum: 16e37ba3c0e6a4c63443c7b55799ce4066d59104143cb637ecb9fce586d5da319cdca786ba1c867abbe3890d2cbf37953f2d51eea85e20dd6c4570d6c54bfebf - languageName: node - linkType: hard - -"os-tmpdir@npm:~1.0.2": - version: 1.0.2 - resolution: "os-tmpdir@npm:1.0.2" - checksum: 5666560f7b9f10182548bf7013883265be33620b1c1b4a4d405c25be2636f970c5488ff3e6c48de75b55d02bde037249fe5dbfbb4c0fb7714953d56aed062e6d + word-wrap: ^1.2.5 + checksum: ecbd010e3dc73e05d239976422d9ef54a82a13f37c11ca5911dff41c98a6c7f0f163b27f922c37e7f8340af9d36febd3b6e9cef508f3339d4c393d7276d716bb languageName: node linkType: hard -"outvariant@npm:^1.2.1, outvariant@npm:^1.3.0": - version: 1.4.2 - resolution: "outvariant@npm:1.4.2" - checksum: 5d9e2b3edb1cc8be9cbfc1c8c97e8b05137c4384bbfc56e0a465de26c5d2f023e65732ddcda9d46599b06d667fbc0de32c30d2ecd11f6f3f43bcf8ce0d320918 +"outvariant@npm:^1.4.0, outvariant@npm:^1.4.3": + version: 1.4.3 + resolution: "outvariant@npm:1.4.3" + checksum: 4a3551fb2b45309e585eebf88bad094dbe56ac6d3a28d59dd2e4050b431aa2beb6097a0763fce3cd82ca0f077026f380a9b60fffc306aaf430141421e7a7b6ed languageName: node linkType: hard -"p-each-series@npm:^2.1.0": - version: 2.2.0 - resolution: "p-each-series@npm:2.2.0" - checksum: 5fbe2f1f1966f55833bd401fe36f7afe410707d5e9fb6032c6dde8aa716d50521c3bb201fdb584130569b5941d5e84993e09e0b3f76a474288e0ede8f632983c +"own-keys@npm:^1.0.1": + version: 1.0.1 + resolution: "own-keys@npm:1.0.1" + dependencies: + get-intrinsic: ^1.2.6 + object-keys: ^1.1.1 + safe-push-apply: ^1.0.0 + checksum: cc9dd7d85c4ccfbe8109fce307d581ac7ede7b26de892b537873fbce2dc6a206d89aea0630dbb98e47ce0873517cefeaa7be15fcf94aaf4764a3b34b474a5b61 languageName: node linkType: hard @@ -14778,15 +16179,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^4.0.0": - version: 4.0.0 - resolution: "p-limit@npm:4.0.0" - dependencies: - yocto-queue: ^1.0.0 - checksum: 01d9d70695187788f984226e16c903475ec6a947ee7b21948d6f597bed788e3112cc7ec2e171c1d37125057a5f45f3da21d8653e04a3a793589e12e9e80e756b - languageName: node - linkType: hard - "p-locate@npm:^3.0.0": version: 3.0.0 resolution: "p-locate@npm:3.0.0" @@ -14805,23 +16197,23 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^2.0.0": - version: 2.1.0 - resolution: "p-map@npm:2.1.0" - checksum: 9e3ad3c9f6d75a5b5661bcad78c91f3a63849189737cd75e4f1225bf9ac205194e5c44aac2ef6f09562b1facdb9bd1425584d7ac375bfaa17b3f1a142dab936d +"p-locate@npm:^5.0.0": + version: 5.0.0 + resolution: "p-locate@npm:5.0.0" + dependencies: + p-limit: ^3.0.2 + checksum: 1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 languageName: node linkType: hard -"p-map@npm:^4.0.0": - version: 4.0.0 - resolution: "p-map@npm:4.0.0" - dependencies: - aggregate-error: ^3.0.0 - checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c +"p-map@npm:^7.0.2": + version: 7.0.3 + resolution: "p-map@npm:7.0.3" + checksum: 8c92d533acf82f0d12f7e196edccff773f384098bbb048acdd55a08778ce4fc8889d8f1bde72969487bd96f9c63212698d79744c20bedfce36c5b00b46d369f8 languageName: node linkType: hard -"p-queue@npm:^6.6.1": +"p-queue@npm:^6": version: 6.6.2 resolution: "p-queue@npm:6.6.2" dependencies: @@ -14831,16 +16223,7 @@ __metadata: languageName: node linkType: hard -"p-retry@npm:^3.0.1": - version: 3.0.1 - resolution: "p-retry@npm:3.0.1" - dependencies: - retry: ^0.12.0 - checksum: 702efc63fc13ef7fc0bab9a1b08432ab38a0236efcbce64af0cf692030ba6ed8009f29ba66e3301cb98dc69ef33e7ccab29ba1ac2bea897f802f81f4f7e468dd - languageName: node - linkType: hard - -"p-retry@npm:^4.0.0": +"p-retry@npm:^4, p-retry@npm:^4.5.0": version: 4.6.2 resolution: "p-retry@npm:4.6.2" dependencies: @@ -14866,25 +16249,21 @@ __metadata: languageName: node linkType: hard -"pako@npm:^1.0.10, pako@npm:^1.0.11, pako@npm:^1.0.6, pako@npm:~1.0.5": - version: 1.0.11 - resolution: "pako@npm:1.0.11" - checksum: 1be2bfa1f807608c7538afa15d6f25baa523c30ec870a3228a89579e474a4d992f4293859524e46d5d87fd30fa17c5edf34dbef0671251d9749820b488660b16 +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 58ee9538f2f762988433da00e26acc788036914d57c71c246bf0be1b60cdbd77dd60b6a3e1a30465f0b248aeb80079e0b34cb6050b1dfa18c06953bb1cbc7602 languageName: node linkType: hard -"parallel-transform@npm:^1.1.0": - version: 1.2.0 - resolution: "parallel-transform@npm:1.2.0" - dependencies: - cyclist: ^1.0.1 - inherits: ^2.0.3 - readable-stream: ^2.1.5 - checksum: ab6ddc1a662cefcfb3d8d546a111763d3b223f484f2e9194e33aefd8f6760c319d0821fd22a00a3adfbd45929b50d2c84cc121389732f013c2ae01c226269c27 +"pako@npm:^1.0.10, pako@npm:^1.0.11, pako@npm:^1.0.6": + version: 1.0.11 + resolution: "pako@npm:1.0.11" + checksum: 1be2bfa1f807608c7538afa15d6f25baa523c30ec870a3228a89579e474a4d992f4293859524e46d5d87fd30fa17c5edf34dbef0671251d9749820b488660b16 languageName: node linkType: hard -"param-case@npm:^3.0.3, param-case@npm:^3.0.4": +"param-case@npm:^3.0.4": version: 3.0.4 resolution: "param-case@npm:3.0.4" dependencies: @@ -14903,45 +16282,22 @@ __metadata: languageName: node linkType: hard -"parse-asn1@npm:^5.0.0, parse-asn1@npm:^5.1.7": - version: 5.1.7 - resolution: "parse-asn1@npm:5.1.7" - dependencies: - asn1.js: ^4.10.1 - browserify-aes: ^1.2.0 - evp_bytestokey: ^1.0.3 - hash-base: ~3.0 - pbkdf2: ^3.1.2 - safe-buffer: ^5.2.1 - checksum: 93c7194c1ed63a13e0b212d854b5213ad1aca0ace41c66b311e97cca0519cf9240f79435a0306a3b412c257f0ea3f1953fd0d9549419a0952c9e995ab361fd6c - languageName: node - linkType: hard - -"parse-entities@npm:^2.0.0": - version: 2.0.0 - resolution: "parse-entities@npm:2.0.0" - dependencies: - character-entities: ^1.0.0 - character-entities-legacy: ^1.0.0 - character-reference-invalid: ^1.0.0 - is-alphanumerical: ^1.0.0 - is-decimal: ^1.0.0 - is-hexadecimal: ^1.0.0 - checksum: 7addfd3e7d747521afac33c8121a5f23043c6973809756920d37e806639b4898385d386fcf4b3c8e2ecf1bc28aac5ae97df0b112d5042034efbe80f44081ebce - languageName: node - linkType: hard - -"parse-json@npm:^4.0.0": - version: 4.0.0 - resolution: "parse-json@npm:4.0.0" +"parse-entities@npm:^4.0.0": + version: 4.0.2 + resolution: "parse-entities@npm:4.0.2" dependencies: - error-ex: ^1.3.1 - json-parse-better-errors: ^1.0.1 - checksum: 0fe227d410a61090c247e34fa210552b834613c006c2c64d9a05cfe9e89cf8b4246d1246b1a99524b53b313e9ac024438d0680f67e33eaed7e6f38db64cfe7b5 + "@types/unist": ^2.0.0 + character-entities-legacy: ^3.0.0 + character-reference-invalid: ^2.0.0 + decode-named-character-reference: ^1.0.0 + is-alphanumerical: ^2.0.0 + is-decimal: ^2.0.0 + is-hexadecimal: ^2.0.0 + checksum: db22b46da1a62af00409c929ac49fbd306b5ebf0dbacf4646d2ae2b58616ef90a40eedc282568a3cf740fac2a7928bc97146973a628f6977ca274dedc2ad6edc languageName: node linkType: hard -"parse-json@npm:^5.0.0": +"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" dependencies: @@ -14960,7 +16316,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": +"parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 @@ -14977,20 +16333,6 @@ __metadata: languageName: node linkType: hard -"pascalcase@npm:^0.1.1": - version: 0.1.1 - resolution: "pascalcase@npm:0.1.1" - checksum: f83681c3c8ff75fa473a2bb2b113289952f802ff895d435edd717e7cb898b0408cbdb247117a938edcbc5d141020909846cc2b92c47213d764e2a94d2ad2b925 - languageName: node - linkType: hard - -"path-browserify@npm:0.0.1": - version: 0.0.1 - resolution: "path-browserify@npm:0.0.1" - checksum: ae8dcd45d0d3cfbaf595af4f206bf3ed82d77f72b4877ae7e77328079e1468c84f9386754bb417d994d5a19bf47882fd253565c18441cd5c5c90ae5187599e35 - languageName: node - linkType: hard - "path-case@npm:^3.0.4": version: 3.0.4 resolution: "path-case@npm:3.0.4" @@ -15001,13 +16343,6 @@ __metadata: languageName: node linkType: hard -"path-dirname@npm:^1.0.0": - version: 1.0.2 - resolution: "path-dirname@npm:1.0.2" - checksum: 0d2f6604ae05a252a0025318685f290e2764ecf9c5436f203cdacfc8c0b17c24cdedaa449d766beb94ab88cc7fc70a09ec21e7933f31abc2b719180883e5e33f - languageName: node - linkType: hard - "path-exists@npm:^3.0.0": version: 3.0.0 resolution: "path-exists@npm:3.0.0" @@ -15029,20 +16364,6 @@ __metadata: languageName: node linkType: hard -"path-is-inside@npm:^1.0.2": - version: 1.0.2 - resolution: "path-is-inside@npm:1.0.2" - checksum: 0b5b6c92d3018b82afb1f74fe6de6338c4c654de4a96123cb343f2b747d5606590ac0c890f956ed38220a4ab59baddfd7b713d78a62d240b20b14ab801fa02cb - languageName: node - linkType: hard - -"path-key@npm:^2.0.0, path-key@npm:^2.0.1": - version: 2.0.1 - resolution: "path-key@npm:2.0.1" - checksum: f7ab0ad42fe3fb8c7f11d0c4f849871e28fbd8e1add65c370e422512fc5887097b9cf34d09c1747d45c942a8c1e26468d6356e2df3f740bf177ab8ca7301ebfd - languageName: node - linkType: hard - "path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" @@ -15050,1097 +16371,1048 @@ __metadata: languageName: node linkType: hard -"path-parse@npm:^1.0.6, path-parse@npm:^1.0.7": +"path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a languageName: node linkType: hard -"path-scurry@npm:^1.10.2": - version: 1.10.2 - resolution: "path-scurry@npm:1.10.2" +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" dependencies: lru-cache: ^10.2.0 minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 - checksum: 6739b4290f7d1a949c61c758b481c07ac7d1a841964c68cf5e1fa153d7e18cbde4872b37aadf9c5173c800d627f219c47945859159de36c977dd82419997b9b8 - languageName: node - linkType: hard - -"path-to-regexp@npm:0.1.7": - version: 0.1.7 - resolution: "path-to-regexp@npm:0.1.7" - checksum: 69a14ea24db543e8b0f4353305c5eac6907917031340e5a8b37df688e52accd09e3cebfe1660b70d76b6bd89152f52183f28c74813dbf454ba1a01c82a38abce + checksum: 890d5abcd593a7912dcce7cf7c6bf7a0b5648e3dee6caf0712c126ca0a65c7f3d7b9d769072a4d1baf370f61ce493ab5b038d59988688e0c5f3f646ee3c69023 languageName: node linkType: hard -"path-to-regexp@npm:^1.7.0": - version: 1.8.0 - resolution: "path-to-regexp@npm:1.8.0" +"path-scurry@npm:^2.0.0": + version: 2.0.0 + resolution: "path-scurry@npm:2.0.0" dependencies: - isarray: 0.0.1 - checksum: 709f6f083c0552514ef4780cb2e7e4cf49b0cc89a97439f2b7cc69a608982b7690fb5d1720a7473a59806508fc2dae0be751ba49f495ecf89fd8fbc62abccbcd - languageName: node - linkType: hard - -"path-to-regexp@npm:^6.2.0": - version: 6.2.2 - resolution: "path-to-regexp@npm:6.2.2" - checksum: b7b0005c36f5099f9ed1fb20a820d2e4ed1297ffe683ea1d678f5e976eb9544f01debb281369dabdc26da82e6453901bf71acf2c7ed14b9243536c2a45286c33 - languageName: node - linkType: hard - -"path-type@npm:^4.0.0": - version: 4.0.0 - resolution: "path-type@npm:4.0.0" - checksum: 5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45 - languageName: node - linkType: hard - -"pathe@npm:^1.1.1, pathe@npm:^1.1.2": - version: 1.1.2 - resolution: "pathe@npm:1.1.2" - checksum: ec5f778d9790e7b9ffc3e4c1df39a5bb1ce94657a4e3ad830c1276491ca9d79f189f47609884671db173400256b005f4955f7952f52a2aeb5834ad5fb4faf134 - languageName: node - linkType: hard - -"pathval@npm:^1.1.1": - version: 1.1.1 - resolution: "pathval@npm:1.1.1" - checksum: 090e3147716647fb7fb5b4b8c8e5b55e5d0a6086d085b6cd23f3d3c01fcf0ff56fd3cc22f2f4a033bd2e46ed55d61ed8379e123b42afe7d531a2a5fc8bb556d6 + lru-cache: ^11.0.0 + minipass: ^7.1.2 + checksum: 9953ce3857f7e0796b187a7066eede63864b7e1dfc14bf0484249801a5ab9afb90d9a58fc533ebb1b552d23767df8aa6a2c6c62caf3f8a65f6ce336a97bbb484 languageName: node linkType: hard -"pbkdf2@npm:^3.0.3, pbkdf2@npm:^3.1.2": - version: 3.1.2 - resolution: "pbkdf2@npm:3.1.2" - dependencies: - create-hash: ^1.1.2 - create-hmac: ^1.1.4 - ripemd160: ^2.0.1 - safe-buffer: ^5.0.1 - sha.js: ^2.4.8 - checksum: 2c950a100b1da72123449208e231afc188d980177d021d7121e96a2de7f2abbc96ead2b87d03d8fe5c318face097f203270d7e27908af9f471c165a4e8e69c92 +"path-to-regexp@npm:0.1.12": + version: 0.1.12 + resolution: "path-to-regexp@npm:0.1.12" + checksum: ab237858bee7b25ecd885189f175ab5b5161e7b712b360d44f5c4516b8d271da3e4bf7bf0a7b9153ecb04c7d90ce8ff5158614e1208819cf62bac2b08452722e languageName: node linkType: hard -"pdf-lib@npm:^1.17.1": - version: 1.17.1 - resolution: "pdf-lib@npm:1.17.1" +"path-to-regexp@npm:^1.7.0": + version: 1.9.0 + resolution: "path-to-regexp@npm:1.9.0" dependencies: - "@pdf-lib/standard-fonts": ^1.0.0 - "@pdf-lib/upng": ^1.0.1 - pako: ^1.0.11 - tslib: ^1.11.1 - checksum: 0dae766f23de60ff071368073990cca0d30fb5d104c50a17fee00f0659a491f66e45ce80b1bbfe254e6915a5bc9079f42501dfff2e37f8f76a8807d3e321b19a - languageName: node - linkType: hard - -"performance-now@npm:^2.1.0": - version: 2.1.0 - resolution: "performance-now@npm:2.1.0" - checksum: 534e641aa8f7cba160f0afec0599b6cecefbb516a2e837b512be0adbe6c1da5550e89c78059c7fabc5c9ffdf6627edabe23eb7c518c4500067a898fa65c2b550 - languageName: node - linkType: hard - -"picocolors@npm:^0.2.1": - version: 0.2.1 - resolution: "picocolors@npm:0.2.1" - checksum: 3b0f441f0062def0c0f39e87b898ae7461c3a16ffc9f974f320b44c799418cabff17780ee647fda42b856a1dc45897e2c62047e1b546d94d6d5c6962f45427b2 - languageName: node - linkType: hard - -"picocolors@npm:^1.0.0": - version: 1.0.0 - resolution: "picocolors@npm:1.0.0" - checksum: a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 - languageName: node - linkType: hard - -"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf - languageName: node - linkType: hard - -"pify@npm:^2.0.0": - version: 2.3.0 - resolution: "pify@npm:2.3.0" - checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + isarray: 0.0.1 + checksum: 5b2ac9cab2a9f82effd30a35164b20998b18d99d96608281dd2cab6e66c0e4536187970369b185ab21d3815da1ecb7dcb2d5f97a4bf0ee6e31a9612299fca147 languageName: node linkType: hard -"pify@npm:^3.0.0": - version: 3.0.0 - resolution: "pify@npm:3.0.0" - checksum: 6cdcbc3567d5c412450c53261a3f10991665d660961e06605decf4544a61a97a54fefe70a68d5c37080ff9d6f4cf51444c90198d1ba9f9309a6c0d6e9f5c4fde +"path-to-regexp@npm:^6.3.0": + version: 6.3.0 + resolution: "path-to-regexp@npm:6.3.0" + checksum: eca78602e6434a1b6799d511d375ec044e8d7e28f5a48aa5c28d57d8152fb52f3fc62fb1cfc5dfa2198e1f041c2a82ed14043d75740a2fe60e91b5089a153250 languageName: node linkType: hard -"pify@npm:^4.0.1": - version: 4.0.1 - resolution: "pify@npm:4.0.1" - checksum: 9c4e34278cb09987685fa5ef81499c82546c033713518f6441778fbec623fc708777fe8ac633097c72d88470d5963094076c7305cafc7ad340aae27cfacd856b +"path-to-regexp@npm:^8.0.0": + version: 8.3.0 + resolution: "path-to-regexp@npm:8.3.0" + checksum: 73e0d3db449f9899692b10be8480bbcfa294fd575be2d09bce3e63f2f708d1fccd3aaa8591709f8b82062c528df116e118ff9df8f5c52ccc4c2443a90be73e10 languageName: node linkType: hard -"pinkie-promise@npm:^2.0.0": - version: 2.0.1 - resolution: "pinkie-promise@npm:2.0.1" - dependencies: - pinkie: ^2.0.0 - checksum: b53a4a2e73bf56b6f421eef711e7bdcb693d6abb474d57c5c413b809f654ba5ee750c6a96dd7225052d4b96c4d053cdcb34b708a86fceed4663303abee52fcca +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45 languageName: node linkType: hard -"pinkie@npm:^2.0.0": - version: 2.0.4 - resolution: "pinkie@npm:2.0.4" - checksum: b12b10afea1177595aab036fc220785488f67b4b0fc49e7a27979472592e971614fa1c728e63ad3e7eb748b4ec3c3dbd780819331dad6f7d635c77c10537b9db +"path2d@npm:^0.2.1": + version: 0.2.2 + resolution: "path2d@npm:0.2.2" + checksum: 06f07f20797163d9807c211bc3e2b4edac462790c0cbe774bc681f18cfeba27a7cdd2d539e62a6863ff8d0fcfe4c5f6f20463b608f3dd32e44bba7be6f632f04 languageName: node linkType: hard -"pirates@npm:^4.0.1": - version: 4.0.6 - resolution: "pirates@npm:4.0.6" - checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 +"pathe@npm:^1.1.2": + version: 1.1.2 + resolution: "pathe@npm:1.1.2" + checksum: ec5f778d9790e7b9ffc3e4c1df39a5bb1ce94657a4e3ad830c1276491ca9d79f189f47609884671db173400256b005f4955f7952f52a2aeb5834ad5fb4faf134 languageName: node linkType: hard -"pkg-dir@npm:^3.0.0": - version: 3.0.0 - resolution: "pkg-dir@npm:3.0.0" - dependencies: - find-up: ^3.0.0 - checksum: 70c9476ffefc77552cc6b1880176b71ad70bfac4f367604b2b04efd19337309a4eec985e94823271c7c0e83946fa5aeb18cd360d15d10a5d7533e19344bfa808 +"pathe@npm:^2.0.3": + version: 2.0.3 + resolution: "pathe@npm:2.0.3" + checksum: 0602bdd4acb54d91044e0c56f1fb63467ae7d44ab3afea1f797947b0eb2b4d1d91cf0d58d065fdb0a8ab0c4acbbd8d3a5b424983eaf10dd5285d37a16f6e3ee9 languageName: node linkType: hard -"pkg-dir@npm:^4.1.0, pkg-dir@npm:^4.2.0": - version: 4.2.0 - resolution: "pkg-dir@npm:4.2.0" - dependencies: - find-up: ^4.0.0 - checksum: 9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 +"pathval@npm:^2.0.0": + version: 2.0.1 + resolution: "pathval@npm:2.0.1" + checksum: 280e71cfd86bb5d7ff371fe2752997e5fa82901fcb209abf19d4457b7814f1b4a17845dfb17bd28a596ccdb0ecea178720ce23dacfa9c841f37804b700647810 languageName: node linkType: hard -"pkg-types@npm:^1.0.3": - version: 1.1.0 - resolution: "pkg-types@npm:1.1.0" +"pdf-lib@npm:^1.17.1": + version: 1.17.1 + resolution: "pdf-lib@npm:1.17.1" dependencies: - confbox: ^0.1.7 - mlly: ^1.6.1 - pathe: ^1.1.2 - checksum: 9cd3684e308c622db79efc8edc9291662e01cb42ed624ea2fa5400fb6eab94679b4e5b28808e9b763298a023c2381fd72a363a1c84a9073c96609af4c5c59f8f + "@pdf-lib/standard-fonts": ^1.0.0 + "@pdf-lib/upng": ^1.0.1 + pako: ^1.0.11 + tslib: ^1.11.1 + checksum: 0dae766f23de60ff071368073990cca0d30fb5d104c50a17fee00f0659a491f66e45ce80b1bbfe254e6915a5bc9079f42501dfff2e37f8f76a8807d3e321b19a languageName: node linkType: hard -"pkg-up@npm:3.1.0": - version: 3.1.0 - resolution: "pkg-up@npm:3.1.0" +"pdfjs-dist@npm:4.8.69": + version: 4.8.69 + resolution: "pdfjs-dist@npm:4.8.69" dependencies: - find-up: ^3.0.0 - checksum: 5bac346b7c7c903613c057ae3ab722f320716199d753f4a7d053d38f2b5955460f3e6ab73b4762c62fd3e947f58e04f1343e92089e7bb6091c90877406fcd8c8 + canvas: ^3.0.0-rc2 + path2d: ^0.2.1 + dependenciesMeta: + canvas: + optional: true + path2d: + optional: true + checksum: 6c26d79a3f8796c7bb9f9ecabbf4c356edac3fb32e5ecb86b8ca649b4a217221c486df416b704a52ea0643aad9f29ad30b05ec6f894b3f95194fb001b7841058 languageName: node linkType: hard -"pnp-webpack-plugin@npm:1.6.4": - version: 1.6.4 - resolution: "pnp-webpack-plugin@npm:1.6.4" - dependencies: - ts-pnp: ^1.1.6 - checksum: 0606a63db96400b07f182300168298da9518727a843f9e10cf5045d2a102a4be06bb18c73dc481281e3e0f1ed8d04ef0d285a342b6dcd0eff1340e28e5d2328d +"performance-now@npm:^2.1.0": + version: 2.1.0 + resolution: "performance-now@npm:2.1.0" + checksum: 534e641aa8f7cba160f0afec0599b6cecefbb516a2e837b512be0adbe6c1da5550e89c78059c7fabc5c9ffdf6627edabe23eb7c518c4500067a898fa65c2b550 languageName: node linkType: hard -"portfinder@npm:^1.0.26": - version: 1.0.32 - resolution: "portfinder@npm:1.0.32" - dependencies: - async: ^2.6.4 - debug: ^3.2.7 - mkdirp: ^0.5.6 - checksum: 116b4aed1b9e16f6d5503823d966d9ffd41b1c2339e27f54c06cd2f3015a9d8ef53e2a53b57bc0a25af0885977b692007353aa28f9a0a98a44335cb50487240d +"picocolors@npm:1.1.1, picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 languageName: node linkType: hard -"posix-character-classes@npm:^0.1.0": - version: 0.1.1 - resolution: "posix-character-classes@npm:0.1.1" - checksum: dedb99913c60625a16050cfed2fb5c017648fc075be41ac18474e1c6c3549ef4ada201c8bd9bd006d36827e289c571b6092e1ef6e756cdbab2fd7046b25c6442 +"picocolors@npm:^0.2.1": + version: 0.2.1 + resolution: "picocolors@npm:0.2.1" + checksum: 3b0f441f0062def0c0f39e87b898ae7461c3a16ffc9f974f320b44c799418cabff17780ee647fda42b856a1dc45897e2c62047e1b546d94d6d5c6962f45427b2 languageName: node linkType: hard -"possible-typed-array-names@npm:^1.0.0": - version: 1.0.0 - resolution: "possible-typed-array-names@npm:1.0.0" - checksum: b32d403ece71e042385cc7856385cecf1cd8e144fa74d2f1de40d1e16035dba097bc189715925e79b67bdd1472796ff168d3a90d296356c9c94d272d5b95f3ae +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf languageName: node linkType: hard -"postcss-attribute-case-insensitive@npm:^4.0.1": - version: 4.0.2 - resolution: "postcss-attribute-case-insensitive@npm:4.0.2" - dependencies: - postcss: ^7.0.2 - postcss-selector-parser: ^6.0.2 - checksum: e9cf4b61f443bf302dcd1110ef38d6a808fa38ae5d85bfd0aaaa6d35bef3825e0434f1aed8eb9596a5d88f21580ce8b9cd0098414d8490293ef71149695cae9a +"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 6817fb74eb745a71445debe1029768de55fd59a42b75606f478ee1d0dc1aa6e78b711d041a7c9d5550e042642029b7f373dc1a43b224c4b7f12d23436735dba0 languageName: node linkType: hard -"postcss-browser-comments@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-browser-comments@npm:3.0.0" - dependencies: - postcss: ^7 - peerDependencies: - browserslist: ^4 - checksum: 6e8cfae4c71cf7b5d4741e19021f3e3d81d772372a9e12f5c675e25bc3ea45fe5154fd0ee055ee041aee8b484c59875fdf15df3cec5e7fd4cf3209bc5ef0b515 +"pify@npm:^2.3.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba languageName: node linkType: hard -"postcss-calc@npm:^7.0.1": - version: 7.0.5 - resolution: "postcss-calc@npm:7.0.5" - dependencies: - postcss: ^7.0.27 - postcss-selector-parser: ^6.0.2 - postcss-value-parser: ^4.0.2 - checksum: 03640d493fb0e557634ab23e5d1eb527b014fb491ac3e62b45e28f5a6ef57e25a209f82040ce54c40d5a1a7307597a55d3fa6e8cece0888261a66bc75e39a68b +"pirates@npm:^4.0.1, pirates@npm:^4.0.4": + version: 4.0.7 + resolution: "pirates@npm:4.0.7" + checksum: 3dcbaff13c8b5bc158416feb6dc9e49e3c6be5fddc1ea078a05a73ef6b85d79324bbb1ef59b954cdeff000dbf000c1d39f32dc69310c7b78fbada5171b583e40 languageName: node linkType: hard -"postcss-color-functional-notation@npm:^2.0.1": - version: 2.0.1 - resolution: "postcss-color-functional-notation@npm:2.0.1" +"pkg-dir@npm:^4.1.0, pkg-dir@npm:^4.2.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" dependencies: - postcss: ^7.0.2 - postcss-values-parser: ^2.0.0 - checksum: 0bfd1fa93bc54a07240d821d091093256511f70f0df5349e27e4d8b034ee3345f0ae58674ce425be6a91cc934325b2ce36ecddbf958fa8805fed6647cf671348 + find-up: ^4.0.0 + checksum: 9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 languageName: node linkType: hard -"postcss-color-gray@npm:^5.0.0": - version: 5.0.0 - resolution: "postcss-color-gray@npm:5.0.0" +"pkg-up@npm:^3.1.0": + version: 3.1.0 + resolution: "pkg-up@npm:3.1.0" dependencies: - "@csstools/convert-colors": ^1.4.0 - postcss: ^7.0.5 - postcss-values-parser: ^2.0.0 - checksum: 81a62b3e2c170ffadc085c1643a7b5f1c153837d7ca228b07df88b9aeb0ec9088a92f8d919a748137ead3936e8dac2606e32b14b5166a59143642c8573949db5 + find-up: ^3.0.0 + checksum: 5bac346b7c7c903613c057ae3ab722f320716199d753f4a7d053d38f2b5955460f3e6ab73b4762c62fd3e947f58e04f1343e92089e7bb6091c90877406fcd8c8 languageName: node linkType: hard -"postcss-color-hex-alpha@npm:^5.0.3": - version: 5.0.3 - resolution: "postcss-color-hex-alpha@npm:5.0.3" - dependencies: - postcss: ^7.0.14 - postcss-values-parser: ^2.0.1 - checksum: 0a0ccb42c7c6a271ffd3c8b123b9c67744827d4b810b759731bc702fea1e00f05f08479ec7cbd8dfa47bc20510830a69f1e316a5724b9e53d5fdc6fabf90afc4 +"possible-typed-array-names@npm:^1.0.0": + version: 1.1.0 + resolution: "possible-typed-array-names@npm:1.1.0" + checksum: cfcd4f05264eee8fd184cd4897a17890561d1d473434b43ab66ad3673d9c9128981ec01e0cb1d65a52cd6b1eebfb2eae1e53e39b2e0eca86afc823ede7a4f41b languageName: node linkType: hard -"postcss-color-mod-function@npm:^3.0.3": - version: 3.0.3 - resolution: "postcss-color-mod-function@npm:3.0.3" +"postcss-attribute-case-insensitive@npm:^5.0.2": + version: 5.0.2 + resolution: "postcss-attribute-case-insensitive@npm:5.0.2" dependencies: - "@csstools/convert-colors": ^1.4.0 - postcss: ^7.0.2 - postcss-values-parser: ^2.0.0 - checksum: ecbf74e9395527aaf3e83b90b1a6c9bba0a1904038d8acef1f530d50a68d912d6b1af8df690342f942be8b89fa7dfaa35ae67cb5fb48013cb389ecb8c74deadb + postcss-selector-parser: ^6.0.10 + peerDependencies: + postcss: ^8.2 + checksum: c0b8139f37e68dba372724cba03a53c30716224f0085f98485cada99489beb7c3da9d598ffc1d81519b59d9899291712c9041c250205e6ec0b034bb2c144dcf9 languageName: node linkType: hard -"postcss-color-rebeccapurple@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-color-rebeccapurple@npm:4.0.1" - dependencies: - postcss: ^7.0.2 - postcss-values-parser: ^2.0.0 - checksum: a7b1a204dfc5163ac4195cc3cb0c7b1bba9561feab49d24be8a17d695d6b69fd92f3da23d638260fe7e9d5076cf81bb798b25134fa2a2fbf7f74b0dda2829a96 +"postcss-browser-comments@npm:^4": + version: 4.0.0 + resolution: "postcss-browser-comments@npm:4.0.0" + peerDependencies: + browserslist: ">=4" + postcss: ">=8" + checksum: 9b8e7094838c2d7bd1ab3ca9cb8d0a78a9a6c8e22f43133ba02db8862fb6c141630e9f590e46f7125cfa4723cacd27b74fa00c05a9907b364dc1f6f17cf13f6f languageName: node linkType: hard -"postcss-colormin@npm:^4.0.3": - version: 4.0.3 - resolution: "postcss-colormin@npm:4.0.3" +"postcss-calc@npm:^8.2.3": + version: 8.2.4 + resolution: "postcss-calc@npm:8.2.4" dependencies: - browserslist: ^4.0.0 - color: ^3.0.0 - has: ^1.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 9b2eab73cd227cbf296f1a2a6466047f6c70b918c3844535531fd87f31d7878e1a8d81e8803ffe2ee8c3330ea5bec65e358a0e0f33defcd758975064e07fe928 + postcss-selector-parser: ^6.0.9 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.2 + checksum: 314b4cebb0c4ed0cf8356b4bce71eca78f5a7842e6a3942a3bba49db168d5296b2bd93c3f735ae1c616f2651d94719ade33becc03c73d2d79c7394fb7f73eabb languageName: node linkType: hard -"postcss-convert-values@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-convert-values@npm:4.0.1" +"postcss-clamp@npm:^4.1.0": + version: 4.1.0 + resolution: "postcss-clamp@npm:4.1.0" dependencies: - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 71cac73f5befeb8bc16274e2aaabe1b8e0cb42a8b8641dc2aa61b1c502697b872a682c36f370cce325553bbfc859c38f2b064fae6f6469b1cada79e733559261 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.6 + checksum: 118eec936b3b035dc8d75c89973408f15c5a3de3d1ee210a2b3511e3e431d9c56e6f354b509a90540241e2225ffe3caaa2fdf25919c63348ce4583a28ada642c languageName: node linkType: hard -"postcss-custom-media@npm:^7.0.8": - version: 7.0.8 - resolution: "postcss-custom-media@npm:7.0.8" +"postcss-color-functional-notation@npm:^4.2.4": + version: 4.2.4 + resolution: "postcss-color-functional-notation@npm:4.2.4" dependencies: - postcss: ^7.0.14 - checksum: 3786eb10f238b22dc620cfcc9257779e27d8cee4510b3209d0ab67310e07dc68b69f3359db7a911f5e76df466f73d078fc80100943fe2e8fa9bcacf226705a2d + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: b763e164fe3577a1de96f75e4bf451585c4f80b8ce60799763a51582cc9402d76faed57324a5d5e5556d90ca7ea0ebde565acb820c95e04bee6f36a91b019831 languageName: node linkType: hard -"postcss-custom-properties@npm:^8.0.11": - version: 8.0.11 - resolution: "postcss-custom-properties@npm:8.0.11" +"postcss-color-hex-alpha@npm:^8.0.4": + version: 8.0.4 + resolution: "postcss-color-hex-alpha@npm:8.0.4" dependencies: - postcss: ^7.0.17 - postcss-values-parser: ^2.0.1 - checksum: cb1b47459a23ff2e48714c5d48d50070d573ef829dc7e57189d1b38c6fba0de7084f1acefbd84c61dd67e30bd9a7d154b22f195547728a9dc5f76f7d3f03ffea + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4 + checksum: a2f3173a60176cf0aea3b7ebbc799b2cb08229127f0fff708fa31efa14e4ded47ca49aff549d8ed92e74ffe24adee32d5b9d557dbde0524fde5fe389bc520b4e languageName: node linkType: hard -"postcss-custom-selectors@npm:^5.1.2": - version: 5.1.2 - resolution: "postcss-custom-selectors@npm:5.1.2" +"postcss-color-rebeccapurple@npm:^7.1.1": + version: 7.1.1 + resolution: "postcss-color-rebeccapurple@npm:7.1.1" dependencies: - postcss: ^7.0.2 - postcss-selector-parser: ^5.0.0-rc.3 - checksum: 26c83d348448f4ab5931cc1621606b09a6b1171e25fac2404073f3e298e77494ac87d4a21009679503b4895452810e93e618b5af26b4c7180a9013f283bb8088 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 03482f9b8170da0fa014c41a5d88bce7b987471fb73fc456d397222a2455c89ac7f974dd6ddf40fd31907e768aad158057164b7c5f62cee63a6ecf29d47d7467 languageName: node linkType: hard -"postcss-dir-pseudo-class@npm:^5.0.0": - version: 5.0.0 - resolution: "postcss-dir-pseudo-class@npm:5.0.0" +"postcss-colormin@npm:^5.3.1": + version: 5.3.1 + resolution: "postcss-colormin@npm:5.3.1" dependencies: - postcss: ^7.0.2 - postcss-selector-parser: ^5.0.0-rc.3 - checksum: 703156fc65f259ec2e86ba51d18370a6d3b71f2e6473c7d65694676a8f0152137b1997bc0a53f7f373c8c3e4d63c72f7b5e2049f2ef3a7276b49409395722044 + browserslist: ^4.21.4 + caniuse-api: ^3.0.0 + colord: ^2.9.1 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: e5778baab30877cd1f51e7dc9d2242a162aeca6360a52956acd7f668c5bc235c2ccb7e4df0370a804d65ebe00c5642366f061db53aa823f9ed99972cebd16024 languageName: node linkType: hard -"postcss-discard-comments@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-discard-comments@npm:4.0.2" +"postcss-convert-values@npm:^5.1.3": + version: 5.1.3 + resolution: "postcss-convert-values@npm:5.1.3" dependencies: - postcss: ^7.0.0 - checksum: b087d47649160b7c6236aba028d27f1796a0dcb21e9ffd0da62271171fc31b7f150ee6c7a24fa97e3f5cd1af92e0dc41cb2e2680a175da53f1e536c441bda56a + browserslist: ^4.21.4 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: df48cdaffabf9737f9cfdc58a3dc2841cf282506a7a944f6c70236cff295d3a69f63de6e0935eeb8a9d3f504324e5b4e240abc29e21df9e35a02585d3060aeb5 languageName: node linkType: hard -"postcss-discard-duplicates@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-discard-duplicates@npm:4.0.2" +"postcss-custom-media@npm:^8.0.2": + version: 8.0.2 + resolution: "postcss-custom-media@npm:8.0.2" dependencies: - postcss: ^7.0.0 - checksum: bd83647a8e5ea34b0cfe563d0c1410a0c9e742011aa67955709c5ecd2d2bb03b7016053781e975e4c802127d2f9a0cd9c22f1f2783b9d7b1c35487d60f7ea540 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.3 + checksum: 887bbbacf6f8fab688123796e5dc1e8283b99f21e4c674235bd929dc8018c50df8634ea08932033ec93baaca32670ef2b87e6632863e0b4d84847375dbde9366 languageName: node linkType: hard -"postcss-discard-empty@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-discard-empty@npm:4.0.1" +"postcss-custom-properties@npm:^12.1.10": + version: 12.1.11 + resolution: "postcss-custom-properties@npm:12.1.11" dependencies: - postcss: ^7.0.0 - checksum: 529b177bd2417fa5c8887891369b4538b858d767461192974a796814265794e08e0e624a9f4c566ed9f841af3faddb7e7a9c05c45cbbe2fb1f092f65bd227f5c + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 421f9d8d6b9c9066919f39251859232efc4dc5dd406c01e62e08734319a6ccda6d03dd6b46063ba0971053ac6ad3f7abade56d67650b3e370851b2291e8e45e6 languageName: node linkType: hard -"postcss-discard-overridden@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-discard-overridden@npm:4.0.1" +"postcss-custom-selectors@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-custom-selectors@npm:6.0.3" dependencies: - postcss: ^7.0.0 - checksum: b34d8cf58e4d13d99a3a9459f4833f1248ca897316bbb927375590feba35c24a0304084a6174a7bf3fe4ba3d5e5e9baf15ea938e7e5744e56915fa7ef6d91ee0 + postcss-selector-parser: ^6.0.4 + peerDependencies: + postcss: ^8.3 + checksum: 18080d60a8a77a76d8ddff185104d65418fffd02bbf9824499f807ced7941509ba63828ab8fe3ec1d6b0d6c72a482bb90a79d79cdef58e5f4b30113cca16e69b languageName: node linkType: hard -"postcss-double-position-gradients@npm:^1.0.0": - version: 1.0.0 - resolution: "postcss-double-position-gradients@npm:1.0.0" +"postcss-dir-pseudo-class@npm:^6.0.5": + version: 6.0.5 + resolution: "postcss-dir-pseudo-class@npm:6.0.5" dependencies: - postcss: ^7.0.5 - postcss-values-parser: ^2.0.0 - checksum: d2c4515b38a131ece44dba331aea2b3f9de646e30873b49f03fa8906179a3c43ddc43183bc4df609d8af0834e7c266ec3a63eaa4b3e96aa445d98ecdc12d2544 + postcss-selector-parser: ^6.0.10 + peerDependencies: + postcss: ^8.2 + checksum: 7810c439d8d1a9072c00f8ab39261a1492873ad170425745bd2819c59767db2f352f906588fc2a7d814e91117900563d7e569ecd640367c7332b26b9829927ef languageName: node linkType: hard -"postcss-env-function@npm:^2.0.2": - version: 2.0.2 - resolution: "postcss-env-function@npm:2.0.2" - dependencies: - postcss: ^7.0.2 - postcss-values-parser: ^2.0.0 - checksum: 0cfa2e6cad5123cce39dcf5af332ec3b0e3e09b54d5142225f255914079d2afda3f1052e60f4b6d3bccf7eb9d592325b7421f1ecc6674ccb13c267a721fc3128 +"postcss-discard-comments@npm:^5.1.2": + version: 5.1.2 + resolution: "postcss-discard-comments@npm:5.1.2" + peerDependencies: + postcss: ^8.2.15 + checksum: abfd064ebc27aeaf5037643dd51ffaff74d1fa4db56b0523d073ace4248cbb64ffd9787bd6924b0983a9d0bd0e9bf9f10d73b120e50391dc236e0d26c812fa2a languageName: node linkType: hard -"postcss-flexbugs-fixes@npm:4.2.1": - version: 4.2.1 - resolution: "postcss-flexbugs-fixes@npm:4.2.1" - dependencies: - postcss: ^7.0.26 - checksum: 51a626bc80dbe42fcc8b0895b4f23a558bb809ec52cdc05aa27fb24cdffd4c9dc53f25218085ddf407c53d76573bc6d7568219c912161609f02532a8f5f59b43 +"postcss-discard-duplicates@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-discard-duplicates@npm:5.1.0" + peerDependencies: + postcss: ^8.2.15 + checksum: 88d6964201b1f4ed6bf7a32cefe68e86258bb6e42316ca01d9b32bdb18e7887d02594f89f4a2711d01b51ea6e3fcca8c54be18a59770fe5f4521c61d3eb6ca35 languageName: node linkType: hard -"postcss-focus-visible@npm:^4.0.0": - version: 4.0.0 - resolution: "postcss-focus-visible@npm:4.0.0" - dependencies: - postcss: ^7.0.2 - checksum: a3c93fbb578608f60c5256d0989ae32fd9100f76fa053880e82bfeb43751e81a3a9e69bd8338e06579b7f56b230a80fb2cc671eff134f2682dcbec9bbb8658ae +"postcss-discard-empty@npm:^5.1.1": + version: 5.1.1 + resolution: "postcss-discard-empty@npm:5.1.1" + peerDependencies: + postcss: ^8.2.15 + checksum: 970adb12fae5c214c0768236ad9a821552626e77dedbf24a8213d19cc2c4a531a757cd3b8cdd3fc22fb1742471b8692a1db5efe436a71236dec12b1318ee8ff4 languageName: node linkType: hard -"postcss-focus-within@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-focus-within@npm:3.0.0" - dependencies: - postcss: ^7.0.2 - checksum: 2a31292cd9b929a2dd3171fc4ed287ea4a93c6ec8df1d634503fb97b8b30b33a2970b5e0df60634c60ff887923ab28641b624d566533096950e0a384705e9b90 +"postcss-discard-overridden@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-discard-overridden@npm:5.1.0" + peerDependencies: + postcss: ^8.2.15 + checksum: d64d4a545aa2c81b22542895cfcddc787d24119f294d35d29b0599a1c818b3cc51f4ee80b80f5a0a09db282453dd5ac49f104c2117cc09112d0ac9b40b499a41 languageName: node linkType: hard -"postcss-font-variant@npm:^4.0.0": - version: 4.0.1 - resolution: "postcss-font-variant@npm:4.0.1" +"postcss-double-position-gradients@npm:^3.1.2": + version: 3.1.2 + resolution: "postcss-double-position-gradients@npm:3.1.2" dependencies: - postcss: ^7.0.2 - checksum: d09836cd848e8c24d144484b6b9b175df26dca59e1a1579e790c7f3dcaea00944a8d0b6ac543f4c128de7b30fab9a0aef544d54789b3b55fd850770b172d980d + "@csstools/postcss-progressive-custom-properties": ^1.1.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: ca09bf2aefddc180f1c1413f379eef30d492b8147543413f7251216f23f413c394b2ed10b7cd255e87b18e0c8efe36087ea8b9bfb26a09813f9607a0b8e538b6 languageName: node linkType: hard -"postcss-gap-properties@npm:^2.0.0": - version: 2.0.0 - resolution: "postcss-gap-properties@npm:2.0.0" +"postcss-env-function@npm:^4.0.6": + version: 4.0.6 + resolution: "postcss-env-function@npm:4.0.6" dependencies: - postcss: ^7.0.2 - checksum: c842d105c9403e34a8fac7bdef33a63fcb6bde038b04b20cae1e719e1966632887545576af99a4a6f302c98ca029c6f0d746419f498ef7f6821177ba676e6c25 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4 + checksum: 645b2363cfa21be9dcce7fe4a0f172f0af70c00d6a4c1eb3d7ff7e9cfe26d569e291ec2533114d77b12d610023cd168a92d62c38f2fc969fa333b5ae2bff5ffe languageName: node linkType: hard -"postcss-image-set-function@npm:^3.0.1": - version: 3.0.1 - resolution: "postcss-image-set-function@npm:3.0.1" - dependencies: - postcss: ^7.0.2 - postcss-values-parser: ^2.0.0 - checksum: 43958d7c1f80077e60e066bdf61bc326bcac64c272f17fd7a0585a6934fb1ffc7ba7f560a39849f597e4d28b8ae3addd9279c7145b9478d2d91a7c54c2fefd8b +"postcss-flexbugs-fixes@npm:^5.0.2": + version: 5.0.2 + resolution: "postcss-flexbugs-fixes@npm:5.0.2" + peerDependencies: + postcss: ^8.1.4 + checksum: 022ddbcca8987303b9be75ff259e9de81b98643adac87a5fc6b52a0fcbbf95e1ac9fd508c4ed67cad76ac5d039b7123de8a0832329481b3c626f5d63f7a28f47 languageName: node linkType: hard -"postcss-initial@npm:^3.0.0": - version: 3.0.4 - resolution: "postcss-initial@npm:3.0.4" +"postcss-focus-visible@npm:^6.0.4": + version: 6.0.4 + resolution: "postcss-focus-visible@npm:6.0.4" dependencies: - postcss: ^7.0.2 - checksum: 710ab6cabc5970912c04314099f5334e7d901235014bb1462657e29f8dc97b6e51caa35f0beba7e5dbe440589ef9c1df13a89bc53d6e6aa664573b945f1630bb + postcss-selector-parser: ^6.0.9 + peerDependencies: + postcss: ^8.4 + checksum: acd010b9ddef9b86ffb5fa604c13515ba83e18bc5118dad0a1281150f412aa0ece056c2c5ac56b55e2599f53ab0f740f5ebfdc51e1f5cfe43b8130bac0096fcc languageName: node linkType: hard -"postcss-lab-function@npm:^2.0.1": - version: 2.0.1 - resolution: "postcss-lab-function@npm:2.0.1" +"postcss-focus-within@npm:^5.0.4": + version: 5.0.4 + resolution: "postcss-focus-within@npm:5.0.4" dependencies: - "@csstools/convert-colors": ^1.4.0 - postcss: ^7.0.2 - postcss-values-parser: ^2.0.0 - checksum: 598229a7a05803b18cccde28114833e910367c5954341bea03c7d7b7b5a667dfb6a77ef9dd4a16d80fdff8b10dd44c478602a7d56e43687c8687af3710b4706f + postcss-selector-parser: ^6.0.9 + peerDependencies: + postcss: ^8.4 + checksum: f23d8ab757345a6deaa807d76e10c88caf4b771c38b60e1593b24aee161c503b5823620e89302226a6ae5e7afdb6ac31809241291912e4176eb594a7ddcc9521 languageName: node linkType: hard -"postcss-load-config@npm:^2.0.0": - version: 2.1.2 - resolution: "postcss-load-config@npm:2.1.2" - dependencies: - cosmiconfig: ^5.0.0 - import-cwd: ^2.0.0 - checksum: 2e6d3a499512a03c19b0090f4143861612d613511d57122879d9fd545558d2a9fcbe85a2b0faf2ec32bbce0e62d22d2b544d91cbc4d4dfb3f22f841f8271fbc6 +"postcss-font-variant@npm:^5.0.0": + version: 5.0.0 + resolution: "postcss-font-variant@npm:5.0.0" + peerDependencies: + postcss: ^8.1.0 + checksum: a19286589261c2bc3e20470486e1ee3b4daf34271c5020167f30856c9b30c26f23264307cb97a184d503814e1b8c5d8a1f9f64a14fd4fd9551c173dca9424695 languageName: node linkType: hard -"postcss-loader@npm:3.0.0": - version: 3.0.0 - resolution: "postcss-loader@npm:3.0.0" - dependencies: - loader-utils: ^1.1.0 - postcss: ^7.0.0 - postcss-load-config: ^2.0.0 - schema-utils: ^1.0.0 - checksum: a6a922cbcc225ef57fb88c8248f91195869cd11e0d2b0b0fe84bc89a3074437d592d79a9fc39e50218677b7ba3a41b0e1c7e8f9666e59d41a196d7ab022c5805 +"postcss-gap-properties@npm:^3.0.5": + version: 3.0.5 + resolution: "postcss-gap-properties@npm:3.0.5" + peerDependencies: + postcss: ^8.2 + checksum: aed559d6d375203a08a006c9ae8cf5ae90d9edaec5cadd20fe65c1b8ce63c2bc8dfe752d4331880a6e24a300541cde61058be790b7bd9b5d04d470c250fbcd39 languageName: node linkType: hard -"postcss-logical@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-logical@npm:3.0.0" +"postcss-image-set-function@npm:^4.0.7": + version: 4.0.7 + resolution: "postcss-image-set-function@npm:4.0.7" dependencies: - postcss: ^7.0.2 - checksum: 5278661b78a093661c9cac8c04666d457734bf156f83d8c67f6034c00e8d4b3a26fce32a8a4a251feae3c7587f42556412dca980e100d0c920ee55e878f7b8ee + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 7e509330986de14250ead1a557e8da8baaf66ebe8a40354a5dff60ab40d99a483d92aa57d52713251ca1adbf0055ef476c5702b0d0ba5f85a4f407367cdabac0 languageName: node linkType: hard -"postcss-media-minmax@npm:^4.0.0": - version: 4.0.0 - resolution: "postcss-media-minmax@npm:4.0.0" +"postcss-import@npm:^15.1.0": + version: 15.1.0 + resolution: "postcss-import@npm:15.1.0" dependencies: - postcss: ^7.0.2 - checksum: 8a4d94e25089bb5a66c6742bcdd263fce2fea391438151a85b442b7f8b66323bbca552b59a93efd6bcabcfd41845ddd4149bd56d156b008f8d7d04bc84d9fb11 + postcss-value-parser: ^4.0.0 + read-cache: ^1.0.0 + resolve: ^1.1.7 + peerDependencies: + postcss: ^8.0.0 + checksum: 7bd04bd8f0235429009d0022cbf00faebc885de1d017f6d12ccb1b021265882efc9302006ba700af6cab24c46bfa2f3bc590be3f9aee89d064944f171b04e2a3 languageName: node linkType: hard -"postcss-merge-longhand@npm:^4.0.11": - version: 4.0.11 - resolution: "postcss-merge-longhand@npm:4.0.11" - dependencies: - css-color-names: 0.0.4 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - stylehacks: ^4.0.0 - checksum: 45082b492d4d771c1607707d04dbcaece85a100011109886af9460a7868720de1121e290a6442360e2668db510edef579194197d1b534e9fb6c8df7a6cb86a4d +"postcss-initial@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-initial@npm:4.0.1" + peerDependencies: + postcss: ^8.0.0 + checksum: 6956953853865de79c39d11533a2860e9f38b770bb284d0010d98a00b9469e22de344e4e5fd8208614d797030487e8918dd2f2c37d9e24d4dd59d565d4fc3e12 languageName: node linkType: hard -"postcss-merge-rules@npm:^4.0.3": - version: 4.0.3 - resolution: "postcss-merge-rules@npm:4.0.3" +"postcss-js@npm:^4.0.1": + version: 4.0.1 + resolution: "postcss-js@npm:4.0.1" dependencies: - browserslist: ^4.0.0 - caniuse-api: ^3.0.0 - cssnano-util-same-parent: ^4.0.0 - postcss: ^7.0.0 - postcss-selector-parser: ^3.0.0 - vendors: ^1.0.0 - checksum: ed0f3880e1076e5b2a08e4cff35b50dc7dfbd337e6ba16a0ca157e28268cfa1d6c6d821e902d319757f32a7d36f944cad51be76f8b34858d1d7a637e7b585919 + camelcase-css: ^2.0.1 + peerDependencies: + postcss: ^8.4.21 + checksum: 5c1e83efeabeb5a42676193f4357aa9c88f4dc1b3c4a0332c132fe88932b33ea58848186db117cf473049fc233a980356f67db490bd0a7832ccba9d0b3fd3491 languageName: node linkType: hard -"postcss-minify-font-values@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-minify-font-values@npm:4.0.2" +"postcss-lab-function@npm:^4.2.1": + version: 4.2.1 + resolution: "postcss-lab-function@npm:4.2.1" dependencies: - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: add296b3bc88501283d65b54ad83552f47c98dd403740a70d8dfeef6d30a21d4a1f40191ffef1029a9474e9580a73e84ef644e99ede76c5a2474579b583f4b34 + "@csstools/postcss-progressive-custom-properties": ^1.1.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 26ac74b430011271b5581beba69b2cd788f56375fcb64c90f6ec1577379af85f6022dc38c410ff471dac520c7ddc289160a6a16cca3c7ff76f5af7e90d31eaa3 languageName: node linkType: hard -"postcss-minify-gradients@npm:^4.0.2": +"postcss-load-config@npm:^4.0.2": version: 4.0.2 - resolution: "postcss-minify-gradients@npm:4.0.2" + resolution: "postcss-load-config@npm:4.0.2" dependencies: - cssnano-util-get-arguments: ^4.0.0 - is-color-stop: ^1.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: b83de019cc392192d64182fa6f609383904ef69013d71cda5d06fadab92b4daa73f5be0d0254c5eb0805405e5e1b9c44e49ca6bc629c4c7a24a8164a30b40d46 + lilconfig: ^3.0.0 + yaml: ^2.3.4 + peerDependencies: + postcss: ">=8.0.9" + ts-node: ">=9.0.0" + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + checksum: 7c27dd3801db4eae207a5116fed2db6b1ebb780b40c3dd62a3e57e087093a8e6a14ee17ada729fee903152d6ef4826c6339eb135bee6208e0f3140d7e8090185 languageName: node linkType: hard -"postcss-minify-params@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-minify-params@npm:4.0.2" +"postcss-loader@npm:^6.2.1": + version: 6.2.1 + resolution: "postcss-loader@npm:6.2.1" dependencies: - alphanum-sort: ^1.0.0 - browserslist: ^4.0.0 - cssnano-util-get-arguments: ^4.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - uniqs: ^2.0.0 - checksum: 15e7f196b3408ab3f55f1a7c9fa8aeea7949fdd02be28af232dd2e47bb7722e0e0a416d6b2c4550ba333a485b775da1bc35c19c9be7b6de855166d2e85d7b28f + cosmiconfig: ^7.0.0 + klona: ^2.0.5 + semver: ^7.3.5 + peerDependencies: + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + checksum: e40ae79c3e39df37014677a817b001bd115d8b10dedf53a07b97513d93b1533cd702d7a48831bdd77b9a9484b1ec84a5d4a723f80e83fb28682c75b5e65e8a90 languageName: node linkType: hard -"postcss-minify-selectors@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-minify-selectors@npm:4.0.2" - dependencies: - alphanum-sort: ^1.0.0 - has: ^1.0.0 - postcss: ^7.0.0 - postcss-selector-parser: ^3.0.0 - checksum: a214809b620e50296417838804c3978d5f0a5ddfd48916780d77c1e0348c9ed0baa4b1f3905511b0f06b77340b5378088cc3188517c0848e8b7a53a71ef36c2b +"postcss-logical@npm:^5.0.4": + version: 5.0.4 + resolution: "postcss-logical@npm:5.0.4" + peerDependencies: + postcss: ^8.4 + checksum: 17c71291ed6a03883a5aa54b9923b874c32710707d041a0f0752e6febdb09dee5d2abf4ef271978d932e4a4c948f349bb23edf633c03e3427ba15e71bfc66ac7 languageName: node linkType: hard -"postcss-modules-extract-imports@npm:1.1.0": - version: 1.1.0 - resolution: "postcss-modules-extract-imports@npm:1.1.0" - dependencies: - postcss: ^6.0.1 - checksum: 3dc9ed98509f654c1220bb8ec7489b30fa4441f2797eb5c894badfd6f4ab1b086f8002f59d47845d827a3f23a40400ba4c18959c7a3702285d4e5bfcfcd180d4 +"postcss-media-minmax@npm:^5.0.0": + version: 5.0.0 + resolution: "postcss-media-minmax@npm:5.0.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 2cd7283e07a1ac1acdcc3ecbaa0e9932f8d1e7647e7aeb14d91845fcb890d60d7257ec70c825cae8d48ae80a08cc77ebc4021a0dfa32360e0cd991e2bc021607 languageName: node linkType: hard -"postcss-modules-extract-imports@npm:^2.0.0": - version: 2.0.0 - resolution: "postcss-modules-extract-imports@npm:2.0.0" +"postcss-merge-longhand@npm:^5.1.7": + version: 5.1.7 + resolution: "postcss-merge-longhand@npm:5.1.7" dependencies: - postcss: ^7.0.5 - checksum: 154790fe5954aaa12f300aa9aa782fae8b847138459c8f533ea6c8f29439dd66b4d9a49e0bf6f8388fa0df898cc03d61c84678e3b0d4b47cac5a4334a7151a9f + postcss-value-parser: ^4.2.0 + stylehacks: ^5.1.1 + peerDependencies: + postcss: ^8.2.15 + checksum: 81c3fc809f001b9b71a940148e242bdd6e2d77713d1bfffa15eb25c1f06f6648d5e57cb21645746d020a2a55ff31e1740d2b27900442913a9d53d8a01fb37e1b languageName: node linkType: hard -"postcss-modules-local-by-default@npm:1.2.0": - version: 1.2.0 - resolution: "postcss-modules-local-by-default@npm:1.2.0" +"postcss-merge-rules@npm:^5.1.4": + version: 5.1.4 + resolution: "postcss-merge-rules@npm:5.1.4" dependencies: - css-selector-tokenizer: ^0.7.0 - postcss: ^6.0.1 - checksum: c8bbe0a9584e0a02339f4143125bf5febbcbfdbabedc33a5f2debdc5b0089f5c238b236101dbf923ea66c11637c0dee8bcf91d1692ed0443762203286b864ea2 + browserslist: ^4.21.4 + caniuse-api: ^3.0.0 + cssnano-utils: ^3.1.0 + postcss-selector-parser: ^6.0.5 + peerDependencies: + postcss: ^8.2.15 + checksum: 8ab6a569babe6cb412d6612adee74f053cea7edb91fa013398515ab36754b1fec830d68782ed8cdfb44cffdc6b78c79eab157bff650f428aa4460d3f3857447e languageName: node linkType: hard -"postcss-modules-local-by-default@npm:^3.0.3": - version: 3.0.3 - resolution: "postcss-modules-local-by-default@npm:3.0.3" +"postcss-minify-font-values@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-minify-font-values@npm:5.1.0" dependencies: - icss-utils: ^4.1.1 - postcss: ^7.0.32 - postcss-selector-parser: ^6.0.2 - postcss-value-parser: ^4.1.0 - checksum: 0267633eaf80e72a3abf391b6e34c5b344a1bdfb1421543d3ed43fc757e053e0fcc1a2eb06d959a8f435776e8dc80288b59bfc34d61e5e021d47b747c417c5a1 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 35e858fa41efa05acdeb28f1c76579c409fdc7eabb1744c3bd76e895bb9fea341a016746362a67609688ab2471f587202b9a3e14ea28ad677754d663a2777ece languageName: node linkType: hard -"postcss-modules-scope@npm:1.1.0": - version: 1.1.0 - resolution: "postcss-modules-scope@npm:1.1.0" +"postcss-minify-gradients@npm:^5.1.1": + version: 5.1.1 + resolution: "postcss-minify-gradients@npm:5.1.1" dependencies: - css-selector-tokenizer: ^0.7.0 - postcss: ^6.0.1 - checksum: e1b7dd8b1aabb0dc719015352835c6865a5b80ef469cf956749540847b751ccac860d7f0f5659aa2c4b8a484c4a9291098895e5c91c9707e02c7f79a7288297e + colord: ^2.9.1 + cssnano-utils: ^3.1.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 27354072a07c5e6dab36731103b94ca2354d4ed3c5bc6aacfdf2ede5a55fa324679d8fee5450800bc50888dbb5e9ed67569c0012040c2be128143d0cebb36d67 languageName: node linkType: hard -"postcss-modules-scope@npm:^2.2.0": - version: 2.2.0 - resolution: "postcss-modules-scope@npm:2.2.0" +"postcss-minify-params@npm:^5.1.4": + version: 5.1.4 + resolution: "postcss-minify-params@npm:5.1.4" dependencies: - postcss: ^7.0.6 - postcss-selector-parser: ^6.0.0 - checksum: c611181df924275ca1ffea261149c229488d6921054896879ca98feeb0913f9b00f4f160654beb2cb243a2989036c269baa96778eeacaaa399a4604b6e2fea17 + browserslist: ^4.21.4 + cssnano-utils: ^3.1.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: bd63e2cc89edcf357bb5c2a16035f6d02ef676b8cede4213b2bddd42626b3d428403849188f95576fc9f03e43ebd73a29bf61d33a581be9a510b13b7f7f100d5 languageName: node linkType: hard -"postcss-modules-values@npm:1.3.0": - version: 1.3.0 - resolution: "postcss-modules-values@npm:1.3.0" +"postcss-minify-selectors@npm:^5.2.1": + version: 5.2.1 + resolution: "postcss-minify-selectors@npm:5.2.1" dependencies: - icss-replace-symbols: ^1.1.0 - postcss: ^6.0.1 - checksum: c1d542f71df43ec8b998808ea8de5e74e215a2428e92a8c157da436724aacf246b77440da1cd3d5daae610c875b46e7f8a845b52e1a49afdc37668093de8e3e7 + postcss-selector-parser: ^6.0.5 + peerDependencies: + postcss: ^8.2.15 + checksum: 6fdbc84f99a60d56b43df8930707da397775e4c36062a106aea2fd2ac81b5e24e584a1892f4baa4469fa495cb87d1422560eaa8f6c9d500f9f0b691a5f95bab5 languageName: node linkType: hard -"postcss-modules-values@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-modules-values@npm:3.0.0" - dependencies: - icss-utils: ^4.0.0 - postcss: ^7.0.6 - checksum: f1aea0b9c6798b39ec02a6d2310924bb9bfbddb4579668c2d4e2205ca7a68c656b85d5720f9bba3629d611f36667fe04ab889ea3f9a6b569a0a0d57b4f2f4e99 +"postcss-modules-extract-imports@npm:^3.1.0": + version: 3.1.0 + resolution: "postcss-modules-extract-imports@npm:3.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: b9192e0f4fb3d19431558be6f8af7ca45fc92baaad9b2778d1732a5880cd25c3df2074ce5484ae491e224f0d21345ffc2d419bd51c25b019af76d7a7af88c17f languageName: node linkType: hard -"postcss-nesting@npm:^7.0.0": - version: 7.0.1 - resolution: "postcss-nesting@npm:7.0.1" +"postcss-modules-local-by-default@npm:^4.0.5": + version: 4.2.0 + resolution: "postcss-modules-local-by-default@npm:4.2.0" dependencies: - postcss: ^7.0.2 - checksum: 4056be95759e8b25477f19aff7202b57dd27eeef41d31f7ca14e4c87d16ffb40e4db3f518fc85bd28b20e183f5e5399b56b52fcc79affd556e13a98bbc678169 + icss-utils: ^5.0.0 + postcss-selector-parser: ^7.0.0 + postcss-value-parser: ^4.1.0 + peerDependencies: + postcss: ^8.1.0 + checksum: 720d145453f82ad5f1c1d0ff7386d64722f0812808e4132e573c1a49909745e109fcce3792a0b0cb18770dbeb3d9741867e81c698dc8353a18bc664b7d6d9533 languageName: node linkType: hard -"postcss-normalize-charset@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-normalize-charset@npm:4.0.1" +"postcss-modules-scope@npm:^3.2.0": + version: 3.2.1 + resolution: "postcss-modules-scope@npm:3.2.1" dependencies: - postcss: ^7.0.0 - checksum: f233f48d61eb005da217e5bfa58f4143165cb525ceea2de4fd88e4172a33712e8b63258ffa089c867875a498c408f293a380ea9e6f40076de550d8053f50e5bc + postcss-selector-parser: ^7.0.0 + peerDependencies: + postcss: ^8.1.0 + checksum: 085f65863bb7d8bf08209a979ceb22b2b07bb466574e0e698d34aaad832d614957bb05f2418348a14e4035f65e23b2be2951369d26ea429dd5762c6a020f0f7c languageName: node linkType: hard -"postcss-normalize-display-values@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-normalize-display-values@npm:4.0.2" +"postcss-modules-values@npm:^4.0.0": + version: 4.0.0 + resolution: "postcss-modules-values@npm:4.0.0" dependencies: - cssnano-util-get-match: ^4.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: c5b857ca05f30a3efc6211cdaa5c9306f3eb0dbac141047d451a418d2bfd3e54be0bd4481d61c640096152d3078881a8dc3dec61913ff7f01ab4fc6df1a14732 + icss-utils: ^5.0.0 + peerDependencies: + postcss: ^8.1.0 + checksum: f7f2cdf14a575b60e919ad5ea52fed48da46fe80db2733318d71d523fc87db66c835814940d7d05b5746b0426e44661c707f09bdb83592c16aea06e859409db6 languageName: node linkType: hard -"postcss-normalize-positions@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-normalize-positions@npm:4.0.2" - dependencies: - cssnano-util-get-arguments: ^4.0.0 - has: ^1.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 291612d0879e6913010937f1193ab56ae1cfd8a274665330ccbedbe72f59c36db3f688b0a3faa4c6689cfd03dff0c27702c6acfce9b1f697a022bfcee3cd4fc4 +"postcss-modules@npm:^6.0.0": + version: 6.0.1 + resolution: "postcss-modules@npm:6.0.1" + dependencies: + generic-names: ^4.0.0 + icss-utils: ^5.1.0 + lodash.camelcase: ^4.3.0 + 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 + string-hash: ^1.1.3 + peerDependencies: + postcss: ^8.0.0 + checksum: bdbf1e2babfb5a6ff13c86c36b8b431b655472cc9e16098cea0b960ed1fe8fa8f298292f939548bf00cc664c66e954d1b4c5a8634a7b57c58bc06d8f54cdd5a0 languageName: node linkType: hard -"postcss-normalize-repeat-style@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-normalize-repeat-style@npm:4.0.2" +"postcss-nested@npm:^6.2.0": + version: 6.2.0 + resolution: "postcss-nested@npm:6.2.0" dependencies: - cssnano-util-get-arguments: ^4.0.0 - cssnano-util-get-match: ^4.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 2160b2a6fe4f9671ad5d044755f0e04cfb5f255db607505fd4c74e7c806315c9dca914e74bb02f5f768de7b70939359d05c3f9b23ae8f72551d8fdeabf79a1fb + postcss-selector-parser: ^6.1.1 + peerDependencies: + postcss: ^8.2.14 + checksum: 2c86ecf2d0ce68f27c87c7e24ae22dc6dd5515a89fcaf372b2627906e11f5c1f36e4a09e4c15c20fd4a23d628b3d945c35839f44496fbee9a25866258006671b languageName: node linkType: hard -"postcss-normalize-string@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-normalize-string@npm:4.0.2" +"postcss-nesting@npm:^10.2.0": + version: 10.2.0 + resolution: "postcss-nesting@npm:10.2.0" dependencies: - has: ^1.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 9d40753ceb4f7854ed690ecd5fe4ea142280b14441dd11e188e573e58af93df293efdc77311f1c599431df785a3bb614dfe4bdacc3081ee3fe8c95916c849b2f + "@csstools/selector-specificity": ^2.0.0 + postcss-selector-parser: ^6.0.10 + peerDependencies: + postcss: ^8.2 + checksum: 25e6e66186bd7f18bc4628cf0f43e02189268f28a449aa4a63b33b8f2c33745af99acfcd4ce2ac69319dc850e83b28dbaabcf517e3977dfe20e37fed0e032c7d languageName: node linkType: hard -"postcss-normalize-timing-functions@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-normalize-timing-functions@npm:4.0.2" - dependencies: - cssnano-util-get-match: ^4.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 8dfd711f5cdb49b823a92d1cd56d40f66f3686e257804495ef59d5d7f71815b6d19412a1ff25d40971bf6e146b1fa0517a6cc1a4c286b36c5cee6ed08a1952db +"postcss-normalize-charset@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-normalize-charset@npm:5.1.0" + peerDependencies: + postcss: ^8.2.15 + checksum: e79d92971fc05b8b3c9b72f3535a574e077d13c69bef68156a0965f397fdf157de670da72b797f57b0e3bac8f38155b5dd1735ecab143b9cc4032d72138193b4 languageName: node linkType: hard -"postcss-normalize-unicode@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-normalize-unicode@npm:4.0.1" +"postcss-normalize-display-values@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-normalize-display-values@npm:5.1.0" dependencies: - browserslist: ^4.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 2b1da17815f8402651a72012fd385b5111e84002baf98b649e0c1fc91298b65bb0e431664f6df8a99b23217259ecec242b169c0f18bf26e727af02eaf475fb07 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: b6eb7b9b02c3bdd62bbc54e01e2b59733d73a1c156905d238e178762962efe0c6f5104544da39f32cade8a4fb40f10ff54b63a8ebfbdff51e8780afb9fbdcf86 languageName: node linkType: hard -"postcss-normalize-url@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-normalize-url@npm:4.0.1" +"postcss-normalize-positions@npm:^5.1.1": + version: 5.1.1 + resolution: "postcss-normalize-positions@npm:5.1.1" dependencies: - is-absolute-url: ^2.0.0 - normalize-url: ^3.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: fcaab832d8b773568197b41406517a9e5fc7704f2fac7185bd0e13b19961e1ce9f1c762e4ffa470de7baa6a82ae8ae5ccf6b1bbeec6e95216d22ce6ab514fe04 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: d9afc233729c496463c7b1cdd06732469f401deb387484c3a2422125b46ec10b4af794c101f8c023af56f01970b72b535e88373b9058ecccbbf88db81662b3c4 languageName: node linkType: hard -"postcss-normalize-whitespace@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-normalize-whitespace@npm:4.0.2" +"postcss-normalize-repeat-style@npm:^5.1.1": + version: 5.1.1 + resolution: "postcss-normalize-repeat-style@npm:5.1.1" dependencies: - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 378a6eadb09ccc5ca2289e8daf98ce7366ae53342c4df7898ef5fae68138884d6c1241493531635458351b2805218bf55ceecae0fd289e5696ab15c78966abbb + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 2c6ad2b0ae10a1fda156b948c34f78c8f1e185513593de4d7e2480973586675520edfec427645fa168c337b0a6b3ceca26f92b96149741ca98a9806dad30d534 languageName: node linkType: hard -"postcss-normalize@npm:8.0.1": - version: 8.0.1 - resolution: "postcss-normalize@npm:8.0.1" +"postcss-normalize-string@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-normalize-string@npm:5.1.0" dependencies: - "@csstools/normalize.css": ^10.1.0 - browserslist: ^4.6.2 - postcss: ^7.0.17 - postcss-browser-comments: ^3.0.0 - sanitize.css: ^10.0.0 - checksum: 3109075389b91a09a790c3cd62a4e8c147bab2113cffa7ea2e776982352796816bc56b7f08ed7f7175c24e5d9c46171a07f95eeee00cfecddac6e3b4c9888dd0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 6e549c6e5b2831e34c7bdd46d8419e2278f6af1d5eef6d26884a37c162844e60339340c57e5e06058cdbe32f27fc6258eef233e811ed2f71168ef2229c236ada languageName: node linkType: hard -"postcss-ordered-values@npm:^4.1.2": - version: 4.1.2 - resolution: "postcss-ordered-values@npm:4.1.2" +"postcss-normalize-timing-functions@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-normalize-timing-functions@npm:5.1.0" dependencies: - cssnano-util-get-arguments: ^4.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: 4a6f6a427a0165e1fa4f04dbe53a88708c73ea23e5b23ce312366ca8d85d83af450154a54f0e5df6c5712f945c180b6a364c3682dc995940b93228bb26658a96 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: da550f50e90b0b23e17b67449a7d1efd1aa68288e66d4aa7614ca6f5cc012896be1972b7168eee673d27da36504faccf7b9f835c0f7e81243f966a42c8c030aa languageName: node linkType: hard -"postcss-overflow-shorthand@npm:^2.0.0": - version: 2.0.0 - resolution: "postcss-overflow-shorthand@npm:2.0.0" +"postcss-normalize-unicode@npm:^5.1.1": + version: 5.1.1 + resolution: "postcss-normalize-unicode@npm:5.1.1" dependencies: - postcss: ^7.0.2 - checksum: 553be1b7f9645017d33b654f9a436ce4f4406066c3056ca4c7ee06c21c2964fbe3437a9a3f998137efb6a17c1a79ee7e8baa39332c7dd9874aac8b69a3ad08b0 + browserslist: ^4.21.4 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 4c24d26cc9f4b19a9397db4e71dd600dab690f1de8e14a3809e2aa1452dbc3791c208c38a6316bbc142f29e934fdf02858e68c94038c06174d78a4937e0f273c languageName: node linkType: hard -"postcss-page-break@npm:^2.0.0": - version: 2.0.0 - resolution: "postcss-page-break@npm:2.0.0" +"postcss-normalize-url@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-normalize-url@npm:5.1.0" dependencies: - postcss: ^7.0.2 - checksum: 65a4453883e904ca0f337d3a988a1b5a090e2e8bc2855913cb0b4b741158e6ea2e4eed9b33f5989e7ae55faa0f7b83cdc09693d600ac4c86ce804ae381ec48a4 + normalize-url: ^6.0.1 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 3bd4b3246d6600230bc827d1760b24cb3101827ec97570e3016cbe04dc0dd28f4dbe763245d1b9d476e182c843008fbea80823061f1d2219b96f0d5c724a24c0 languageName: node linkType: hard -"postcss-place@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-place@npm:4.0.1" - dependencies: - postcss: ^7.0.2 - postcss-values-parser: ^2.0.0 - checksum: 26b2a443b0a8fcb6774d00036fa351633798a655ccd609da2d561fbd6561b0ba6f6b6d89e15fb074389fadb7da4cbc59c48ba75f1f5fdc478c020febb4e2b557 - languageName: node - linkType: hard - -"postcss-preset-env@npm:6.7.0": - version: 6.7.0 - resolution: "postcss-preset-env@npm:6.7.0" - dependencies: - autoprefixer: ^9.6.1 - browserslist: ^4.6.4 - caniuse-lite: ^1.0.30000981 - css-blank-pseudo: ^0.1.4 - css-has-pseudo: ^0.10.0 - css-prefers-color-scheme: ^3.1.1 - cssdb: ^4.4.0 - postcss: ^7.0.17 - postcss-attribute-case-insensitive: ^4.0.1 - postcss-color-functional-notation: ^2.0.1 - postcss-color-gray: ^5.0.0 - postcss-color-hex-alpha: ^5.0.3 - postcss-color-mod-function: ^3.0.3 - postcss-color-rebeccapurple: ^4.0.1 - postcss-custom-media: ^7.0.8 - postcss-custom-properties: ^8.0.11 - postcss-custom-selectors: ^5.1.2 - postcss-dir-pseudo-class: ^5.0.0 - postcss-double-position-gradients: ^1.0.0 - postcss-env-function: ^2.0.2 - postcss-focus-visible: ^4.0.0 - postcss-focus-within: ^3.0.0 - postcss-font-variant: ^4.0.0 - postcss-gap-properties: ^2.0.0 - postcss-image-set-function: ^3.0.1 - postcss-initial: ^3.0.0 - postcss-lab-function: ^2.0.1 - postcss-logical: ^3.0.0 - postcss-media-minmax: ^4.0.0 - postcss-nesting: ^7.0.0 - postcss-overflow-shorthand: ^2.0.0 - postcss-page-break: ^2.0.0 - postcss-place: ^4.0.1 - postcss-pseudo-class-any-link: ^6.0.0 - postcss-replace-overflow-wrap: ^3.0.0 - postcss-selector-matches: ^4.0.0 - postcss-selector-not: ^4.0.0 - checksum: 209cbb63443a1631aa97ccfc3b95b1ff519ddaeb672f84d6af501bd9e9ad6727680b5b1bffb8209322e47d93029a69df6064f75cd0b7633b6df943cbef33f22e - languageName: node - linkType: hard - -"postcss-pseudo-class-any-link@npm:^6.0.0": - version: 6.0.0 - resolution: "postcss-pseudo-class-any-link@npm:6.0.0" +"postcss-normalize-whitespace@npm:^5.1.1": + version: 5.1.1 + resolution: "postcss-normalize-whitespace@npm:5.1.1" dependencies: - postcss: ^7.0.2 - postcss-selector-parser: ^5.0.0-rc.3 - checksum: d7dc3bba45df2966f8512c082a9cc341e63edac14d915ad9f41c62c452cd306d82da6baeee757dd4e7deafe3fa33b26c16e5236c670916bbb7ff4b4723453541 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 12d8fb6d1c1cba208cc08c1830959b7d7ad447c3f5581873f7e185f99a9a4230c43d3af21ca12c818e4690a5085a95b01635b762ad4a7bef69d642609b4c0e19 languageName: node linkType: hard -"postcss-reduce-initial@npm:^4.0.3": - version: 4.0.3 - resolution: "postcss-reduce-initial@npm:4.0.3" +"postcss-normalize@npm:^10.0.1": + version: 10.0.1 + resolution: "postcss-normalize@npm:10.0.1" dependencies: - browserslist: ^4.0.0 - caniuse-api: ^3.0.0 - has: ^1.0.0 - postcss: ^7.0.0 - checksum: 5ad1a955cb20f5b1792ff8cc35894621edc23ee77397cc7e9692d269882fb4451655633947e0407fe20bd127d09d0b7e693034c64417bf8bf1034a83c6e71668 + "@csstools/normalize.css": "*" + postcss-browser-comments: ^4 + sanitize.css: "*" + peerDependencies: + browserslist: ">= 4" + postcss: ">= 8" + checksum: af67ade84e5d65de0cf84cde479840da96ffb2037fe6bf86737788216f67e414622e718e7d84182885ad65fa948150e4a0c3e454ca63e619dd5c7b4eb4224c39 languageName: node linkType: hard -"postcss-reduce-transforms@npm:^4.0.2": - version: 4.0.2 - resolution: "postcss-reduce-transforms@npm:4.0.2" - dependencies: - cssnano-util-get-match: ^4.0.0 - has: ^1.0.0 - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - checksum: e6a351d5da7ecf276ddda350635b15bce8e14af08aee1c8a0e8d9c2ab2631eab33b06f3c2f31c6f9c76eedbfc23f356d86da3539e011cde3e335a2cac9d91dc1 +"postcss-opacity-percentage@npm:^1.1.2": + version: 1.1.3 + resolution: "postcss-opacity-percentage@npm:1.1.3" + peerDependencies: + postcss: ^8.2 + checksum: 54d1b8ca68035bc1a5788aaabdbc3b66ffee34b5a2412cecf073627dad7e3f2bae07c01fac3bc7f46bbac5da3291ac9ddcf74bfee26dfd86f9f96c847a0afc13 languageName: node linkType: hard -"postcss-replace-overflow-wrap@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-replace-overflow-wrap@npm:3.0.0" +"postcss-ordered-values@npm:^5.1.3": + version: 5.1.3 + resolution: "postcss-ordered-values@npm:5.1.3" dependencies: - postcss: ^7.0.2 - checksum: 8c5b512a1172dd3d7b4a06d56d3b64c76dea01ca0950b546f83ae993f83aa95f933239e18deed0a5f3d2ef47840de55fa73498c4a46bfbe7bd892eb0dd8b606c + cssnano-utils: ^3.1.0 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 6f3ca85b6ceffc68aadaf319d9ee4c5ac16d93195bf8cba2d1559b631555ad61941461cda6d3909faab86e52389846b2b36345cff8f0c3f4eb345b1b8efadcf9 languageName: node linkType: hard -"postcss-safe-parser@npm:5.0.2": - version: 5.0.2 - resolution: "postcss-safe-parser@npm:5.0.2" +"postcss-overflow-shorthand@npm:^3.0.4": + version: 3.0.4 + resolution: "postcss-overflow-shorthand@npm:3.0.4" dependencies: - postcss: ^8.1.0 - checksum: b786eca091f856f2d31856d903c24c1b591ecbc0b607af0824e1cf12b9b254b5e1f24bc842cc2b95bc561f097d8b358fb4c9e04c73c1ba9c118d21bde9a83253 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 74009022491e3901263f8f5811630393480323e51f5d23ef17f3fdc7e03bf9c2502a632f3ba8fe6a468b57590f13b2fa3b17a68ef19653589e76277607696743 languageName: node linkType: hard -"postcss-selector-matches@npm:^4.0.0": - version: 4.0.0 - resolution: "postcss-selector-matches@npm:4.0.0" - dependencies: - balanced-match: ^1.0.0 - postcss: ^7.0.2 - checksum: 724f6cb345477691909468268a456f978ad3bae9ecd9908b2bb55c55c5f3c6d54a1fe50ce3956d93b122d05fc36677a8e4a34eed07bccda969c3f8baa43669a6 +"postcss-page-break@npm:^3.0.4": + version: 3.0.4 + resolution: "postcss-page-break@npm:3.0.4" + peerDependencies: + postcss: ^8 + checksum: a7d08c945fc691f62c77ac701e64722218b14ec5c8fc1972b8af9c21553492d40808cf95e61b9697b1dacaf7e6180636876d7fee314f079e6c9e39ac1b1edc6f languageName: node linkType: hard -"postcss-selector-not@npm:^4.0.0": - version: 4.0.1 - resolution: "postcss-selector-not@npm:4.0.1" +"postcss-place@npm:^7.0.5": + version: 7.0.5 + resolution: "postcss-place@npm:7.0.5" dependencies: - balanced-match: ^1.0.0 - postcss: ^7.0.2 - checksum: 08fbd3e5ca273f3b767bd35d6bd033647a68f59b596d8aec19a9089b750539bdf85121ed7fd00a7763174a55c75c22a309d75d306127e23dc396069781efbaa4 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 903fec0c313bb7ec20f2c8f0a125866fb7804aa3186b5b2c7c2d58cb9039ff301461677a060e9db643d1aaffaf80a0ff71e900a6da16705dad6b49c804cb3c73 languageName: node linkType: hard -"postcss-selector-parser@npm:^3.0.0": - version: 3.1.2 - resolution: "postcss-selector-parser@npm:3.1.2" - dependencies: - dot-prop: ^5.2.0 - indexes-of: ^1.0.1 - uniq: ^1.0.1 - checksum: 85b754bf3b5f671cddd75a199589e5b03da114ec119aa4628ab7f35f76134b25296d18a68f745e39780c379d66d3919ae7a1b6129aeec5049cedb9ba4c660803 +"postcss-preset-env@npm:^7.0.1": + version: 7.8.3 + resolution: "postcss-preset-env@npm:7.8.3" + dependencies: + "@csstools/postcss-cascade-layers": ^1.1.1 + "@csstools/postcss-color-function": ^1.1.1 + "@csstools/postcss-font-format-keywords": ^1.0.1 + "@csstools/postcss-hwb-function": ^1.0.2 + "@csstools/postcss-ic-unit": ^1.0.1 + "@csstools/postcss-is-pseudo-class": ^2.0.7 + "@csstools/postcss-nested-calc": ^1.0.0 + "@csstools/postcss-normalize-display-values": ^1.0.1 + "@csstools/postcss-oklab-function": ^1.1.1 + "@csstools/postcss-progressive-custom-properties": ^1.3.0 + "@csstools/postcss-stepped-value-functions": ^1.0.1 + "@csstools/postcss-text-decoration-shorthand": ^1.0.0 + "@csstools/postcss-trigonometric-functions": ^1.0.2 + "@csstools/postcss-unset-value": ^1.0.2 + autoprefixer: ^10.4.13 + browserslist: ^4.21.4 + css-blank-pseudo: ^3.0.3 + css-has-pseudo: ^3.0.4 + css-prefers-color-scheme: ^6.0.3 + cssdb: ^7.1.0 + postcss-attribute-case-insensitive: ^5.0.2 + postcss-clamp: ^4.1.0 + postcss-color-functional-notation: ^4.2.4 + postcss-color-hex-alpha: ^8.0.4 + postcss-color-rebeccapurple: ^7.1.1 + postcss-custom-media: ^8.0.2 + postcss-custom-properties: ^12.1.10 + postcss-custom-selectors: ^6.0.3 + postcss-dir-pseudo-class: ^6.0.5 + postcss-double-position-gradients: ^3.1.2 + postcss-env-function: ^4.0.6 + postcss-focus-visible: ^6.0.4 + postcss-focus-within: ^5.0.4 + postcss-font-variant: ^5.0.0 + postcss-gap-properties: ^3.0.5 + postcss-image-set-function: ^4.0.7 + postcss-initial: ^4.0.1 + postcss-lab-function: ^4.2.1 + postcss-logical: ^5.0.4 + postcss-media-minmax: ^5.0.0 + postcss-nesting: ^10.2.0 + postcss-opacity-percentage: ^1.1.2 + postcss-overflow-shorthand: ^3.0.4 + postcss-page-break: ^3.0.4 + postcss-place: ^7.0.5 + postcss-pseudo-class-any-link: ^7.1.6 + postcss-replace-overflow-wrap: ^4.0.0 + postcss-selector-not: ^6.0.1 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2 + checksum: 71bfb697ffc55e27895b2bf3a579dd9b4c1321872816091935e33d6f659cab60795a03bb022dc8a4cab48fd5680a419fe9ae5d61a3a3d8c785ec9308f323e787 languageName: node linkType: hard -"postcss-selector-parser@npm:^5.0.0-rc.3, postcss-selector-parser@npm:^5.0.0-rc.4": - version: 5.0.0 - resolution: "postcss-selector-parser@npm:5.0.0" +"postcss-pseudo-class-any-link@npm:^7.1.6": + version: 7.1.6 + resolution: "postcss-pseudo-class-any-link@npm:7.1.6" dependencies: - cssesc: ^2.0.0 - indexes-of: ^1.0.1 - uniq: ^1.0.1 - checksum: e49d21455e06d2cb9bf2a615bf3e605e0603c2c430a84c37a34f8baedaf3e8f9d0059a085d3e0483cbfa04c0d4153c7da28e7ac0ada319efdefe407df11dc1d4 + postcss-selector-parser: ^6.0.10 + peerDependencies: + postcss: ^8.2 + checksum: 43aa18ea1ef1b168f61310856dd92f46ceb3dc60b6cf820e079ca1a849df5cc0f12a1511bdc1811a23f03d60ddcc959200c80c3f9a7b57feebe32bab226afb39 languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.0, postcss-selector-parser@npm:^6.0.2": - version: 6.0.16 - resolution: "postcss-selector-parser@npm:6.0.16" +"postcss-reduce-initial@npm:^5.1.2": + version: 5.1.2 + resolution: "postcss-reduce-initial@npm:5.1.2" dependencies: - cssesc: ^3.0.0 - util-deprecate: ^1.0.2 - checksum: e1cd68e33a39e3dc1e1e5bd8717be5bbe3cc23a4cecb466c3acb2f3a77daad7a47df4d6137a76f8db74cf160d2fb16b2cfdb4ccbebdfda844690f8d545fe281d + browserslist: ^4.21.4 + caniuse-api: ^3.0.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 55db697f85231a81f1969d54c894e4773912d9ddb914f9b03d2e73abc4030f2e3bef4d7465756d0c1acfcc2c2d69974bfb50a972ab27546a7d68b5a4fc90282b languageName: node linkType: hard -"postcss-svgo@npm:^4.0.3": - version: 4.0.3 - resolution: "postcss-svgo@npm:4.0.3" +"postcss-reduce-transforms@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-reduce-transforms@npm:5.1.0" dependencies: - postcss: ^7.0.0 - postcss-value-parser: ^3.0.0 - svgo: ^1.0.0 - checksum: 6f5264241193ca3ba748fdf43c88ef692948d2ae38787398dc90089061fed884064ec14ee244fce07f19c419d1b058c77e135407d0932b09e93e528581ce3e10 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.2.15 + checksum: 0c6af2cba20e3ff63eb9ad045e634ddfb9c3e5c0e614c020db2a02f3aa20632318c4ede9e0c995f9225d9a101e673de91c0a6e10bb2fa5da6d6c75d15a55882f languageName: node linkType: hard -"postcss-unique-selectors@npm:^4.0.1": - version: 4.0.1 - resolution: "postcss-unique-selectors@npm:4.0.1" - dependencies: - alphanum-sort: ^1.0.0 - postcss: ^7.0.0 - uniqs: ^2.0.0 - checksum: 272eb1fa17d6ea513b5f4d2f694ef30fa690795ce388aef7bf3967fd3bcec7a9a3c8da380e74961ded8d98253a6ed18fb380b29da00e2fe03e74813e7765ea71 +"postcss-replace-overflow-wrap@npm:^4.0.0": + version: 4.0.0 + resolution: "postcss-replace-overflow-wrap@npm:4.0.0" + peerDependencies: + postcss: ^8.0.3 + checksum: 3ffe20b300a4c377a11c588b142740d8557e03c707474c45234c934190ac374750ddc92c7906c373471d273a20504a429c2062c21fdcaff830fb28e0a81ac1dc languageName: node linkType: hard -"postcss-value-parser@npm:^3.0.0": - version: 3.3.1 - resolution: "postcss-value-parser@npm:3.3.1" - checksum: 62cd26e1cdbcf2dcc6bcedf3d9b409c9027bc57a367ae20d31dd99da4e206f730689471fd70a2abe866332af83f54dc1fa444c589e2381bf7f8054c46209ce16 +"postcss-selector-not@npm:^6.0.1": + version: 6.0.1 + resolution: "postcss-selector-not@npm:6.0.1" + dependencies: + postcss-selector-parser: ^6.0.10 + peerDependencies: + postcss: ^8.2 + checksum: fe523a0219e4bd34f04498534bb9e8aec3193f3585eafe4c388d086955b41201cae71fd20980ca465acade7f182029b43dbd5ca7e9d50bf34bbcaf1d19fe3ee6 languageName: node linkType: hard -"postcss-value-parser@npm:^4.0.2, postcss-value-parser@npm:^4.1.0": - version: 4.2.0 - resolution: "postcss-value-parser@npm:4.2.0" - checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f +"postcss-selector-parser@npm:^6.0.10, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.9, postcss-selector-parser@npm:^6.1.1, postcss-selector-parser@npm:^6.1.2": + version: 6.1.2 + resolution: "postcss-selector-parser@npm:6.1.2" + dependencies: + cssesc: ^3.0.0 + util-deprecate: ^1.0.2 + checksum: ce9440fc42a5419d103f4c7c1847cb75488f3ac9cbe81093b408ee9701193a509f664b4d10a2b4d82c694ee7495e022f8f482d254f92b7ffd9ed9dea696c6f84 languageName: node linkType: hard -"postcss-values-parser@npm:^2.0.0, postcss-values-parser@npm:^2.0.1": - version: 2.0.1 - resolution: "postcss-values-parser@npm:2.0.1" +"postcss-selector-parser@npm:^7.0.0": + version: 7.1.0 + resolution: "postcss-selector-parser@npm:7.1.0" dependencies: - flatten: ^1.0.2 - indexes-of: ^1.0.1 - uniq: ^1.0.1 - checksum: 050877880937e15af8d18bf48902e547e2123d7cc32c1f215b392642bc5e2598a87a341995d62f38e450aab4186b8afeb2c9541934806d458ad8b117020b2ebf + cssesc: ^3.0.0 + util-deprecate: ^1.0.2 + checksum: 1300e7871dd60a5132ee5462cc6e94edd4f3df28462b2495ca9ff025bd83768a908e892a18fde62cae63ff63524641baa6d58c64120f04fe6884b916663ce737 languageName: node linkType: hard -"postcss@npm:6.0.1": - version: 6.0.1 - resolution: "postcss@npm:6.0.1" +"postcss-svgo@npm:^5.1.0": + version: 5.1.0 + resolution: "postcss-svgo@npm:5.1.0" dependencies: - chalk: ^1.1.3 - source-map: ^0.5.6 - supports-color: ^3.2.3 - checksum: 2533d218b6c23dad42fffb98979f3fd2b98bbe11c923e3245ed8f83da9591c176a5de2403ad3ebaedea819f50d5f6c88c40d322265c59b6b10ed8a02c12fd4bc + postcss-value-parser: ^4.2.0 + svgo: ^2.7.0 + peerDependencies: + postcss: ^8.2.15 + checksum: d86eb5213d9f700cf5efe3073799b485fb7cacae0c731db3d7749c9c2b1c9bc85e95e0baeca439d699ff32ea24815fc916c4071b08f67ed8219df229ce1129bd languageName: node linkType: hard -"postcss@npm:7.0.36": - version: 7.0.36 - resolution: "postcss@npm:7.0.36" +"postcss-unique-selectors@npm:^5.1.1": + version: 5.1.1 + resolution: "postcss-unique-selectors@npm:5.1.1" dependencies: - chalk: ^2.4.2 - source-map: ^0.6.1 - supports-color: ^6.1.0 - checksum: 4cfc0989b9ad5d0e8971af80d87f9c5beac5c84cb89ff22ad69852edf73c0a2fa348e7e0a135b5897bf893edad0fe86c428769050431ad9b532f072ff530828d + postcss-selector-parser: ^6.0.5 + peerDependencies: + postcss: ^8.2.15 + checksum: 637e7b786e8558265775c30400c54b6b3b24d4748923f4a39f16a65fd0e394f564ccc9f0a1d3c0e770618a7637a7502ea1d0d79f731d429cb202255253c23278 languageName: node linkType: hard -"postcss@npm:^6.0.1": - version: 6.0.23 - resolution: "postcss@npm:6.0.23" - dependencies: - chalk: ^2.4.1 - source-map: ^0.6.1 - supports-color: ^5.4.0 - checksum: cc6cb2c1dbcdefa6f57a71d67fe535c9e96543298bbe28f9a6a64c4f1e21b6127113890dd4cda8873d3f4e6613a0566b7b4bbb230204f3a9a309190bda065d81 +"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0": + version: 4.2.0 + resolution: "postcss-value-parser@npm:4.2.0" + checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f languageName: node linkType: hard -"postcss@npm:^7, postcss@npm:^7.0.0, postcss@npm:^7.0.1, postcss@npm:^7.0.14, postcss@npm:^7.0.17, postcss@npm:^7.0.2, postcss@npm:^7.0.26, postcss@npm:^7.0.27, postcss@npm:^7.0.32, postcss@npm:^7.0.5, postcss@npm:^7.0.6": +"postcss@npm:^7.0.35": version: 7.0.39 resolution: "postcss@npm:7.0.39" dependencies: @@ -16150,14 +17422,36 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.1.0, postcss@npm:^8.4.27": - version: 8.4.38 - resolution: "postcss@npm:8.4.38" +"postcss@npm:^8.3.5, postcss@npm:^8.4.27, postcss@npm:^8.4.33, postcss@npm:^8.4.4, postcss@npm:^8.4.43, postcss@npm:^8.4.47, postcss@npm:^8.4.49, postcss@npm:^8.5.6": + version: 8.5.6 + resolution: "postcss@npm:8.5.6" dependencies: - nanoid: ^3.3.7 - picocolors: ^1.0.0 - source-map-js: ^1.2.0 - checksum: 649f9e60a763ca4b5a7bbec446a069edf07f057f6d780a5a0070576b841538d1ecf7dd888f2fbfd1f76200e26c969e405aeeae66332e6927dbdc8bdcb90b9451 + nanoid: ^3.3.11 + picocolors: ^1.1.1 + source-map-js: ^1.2.1 + checksum: 20f3b5d673ffeec2b28d65436756d31ee33f65b0a8bedb3d32f556fbd5973be38c3a7fb5b959a5236c60a5db7b91b0a6b14ffaac0d717dce1b903b964ee1c1bb + languageName: node + linkType: hard + +"prebuild-install@npm:^7.1.3": + version: 7.1.3 + resolution: "prebuild-install@npm:7.1.3" + dependencies: + detect-libc: ^2.0.0 + expand-template: ^2.0.3 + github-from-package: 0.0.0 + minimist: ^1.2.3 + mkdirp-classic: ^0.5.3 + napi-build-utils: ^2.0.0 + node-abi: ^3.3.0 + pump: ^3.0.0 + rc: ^1.2.7 + simple-get: ^4.0.0 + tar-fs: ^2.0.0 + tunnel-agent: ^0.6.0 + bin: + prebuild-install: bin.js + checksum: 300740ca415e9ddbf2bd363f1a6d2673cc11dd0665c5ec431bbb5bf024c2f13c56791fb939ce2b2a2c12f2d2a09c91316169e8063a80eb4482a44b8fe5b265e1 languageName: node linkType: hard @@ -16175,13 +17469,6 @@ __metadata: languageName: node linkType: hard -"prepend-http@npm:^1.0.0": - version: 1.0.4 - resolution: "prepend-http@npm:1.0.4" - checksum: 01e7baf4ad38af02257b99098543469332fc42ae50df33d97a124bf8172295907352fa6138c9b1610c10c6dd0847ca736e53fda736387cc5cf8fcffe96b47f29 - languageName: node - linkType: hard - "prettier-linter-helpers@npm:^1.0.0": version: 1.0.0 resolution: "prettier-linter-helpers@npm:1.0.0" @@ -16191,45 +17478,33 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^2.0.5": - version: 2.8.8 - resolution: "prettier@npm:2.8.8" +"prettier@npm:^3.4.2": + version: 3.6.2 + resolution: "prettier@npm:3.6.2" bin: - prettier: bin-prettier.js - checksum: b49e409431bf129dd89238d64299ba80717b57ff5a6d1c1a8b1a28b590d998a34e083fa13573bc732bb8d2305becb4c9a4407f8486c81fa7d55100eb08263cf8 + prettier: bin/prettier.cjs + checksum: 0206f5f437892e8858f298af8850bf9d0ef1c22e21107a213ba56bfb9c2387a2020bfda244a20161d8e3dad40c6b04101609a55d370dece53d0a31893b64f861 languageName: node linkType: hard -"pretty-bytes@npm:^5.3.0": +"pretty-bytes@npm:^5.3.0, pretty-bytes@npm:^5.4.1": version: 5.6.0 resolution: "pretty-bytes@npm:5.6.0" checksum: 9c082500d1e93434b5b291bd651662936b8bd6204ec9fa17d563116a192d6d86b98f6d328526b4e8d783c07d5499e2614a807520249692da9ec81564b2f439cd languageName: node linkType: hard -"pretty-error@npm:^2.1.1": - version: 2.1.2 - resolution: "pretty-error@npm:2.1.2" +"pretty-error@npm:^4.0.0": + version: 4.0.0 + resolution: "pretty-error@npm:4.0.0" dependencies: lodash: ^4.17.20 - renderkid: ^2.0.4 - checksum: 16775d06f9a695d17103414d610b1281f9535ee1f2da1ce1e1b9be79584a114aa7eac6dcdcc5ef151756d3c014dfd4ac1c7303ed8016d0cec12437cfdf4021c6 + renderkid: ^3.0.0 + checksum: a5b9137365690104ded6947dca2e33360bf55e62a4acd91b1b0d7baa3970e43754c628cc9e16eafbdd4e8f8bcb260a5865475d4fc17c3106ff2d61db4e72cdf3 languageName: node linkType: hard -"pretty-format@npm:^26.6.0, pretty-format@npm:^26.6.2": - version: 26.6.2 - resolution: "pretty-format@npm:26.6.2" - dependencies: - "@jest/types": ^26.6.2 - ansi-regex: ^5.0.0 - ansi-styles: ^4.0.0 - react-is: ^17.0.1 - checksum: e3b808404d7e1519f0df1aa1f25cee0054ab475775c6b2b8c5568ff23194a92d54bf93274139b6f584ca70fd773be4eaa754b0e03f12bb0a8d1426b07f079976 - languageName: node - linkType: hard - -"pretty-format@npm:^27.0.2": +"pretty-format@npm:^27.0.2, pretty-format@npm:^27.5.1": version: 27.5.1 resolution: "pretty-format@npm:27.5.1" dependencies: @@ -16240,7 +17515,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^28.0.0, pretty-format@npm:^28.1.3": +"pretty-format@npm:^28.1.3": version: 28.1.3 resolution: "pretty-format@npm:28.1.3" dependencies: @@ -16252,7 +17527,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.0.0, pretty-format@npm:^29.5.0, pretty-format@npm:^29.7.0": +"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" dependencies: @@ -16263,22 +17538,25 @@ __metadata: languageName: node linkType: hard -"prisma@npm:^4.4.0": - version: 4.16.2 - resolution: "prisma@npm:4.16.2" +"prisma@npm:6.2.1": + version: 6.2.1 + resolution: "prisma@npm:6.2.1" dependencies: - "@prisma/engines": 4.16.2 + "@prisma/engines": 6.2.1 + fsevents: 2.3.3 + dependenciesMeta: + fsevents: + optional: true bin: prisma: build/index.js - prisma2: build/index.js - checksum: 1d0ed616abd7f8de22441e333b976705f1cb05abcb206965df3fc6a7ea03911ef467dd484a4bc51fdc6cff72dd9857b9852be5f232967a444af0a98c49bfdb76 + checksum: 04232e345506c0b0fe8c5c16b15c9f0a51179501ee7c00b6bf52ad193cf38222ff0eb1f04a02b1a24feb1445bc5796f612838e93be39fdec416576883f8c2ca7 languageName: node linkType: hard -"proc-log@npm:^3.0.0": - version: 3.0.0 - resolution: "proc-log@npm:3.0.0" - checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 +"proc-log@npm:^5.0.0": + version: 5.0.0 + resolution: "proc-log@npm:5.0.0" + checksum: c78b26ecef6d5cce4a7489a1e9923d7b4b1679028c8654aef0463b27f4a90b0946cd598f55799da602895c52feb085ec76381d007ab8dcceebd40b89c2f9dfe0 languageName: node linkType: hard @@ -16289,13 +17567,6 @@ __metadata: languageName: node linkType: hard -"process@npm:^0.11.10": - version: 0.11.10 - resolution: "process@npm:0.11.10" - checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 - languageName: node - linkType: hard - "progress@npm:^2.0.0": version: 2.0.3 resolution: "progress@npm:2.0.3" @@ -16303,13 +17574,6 @@ __metadata: languageName: node linkType: hard -"promise-inflight@npm:^1.0.1": - version: 1.0.1 - resolution: "promise-inflight@npm:1.0.1" - checksum: 22749483091d2c594261517f4f80e05226d4d5ecc1fc917e1886929da56e22b5718b7f2a75f3807e7a7d471bc3be2907fe92e6e8f373ddf5c64bae35b5af3981 - languageName: node - linkType: hard - "promise-retry@npm:^2.0.1": version: 2.0.1 resolution: "promise-retry@npm:2.0.1" @@ -16329,17 +17593,7 @@ __metadata: languageName: node linkType: hard -"prompts@npm:2.4.0": - version: 2.4.0 - resolution: "prompts@npm:2.4.0" - dependencies: - kleur: ^3.0.3 - sisteransi: ^1.0.5 - checksum: 96c7bef8eb3c0bb2076d2bc5ee473f06e6d8ac01ac4d0f378dfeb0ddaf2f31c339360ec8f0f8486f78601d16ebef7c6bd9886d44b937ba01bab568b937190265 - languageName: node - linkType: hard - -"prompts@npm:^2.0.1": +"prompts@npm:^2.0.1, prompts@npm:^2.4.2": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: @@ -16349,7 +17603,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.6.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -16360,23 +17614,21 @@ __metadata: languageName: node linkType: hard -"property-expr@npm:^2.0.4": +"property-expr@npm:^2.0.5": version: 2.0.6 resolution: "property-expr@npm:2.0.6" checksum: 89977f4bb230736c1876f460dd7ca9328034502fd92e738deb40516d16564b850c0bbc4e052c3df88b5b8cd58e51c93b46a94bea049a3f23f4a022c038864cab languageName: node linkType: hard -"property-information@npm:^5.3.0": - version: 5.6.0 - resolution: "property-information@npm:5.6.0" - dependencies: - xtend: ^4.0.0 - checksum: fcf87c6542e59a8bbe31ca0b3255a4a63ac1059b01b04469680288998bcfa97f341ca989566adbb63975f4d85339030b82320c324a511532d390910d1c583893 +"property-information@npm:^7.0.0": + version: 7.1.0 + resolution: "property-information@npm:7.1.0" + checksum: 3875161d204bac89d75181f6d3ebc3ecaeb2699b4e2ecfcf5452201d7cdd275168c6742d7ff8cec5ab0c342fae72369ac705e1f8e9680a9acd911692e80dfb88 languageName: node linkType: hard -"proxy-addr@npm:~2.0.7": +"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -16393,17 +17645,12 @@ __metadata: languageName: node linkType: hard -"prr@npm:~1.0.1": - version: 1.0.1 - resolution: "prr@npm:1.0.1" - checksum: 3bca2db0479fd38f8c4c9439139b0c42dcaadcc2fbb7bb8e0e6afaa1383457f1d19aea9e5f961d5b080f1cfc05bfa1fe9e45c97a1d3fd6d421950a73d3108381 - languageName: node - linkType: hard - "psl@npm:^1.1.33": - version: 1.9.0 - resolution: "psl@npm:1.9.0" - checksum: 20c4277f640c93d393130673f392618e9a8044c6c7bf61c53917a0fddb4952790f5f362c6c730a9c32b124813e173733f9895add8d26f566ed0ea0654b2e711d + version: 1.15.0 + resolution: "psl@npm:1.15.0" + dependencies: + punycode: ^2.3.1 + checksum: 6f777d82eecfe1c2406dadbc15e77467b186fec13202ec887a45d0209a2c6fca530af94a462a477c3c4a767ad892ec9ede7c482d98f61f653dd838b50e89dc15 languageName: node linkType: hard @@ -16414,59 +17661,17 @@ __metadata: languageName: node linkType: hard -"public-encrypt@npm:^4.0.0": - version: 4.0.3 - resolution: "public-encrypt@npm:4.0.3" - dependencies: - bn.js: ^4.1.0 - browserify-rsa: ^4.0.0 - create-hash: ^1.1.0 - parse-asn1: ^5.0.0 - randombytes: ^2.0.1 - safe-buffer: ^5.1.2 - checksum: 215d446e43cef021a20b67c1df455e5eea134af0b1f9b8a35f9e850abf32991b0c307327bc5b9bc07162c288d5cdb3d4a783ea6c6640979ed7b5017e3e0c9935 - languageName: node - linkType: hard - -"pump@npm:^2.0.0": - version: 2.0.1 - resolution: "pump@npm:2.0.1" - dependencies: - end-of-stream: ^1.1.0 - once: ^1.3.1 - checksum: e9f26a17be00810bff37ad0171edb35f58b242487b0444f92fb7d78bc7d61442fa9b9c5bd93a43fd8fd8ddd3cc75f1221f5e04c790f42907e5baab7cf5e2b931 - languageName: node - linkType: hard - "pump@npm:^3.0.0": - version: 3.0.0 - resolution: "pump@npm:3.0.0" + version: 3.0.3 + resolution: "pump@npm:3.0.3" dependencies: end-of-stream: ^1.1.0 once: ^1.3.1 - checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 - languageName: node - linkType: hard - -"pumpify@npm:^1.3.3": - version: 1.5.1 - resolution: "pumpify@npm:1.5.1" - dependencies: - duplexify: ^3.6.0 - inherits: ^2.0.3 - pump: ^2.0.0 - checksum: 26ca412ec8d665bd0d5e185c1b8f627728eff603440d75d22a58e421e3c66eaf86ec6fc6a6efc54808ecef65979279fa8e99b109a23ec1fa8d79f37e6978c9bd - languageName: node - linkType: hard - -"punycode@npm:^1.2.4, punycode@npm:^1.4.1": - version: 1.4.1 - resolution: "punycode@npm:1.4.1" - checksum: fa6e698cb53db45e4628559e557ddaf554103d2a96a1d62892c8f4032cd3bc8871796cae9eabc1bc700e2b6677611521ce5bb1d9a27700086039965d0cf34518 + checksum: 52843fc933b838c0330f588388115a1b28ef2a5ffa7774709b142e35431e8ab0c2edec90de3fa34ebb72d59fef854f151eea7dfc211b6dcf586b384556bd2f39 languageName: node linkType: hard -"punycode@npm:^2.1.0, punycode@npm:^2.1.1": +"punycode@npm:^2.1.0, punycode@npm:^2.1.1, punycode@npm:^2.3.1": version: 2.3.1 resolution: "punycode@npm:2.3.1" checksum: bb0a0ceedca4c3c57a9b981b90601579058903c62be23c5e8e843d2c2d4148a3ecf029d5133486fb0e1822b098ba8bba09e89d6b21742d02fa26bda6441a6fb2 @@ -16480,45 +17685,21 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.11.0": - version: 6.11.0 - resolution: "qs@npm:6.11.0" - dependencies: - side-channel: ^1.0.4 - checksum: 6e1f29dd5385f7488ec74ac7b6c92f4d09a90408882d0c208414a34dd33badc1a621019d4c799a3df15ab9b1d0292f97c1dd71dc7c045e69f81a8064e5af7297 - languageName: node - linkType: hard - -"qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.7.0": - version: 6.12.1 - resolution: "qs@npm:6.12.1" +"qs@npm:6.13.0": + version: 6.13.0 + resolution: "qs@npm:6.13.0" dependencies: side-channel: ^1.0.6 - checksum: aa761d99e65b6936ba2dd2187f2d9976afbcda38deb3ff1b3fe331d09b0c578ed79ca2abdde1271164b5be619c521ec7db9b34c23f49a074e5921372d16242d5 + checksum: e9404dc0fc2849245107108ce9ec2766cde3be1b271de0bf1021d049dc5b98d1a2901e67b431ac5509f865420a7ed80b7acb3980099fe1c118a1c5d2e1432ad8 languageName: node linkType: hard -"query-string@npm:^4.1.0": - version: 4.3.4 - resolution: "query-string@npm:4.3.4" +"qs@npm:^6.11.0, qs@npm:^6.14.0, qs@npm:^6.7.0": + version: 6.14.0 + resolution: "qs@npm:6.14.0" dependencies: - object-assign: ^4.1.0 - strict-uri-encode: ^1.0.0 - checksum: 3b2bae6a8454cf0edf11cf1aa4d1f920398bbdabc1c39222b9bb92147e746fcd97faf00e56f494728fb66b2961b495ba0fde699d5d3bd06b11472d664b36c6cf - languageName: node - linkType: hard - -"querystring-es3@npm:^0.2.0": - version: 0.2.1 - resolution: "querystring-es3@npm:0.2.1" - checksum: 691e8d6b8b157e7cd49ae8e83fcf86de39ab3ba948c25abaa94fba84c0986c641aa2f597770848c64abce290ed17a39c9df6df737dfa7e87c3b63acc7d225d61 - languageName: node - linkType: hard - -"querystring@npm:^0.2.0": - version: 0.2.1 - resolution: "querystring@npm:0.2.1" - checksum: 7b83b45d641e75fd39cd6625ddfd44e7618e741c61e95281b57bbae8fde0afcc12cf851924559e5cc1ef9baa3b1e06e22b164ea1397d65dd94b801f678d9c8ce + side-channel: ^1.1.0 + checksum: 189b52ad4e9a0da1a16aff4c58b2a554a8dad9bd7e287c7da7446059b49ca2e33a49e570480e8be406b87fccebf134f51c373cbce36c8c83859efa0c9b71d635 languageName: node linkType: hard @@ -16536,6 +17717,13 @@ __metadata: languageName: node linkType: hard +"raf-schd@npm:^4.0.3": + version: 4.0.3 + resolution: "raf-schd@npm:4.0.3" + checksum: 45514041c5ad31fa96aef3bb3c572a843b92da2f2cd1cb4a47c9ad58e48761d3a4126e18daa32b2bfa0bc2551a42d8f324a0e40e536cb656969929602b4e8b58 + languageName: node + linkType: hard + "raf@npm:^3.4.1": version: 3.4.1 resolution: "raf@npm:3.4.1" @@ -16545,7 +17733,7 @@ __metadata: languageName: node linkType: hard -"randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": +"randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" dependencies: @@ -16554,16 +17742,6 @@ __metadata: languageName: node linkType: hard -"randomfill@npm:^1.0.3": - version: 1.0.4 - resolution: "randomfill@npm:1.0.4" - dependencies: - randombytes: ^2.0.5 - safe-buffer: ^5.1.0 - checksum: 33734bb578a868d29ee1b8555e21a36711db084065d94e019a6d03caa67debef8d6a1bfd06a2b597e32901ddc761ab483a85393f0d9a75838f1912461d4dbfc7 - languageName: node - linkType: hard - "range-parser@npm:^1.2.1, range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" @@ -16571,7 +17749,7 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.2": +"raw-body@npm:2.5.2, raw-body@npm:^2.3.3": version: 2.5.2 resolution: "raw-body@npm:2.5.2" dependencies: @@ -16583,61 +17761,123 @@ __metadata: languageName: node linkType: hard -"react-app-polyfill@npm:^2.0.0": - version: 2.0.0 - resolution: "react-app-polyfill@npm:2.0.0" +"raw-body@npm:^3.0.0": + version: 3.0.1 + resolution: "raw-body@npm:3.0.1" dependencies: - core-js: ^3.6.5 + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.7.0 + unpipe: 1.0.0 + checksum: e75e1db74337e01b78cc07f7e65692ed46aef2e0c4fb39cb25bb365a7ab04cbdb8b3541aabebe50b07a5bffec5def5674b587fd9e8fbde84c8838cbab1ad9836 + languageName: node + linkType: hard + +"rc@npm:^1.2.7": + version: 1.2.8 + resolution: "rc@npm:1.2.8" + dependencies: + deep-extend: ^0.6.0 + ini: ~1.3.0 + minimist: ^1.2.0 + strip-json-comments: ~2.0.1 + bin: + rc: ./cli.js + checksum: 2e26e052f8be2abd64e6d1dabfbd7be03f80ec18ccbc49562d31f617d0015fbdbcf0f9eed30346ea6ab789e0fdfe4337f033f8016efdbee0df5354751842080e + languageName: node + linkType: hard + +"react-app-polyfill@npm:^3.0.0": + version: 3.0.0 + resolution: "react-app-polyfill@npm:3.0.0" + dependencies: + core-js: ^3.19.2 object-assign: ^4.1.1 promise: ^8.1.0 raf: ^3.4.1 - regenerator-runtime: ^0.13.7 - whatwg-fetch: ^3.4.1 - checksum: 99e52a6b2229c7ca730cfd44ac95640f955be71d144225bd6c24fa47922a742658a371d0a2f0876d732533f1055b7cd7e9d534c89c29f8ca889ecd1b8d15f065 + regenerator-runtime: ^0.13.9 + whatwg-fetch: ^3.6.2 + checksum: 1bb031080af15397d6eb9c69a0c2e93799991f7197a086e4409ba719398f1256b542a3d6c9a34673d516c684eef3e8226c99b335982593851f58f65f6e43571b + languageName: node + linkType: hard + +"react-archer@npm:^4.4.0": + version: 4.4.0 + resolution: "react-archer@npm:4.4.0" + dependencies: + react-fast-compare: ^2.0.4 + resize-observer-polyfill: 1.5.0 + peerDependencies: + "@types/react": ^16.8.8 || ^17 || ^18 + prop-types: ^15.6.2 + react: ^16.9.0 || ^17 || ^18 + checksum: 2f675499d9af5a06911332e432af24280b38715151078a3a75b6dd7790f6756c19647928e3f67cda3b21526c6dda2729bedb17e40d1f21835a1b4873c362c6c4 + languageName: node + linkType: hard + +"react-chartjs-2@npm:5.2.0": + version: 5.2.0 + resolution: "react-chartjs-2@npm:5.2.0" + peerDependencies: + chart.js: ^4.1.1 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: ace702185be1450e5888a8bcd8b5fc1995067e3b11d236764a67f5567a3d7c32ff16923b8d48d3d39bda6e45135da6c044c9b43fbe8e1978f95aca9d2c0ce348 + languageName: node + linkType: hard + +"react-dev-utils@npm:^12.0.1": + version: 12.0.1 + resolution: "react-dev-utils@npm:12.0.1" + dependencies: + "@babel/code-frame": ^7.16.0 + address: ^1.1.2 + browserslist: ^4.18.1 + chalk: ^4.1.2 + cross-spawn: ^7.0.3 + detect-port-alt: ^1.1.6 + escape-string-regexp: ^4.0.0 + filesize: ^8.0.6 + find-up: ^5.0.0 + fork-ts-checker-webpack-plugin: ^6.5.0 + global-modules: ^2.0.0 + globby: ^11.0.4 + gzip-size: ^6.0.0 + immer: ^9.0.7 + is-root: ^2.1.0 + loader-utils: ^3.2.0 + open: ^8.4.0 + pkg-up: ^3.1.0 + prompts: ^2.4.2 + react-error-overlay: ^6.0.11 + recursive-readdir: ^2.2.2 + shell-quote: ^1.7.3 + strip-ansi: ^6.0.1 + text-table: ^0.2.0 + checksum: 2c6917e47f03d9595044770b0f883a61c6b660fcaa97b8ba459a1d57c9cca9aa374cd51296b22d461ff5e432105dbe6f04732dab128e52729c79239e1c23ab56 languageName: node linkType: hard -"react-dev-utils@npm:^11.0.3": - version: 11.0.4 - resolution: "react-dev-utils@npm:11.0.4" +"react-dom@npm:19.0.0": + version: 19.0.0 + resolution: "react-dom@npm:19.0.0" dependencies: - "@babel/code-frame": 7.10.4 - address: 1.1.2 - browserslist: 4.14.2 - chalk: 2.4.2 - cross-spawn: 7.0.3 - detect-port-alt: 1.1.6 - escape-string-regexp: 2.0.0 - filesize: 6.1.0 - find-up: 4.1.0 - fork-ts-checker-webpack-plugin: 4.1.6 - global-modules: 2.0.0 - globby: 11.0.1 - gzip-size: 5.1.1 - immer: 8.0.1 - is-root: 2.1.0 - loader-utils: 2.0.0 - open: ^7.0.2 - pkg-up: 3.1.0 - prompts: 2.4.0 - react-error-overlay: ^6.0.9 - recursive-readdir: 2.2.2 - shell-quote: 1.7.2 - strip-ansi: 6.0.0 - text-table: 0.2.0 - checksum: b41c95010a4fb60d4ea6309423520e6268757b68df34de7e9e8dbc72549236a1f5a698ff99ad72a034ac51b042aa79ee53994330ce4df05bf867e63c5464bb3f + scheduler: ^0.25.0 + peerDependencies: + react: ^19.0.0 + checksum: 009cc6e575263a0d1906f9dd4aa6532d2d3d0d71e4c2b7777c8fe4de585fa06b5b77cdc2e0fbaa2f3a4a5e5d3305c189ba152153f358ee7da4d9d9ba5d3a8975 languageName: node linkType: hard -"react-dom@npm:^18.2.0": - version: 18.2.0 - resolution: "react-dom@npm:18.2.0" +"react-draggable@npm:^4.4.6": + version: 4.5.0 + resolution: "react-draggable@npm:4.5.0" dependencies: - loose-envify: ^1.1.0 - scheduler: ^0.23.0 + clsx: ^2.1.1 + prop-types: ^15.8.1 peerDependencies: - react: ^18.2.0 - checksum: 7d323310bea3a91be2965f9468d552f201b1c27891e45ddc2d6b8f717680c95a75ae0bc1e3f5cf41472446a2589a75aed4483aee8169287909fcd59ad149e8cc + react: ">= 16.3.0" + react-dom: ">= 16.3.0" + checksum: a5563ed8142ab77e9e68af9b5a57484358462bae76368691362419d7fb4d9fba73300b5c5d1346db6551d88743c68746dc18bc035276db1539d0ad0aff6580cc languageName: node linkType: hard @@ -16652,10 +17892,17 @@ __metadata: languageName: node linkType: hard -"react-error-overlay@npm:^6.0.9": - version: 6.0.11 - resolution: "react-error-overlay@npm:6.0.11" - checksum: ce7b44c38fadba9cedd7c095cf39192e632daeccf1d0747292ed524f17dcb056d16bc197ddee5723f9dd888f0b9b19c3b486c430319e30504289b9296f2d2c42 +"react-error-overlay@npm:^6.0.11": + version: 6.1.0 + resolution: "react-error-overlay@npm:6.1.0" + checksum: 4f0785ea14390e333d040e7d7d6f8b915ad9bd4b8ae6eb28e1a5338f23a0325798d20deea7572c3c129bd1d32c432b01e7a4d40ca99710e2fa1f8157929e6cda + languageName: node + linkType: hard + +"react-fast-compare@npm:^2.0.4": + version: 2.0.4 + resolution: "react-fast-compare@npm:2.0.4" + checksum: 06046595f90a4e3e3a56f40a8078c00aa71bdb064ddb98343f577f546aa22e888831fd45f009c93b34707cc842b4c637737e956fd13d6f80607ee92fb9cf9a1c languageName: node linkType: hard @@ -16666,26 +17913,13 @@ __metadata: languageName: node linkType: hard -"react-google-charts@npm:^4.0.0": - version: 4.0.1 - resolution: "react-google-charts@npm:4.0.1" +"react-google-charts@npm:^5.2.1": + version: 5.2.1 + resolution: "react-google-charts@npm:5.2.1" peerDependencies: react: ">=16.3.0" react-dom: ">=16.3.0" - checksum: 874a552b07cc67d6b830718dd5e71055c46fbd0c7a12bca14078c0744111d8fead833e36a16bd0b0ea5c26f6cff0eb84b4b6de62845c945b3c47c6cc75233f9d - languageName: node - linkType: hard - -"react-google-login@npm:^5.2.2": - version: 5.2.2 - resolution: "react-google-login@npm:5.2.2" - dependencies: - "@types/react": "*" - prop-types: ^15.6.0 - peerDependencies: - react: ^16 || ^17 - react-dom: ^16 || ^17 - checksum: 29199c7035c3c1070a82241dc4063628d693f35a1736d292e3db736e52da825e8a53f9287b0b12b08a50d676973ce1349a4d8243cd849ca25fed6a4284378880 + checksum: 80a03fda3e9c828e9d22919fe8b2f9cdb40cb9c38b617d9de2afa1a288304ab652604149e818c9f5fe990ffc748290b5db74539c61c3720c7d85c8d7840482ce languageName: node linkType: hard @@ -16703,12 +17937,22 @@ __metadata: languageName: node linkType: hard +"react-hook-form-persist@npm:^3.0.0": + version: 3.0.0 + resolution: "react-hook-form-persist@npm:3.0.0" + peerDependencies: + react: ">= 16.3" + react-hook-form: ">= 6" + checksum: de90d45cb8ac49c636df78da96284e5f915894a639b06b95c1ce1d7da7bbd04305a52411b90693007376417dac3fd9bd3ed114dedbbae32fb15c2a588e870260 + languageName: node + linkType: hard + "react-hook-form@npm:^7.34.0": - version: 7.51.3 - resolution: "react-hook-form@npm:7.51.3" + version: 7.62.0 + resolution: "react-hook-form@npm:7.62.0" peerDependencies: - react: ^16.8.0 || ^17 || ^18 - checksum: 4ac71033b66ae0b7b9d75a1bc2053a6747fb37f68c6895ee85a72cabb890168d82990c8ca7bddd271e80fdbf58f471d14d6a0e0714400d017590d4f56b3d241f + react: ^16.8.0 || ^17 || ^18 || ^19 + checksum: 76f0574d0df632c22b37c2666e8aef8b4378dfa0bcc5ae5b20c410d3103abd17e0bcf6256f8a6d9d18cbd687f96edf3fce35bf41d06872ffb412c91664361b1a languageName: node linkType: hard @@ -16719,41 +17963,69 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^17.0.0, react-is@npm:^17.0.1": +"react-is@npm:^17.0.1": version: 17.0.2 resolution: "react-is@npm:17.0.2" checksum: 9d6d111d8990dc98bc5402c1266a808b0459b5d54830bbea24c12d908b536df7883f268a7868cfaedde3dd9d4e0d574db456f84d2e6df9c4526f99bb4b5344d8 languageName: node linkType: hard -"react-is@npm:^18.0.0, react-is@npm:^18.2.0": - version: 18.2.0 - resolution: "react-is@npm:18.2.0" - checksum: e72d0ba81b5922759e4aff17e0252bd29988f9642ed817f56b25a3e217e13eea8a7f2322af99a06edb779da12d5d636e9fda473d620df9a3da0df2a74141d53e +"react-is@npm:^18.0.0, react-is@npm:^18.3.1": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: e20fe84c86ff172fc8d898251b7cc2c43645d108bf96d0b8edf39b98f9a2cae97b40520ee7ed8ee0085ccc94736c4886294456033304151c3f94978cec03df21 + languageName: node + linkType: hard + +"react-is@npm:^19.0.0, react-is@npm:^19.1.1": + version: 19.1.1 + resolution: "react-is@npm:19.1.1" + checksum: e60ed01c27fe4d22b08f8a31f18831d144a801d08a909ca31fb1d02721b4f4cde0759148d6341f660a4d6ce54a78e22b8b39520b67e2e76254e583885868ab43 + languageName: node + linkType: hard + +"react-markdown@npm:^9.0.3": + version: 9.1.0 + resolution: "react-markdown@npm:9.1.0" + dependencies: + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + devlop: ^1.0.0 + hast-util-to-jsx-runtime: ^2.0.0 + html-url-attributes: ^3.0.0 + mdast-util-to-hast: ^13.0.0 + remark-parse: ^11.0.0 + remark-rehype: ^11.0.0 + unified: ^11.0.0 + unist-util-visit: ^5.0.0 + vfile: ^6.0.0 + peerDependencies: + "@types/react": ">=18" + react: ">=18" + checksum: d78ca3b6bea23a3383d067ad8eb0aec3a22a4500663f32773be45ad38572b5f1b823184fafc85c1a35ff6290bddea42b003dc7bdfc02cf20a9e0163ecd3ea605 languageName: node linkType: hard -"react-markdown@npm:^6.0.0": - version: 6.0.3 - resolution: "react-markdown@npm:6.0.3" +"react-pdf@npm:^9.2.1": + version: 9.2.1 + resolution: "react-pdf@npm:9.2.1" dependencies: - "@types/hast": ^2.0.0 - "@types/unist": ^2.0.3 - comma-separated-tokens: ^1.0.0 - prop-types: ^15.7.2 - property-information: ^5.3.0 - react-is: ^17.0.0 - remark-parse: ^9.0.0 - remark-rehype: ^8.0.0 - space-separated-tokens: ^1.1.0 - style-to-object: ^0.3.0 - unified: ^9.0.0 - unist-util-visit: ^2.0.0 - vfile: ^4.0.0 + clsx: ^2.0.0 + dequal: ^2.0.3 + make-cancellable-promise: ^1.3.1 + make-event-props: ^1.6.0 + merge-refs: ^1.3.0 + pdfjs-dist: 4.8.69 + tiny-invariant: ^1.0.0 + warning: ^4.0.0 peerDependencies: - "@types/react": ">=16" - react: ">=16" - checksum: 5176e6a314a397b4747570213ae6c092f76c5c3dc67c748731243a0d4108e002134a9061cea87df1bea00db46cc7d238e092bae1609de74983c844e8386c0554 + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 0d90c19e0cbc3a053479f161c18060a744f3b644d9decfac05b4186ba62a36924361f239bf4d85c713ea2e1b7b304fcc659b617148c6f261c1cc3b19ca862404 languageName: node linkType: hard @@ -16793,17 +18065,36 @@ __metadata: languageName: node linkType: hard -"react-refresh@npm:^0.14.0": - version: 0.14.0 - resolution: "react-refresh@npm:0.14.0" - checksum: dc69fa8c993df512f42dd0f1b604978ae89bd747c0ed5ec595c0cc50d535fb2696619ccd98ae28775cc01d0a7c146a532f0f7fb81dc22e1977c242a4912312f4 +"react-redux@npm:^9.1.2": + version: 9.2.0 + resolution: "react-redux@npm:9.2.0" + dependencies: + "@types/use-sync-external-store": ^0.0.6 + use-sync-external-store: ^1.4.0 + peerDependencies: + "@types/react": ^18.2.25 || ^19 + react: ^18.0 || ^19 + redux: ^5.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + redux: + optional: true + checksum: 96dfe2929561d7c98d4443722738e4595f08758bde27b7bc20cd98ba9b0dfe9b81b9fa17b6888be94a0c1d2d1305397ae493a8219698536d011a941589eb82bd languageName: node linkType: hard -"react-refresh@npm:^0.8.3": - version: 0.8.3 - resolution: "react-refresh@npm:0.8.3" - checksum: 3cffe5a9cbac1c5d59bf74bf9fff43c987d87ef32098b9092ea94b6637377d86c08565b9374d9397f446b3fbcd95de986ec77220a16f979687cb39b7b89e2f91 +"react-refresh@npm:^0.11.0": + version: 0.11.0 + resolution: "react-refresh@npm:0.11.0" + checksum: 112178a05b1e0ffeaf5d9fb4e56b4410a34a73adeb04dbf13abdc50d9ac9df2ada83e81485156cca0b3fa296aa3612751b3d6cd13be4464642a43679b819cbc7 + languageName: node + linkType: hard + +"react-refresh@npm:^0.17.0": + version: 0.17.0 + resolution: "react-refresh@npm:0.17.0" + checksum: e9d23a70543edde879263976d7909cd30c6f698fa372a1240142cf7c8bf99e0396378b9c07c2d39c3a10261d7ba07dc49f990cd8f1ac7b88952e99040a0be5e9 languageName: node linkType: hard @@ -16843,69 +18134,58 @@ __metadata: languageName: node linkType: hard -"react-scripts@npm:^4.0.1": - version: 4.0.3 - resolution: "react-scripts@npm:4.0.3" - dependencies: - "@babel/core": 7.12.3 - "@pmmmwh/react-refresh-webpack-plugin": 0.4.3 - "@svgr/webpack": 5.5.0 - "@typescript-eslint/eslint-plugin": ^4.5.0 - "@typescript-eslint/parser": ^4.5.0 - babel-eslint: ^10.1.0 - babel-jest: ^26.6.0 - babel-loader: 8.1.0 - babel-plugin-named-asset-import: ^0.3.7 - babel-preset-react-app: ^10.0.0 +"react-scripts@npm:^5.0.1": + version: 5.0.1 + resolution: "react-scripts@npm:5.0.1" + dependencies: + "@babel/core": ^7.16.0 + "@pmmmwh/react-refresh-webpack-plugin": ^0.5.3 + "@svgr/webpack": ^5.5.0 + babel-jest: ^27.4.2 + babel-loader: ^8.2.3 + babel-plugin-named-asset-import: ^0.3.8 + babel-preset-react-app: ^10.0.1 bfj: ^7.0.2 - camelcase: ^6.1.0 - case-sensitive-paths-webpack-plugin: 2.3.0 - css-loader: 4.3.0 - dotenv: 8.2.0 - dotenv-expand: 5.1.0 - eslint: ^7.11.0 - eslint-config-react-app: ^6.0.0 - eslint-plugin-flowtype: ^5.2.0 - eslint-plugin-import: ^2.22.1 - eslint-plugin-jest: ^24.1.0 - eslint-plugin-jsx-a11y: ^6.3.1 - eslint-plugin-react: ^7.21.5 - eslint-plugin-react-hooks: ^4.2.0 - eslint-plugin-testing-library: ^3.9.2 - eslint-webpack-plugin: ^2.5.2 - file-loader: 6.1.1 - fs-extra: ^9.0.1 - fsevents: ^2.1.3 - html-webpack-plugin: 4.5.0 - identity-obj-proxy: 3.0.0 - jest: 26.6.0 - jest-circus: 26.6.0 - jest-resolve: 26.6.0 - jest-watch-typeahead: 0.6.1 - mini-css-extract-plugin: 0.11.3 - optimize-css-assets-webpack-plugin: 5.0.4 - pnp-webpack-plugin: 1.6.4 - postcss-flexbugs-fixes: 4.2.1 - postcss-loader: 3.0.0 - postcss-normalize: 8.0.1 - postcss-preset-env: 6.7.0 - postcss-safe-parser: 5.0.2 - prompts: 2.4.0 - react-app-polyfill: ^2.0.0 - react-dev-utils: ^11.0.3 - react-refresh: ^0.8.3 - resolve: 1.18.1 - resolve-url-loader: ^3.1.2 - sass-loader: ^10.0.5 - semver: 7.3.2 - style-loader: 1.3.0 - terser-webpack-plugin: 4.2.3 - ts-pnp: 1.2.0 - url-loader: 4.1.1 - webpack: 4.44.2 - webpack-dev-server: 3.11.1 - webpack-manifest-plugin: 2.2.0 - workbox-webpack-plugin: 5.1.4 + browserslist: ^4.18.1 + camelcase: ^6.2.1 + case-sensitive-paths-webpack-plugin: ^2.4.0 + css-loader: ^6.5.1 + css-minimizer-webpack-plugin: ^3.2.0 + dotenv: ^10.0.0 + dotenv-expand: ^5.1.0 + eslint: ^8.3.0 + eslint-config-react-app: ^7.0.1 + eslint-webpack-plugin: ^3.1.1 + file-loader: ^6.2.0 + fs-extra: ^10.0.0 + fsevents: ^2.3.2 + html-webpack-plugin: ^5.5.0 + identity-obj-proxy: ^3.0.0 + jest: ^27.4.3 + jest-resolve: ^27.4.2 + jest-watch-typeahead: ^1.0.0 + mini-css-extract-plugin: ^2.4.5 + postcss: ^8.4.4 + postcss-flexbugs-fixes: ^5.0.2 + postcss-loader: ^6.2.1 + postcss-normalize: ^10.0.1 + postcss-preset-env: ^7.0.1 + prompts: ^2.4.2 + react-app-polyfill: ^3.0.0 + react-dev-utils: ^12.0.1 + react-refresh: ^0.11.0 + resolve: ^1.20.0 + resolve-url-loader: ^4.0.0 + sass-loader: ^12.3.0 + semver: ^7.3.5 + source-map-loader: ^3.0.0 + style-loader: ^3.3.1 + tailwindcss: ^3.0.2 + terser-webpack-plugin: ^5.2.5 + webpack: ^5.64.4 + webpack-dev-server: ^4.6.0 + webpack-manifest-plugin: ^4.0.2 + workbox-webpack-plugin: ^6.4.1 peerDependencies: react: ">= 16" typescript: ^3.2.1 || ^4 @@ -16916,8 +18196,8 @@ __metadata: typescript: optional: true bin: - react-scripts: ./bin/react-scripts.js - checksum: a05a46ce3145b42ac8b57633d3b90b6689c24697c1449bccf219349996d718a3cd0796e4910f4ab6abb5b024982cafd62345e88c8e7b42a45efca3bef1a0eb87 + react-scripts: bin/react-scripts.js + checksum: 92afa2f245c7092ccc97d5609dc7a2130616262e34da7f15072d9442e2d2e1d4909a91022abd1faac1336eb17c5525a10d9bd43e1ae374c7ec941ca20addca68 languageName: node linkType: hard @@ -16930,6 +18210,20 @@ __metadata: languageName: node linkType: hard +"react-smooth@npm:^4.0.4": + version: 4.0.4 + resolution: "react-smooth@npm:4.0.4" + dependencies: + fast-equals: ^5.0.1 + prop-types: ^15.8.1 + react-transition-group: ^4.4.5 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 909305d40bae79a011ff21a10c4bc7ddadc87ac5ff093b4a5f827f730f093ec4e044c4330688d29b3ad2db83aab8997c3bb1bae550a9c66de74521b8ed52cc53 + languageName: node + linkType: hard + "react-transition-group@npm:^4.4.5": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5" @@ -16946,61 +18240,35 @@ __metadata: linkType: hard "react-use-measure@npm:^2.1.1": - version: 2.1.1 - resolution: "react-use-measure@npm:2.1.1" - dependencies: - debounce: ^1.2.1 + version: 2.1.7 + resolution: "react-use-measure@npm:2.1.7" peerDependencies: react: ">=16.13" react-dom: ">=16.13" - checksum: b8e8939229d463c3c505f7b617925c0228efae0cd6f651371f463846417b06c9170be57df51293a61027c41770f8a090fdb8a08717c4e36290ccb496e0318f1f - languageName: node - linkType: hard - -"react@npm:^18.2.0": - version: 18.2.0 - resolution: "react@npm:18.2.0" - dependencies: - loose-envify: ^1.1.0 - checksum: 88e38092da8839b830cda6feef2e8505dec8ace60579e46aa5490fc3dc9bba0bd50336507dc166f43e3afc1c42939c09fe33b25fae889d6f402721dcd78fca1b - languageName: node - linkType: hard - -"read-pkg-up@npm:^7.0.1": - version: 7.0.1 - resolution: "read-pkg-up@npm:7.0.1" - dependencies: - find-up: ^4.1.0 - read-pkg: ^5.2.0 - type-fest: ^0.8.1 - checksum: e4e93ce70e5905b490ca8f883eb9e48b5d3cebc6cd4527c25a0d8f3ae2903bd4121c5ab9c5a3e217ada0141098eeb661313c86fa008524b089b8ed0b7f165e44 + peerDependenciesMeta: + react-dom: + optional: true + checksum: 5f00c14cf50b0710cdbd27b63a005be20283099d2fa2723a97f3a1cf0b2daedddd67249520c21e49e95348f56428689f3229c343dcb9ed37da58f9c227d29bee languageName: node linkType: hard -"read-pkg@npm:^4.0.1": - version: 4.0.1 - resolution: "read-pkg@npm:4.0.1" - dependencies: - normalize-package-data: ^2.3.2 - parse-json: ^4.0.0 - pify: ^3.0.0 - checksum: 56193535486c50a0a40039e4a92f68676362f5a7160628ca4d856c62509e125220f69c562a32940dcc51e3dcd38211af69756bbb5b8a1aed1d09be1bedd1e1a5 +"react@npm:19.0.0": + version: 19.0.0 + resolution: "react@npm:19.0.0" + checksum: 86de15d85b2465feb40297a90319c325cb07cf27191a361d47bcfe8c6126c973d660125aa67b8f4cbbe39f15a2f32efd0c814e98196d8e5b68c567ba40a399c6 languageName: node linkType: hard -"read-pkg@npm:^5.2.0": - version: 5.2.0 - resolution: "read-pkg@npm:5.2.0" +"read-cache@npm:^1.0.0": + version: 1.0.0 + resolution: "read-cache@npm:1.0.0" dependencies: - "@types/normalize-package-data": ^2.4.0 - normalize-package-data: ^2.5.0 - parse-json: ^5.0.0 - type-fest: ^0.6.0 - checksum: eb696e60528b29aebe10e499ba93f44991908c57d70f2d26f369e46b8b9afc208ef11b4ba64f67630f31df8b6872129e0a8933c8c53b7b4daf0eace536901222 + pify: ^2.3.0 + checksum: cffc728b9ede1e0667399903f9ecaf3789888b041c46ca53382fa3a06303e5132774dc0a96d0c16aa702dbac1ea0833d5a868d414f5ab2af1e1438e19e6657c6 languageName: node linkType: hard -"readable-stream@npm:1 || 2, readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.1.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.6, readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.0.1, readable-stream@npm:^2.2.2": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -17015,7 +18283,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.0.2, readable-stream@npm:^3.0.6, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": +"readable-stream@npm:^3.0.2, readable-stream@npm:^3.0.6, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -17026,14 +18294,10 @@ __metadata: languageName: node linkType: hard -"readdirp@npm:^2.2.1": - version: 2.2.1 - resolution: "readdirp@npm:2.2.1" - dependencies: - graceful-fs: ^4.1.11 - micromatch: ^3.1.10 - readable-stream: ^2.0.2 - checksum: 3879b20f1a871e0e004a14fbf1776e65ee0b746a62f5a416010808b37c272ac49b023c47042c7b1e281cba75a449696635bc64c397ed221ea81d853a8f2ed79a +"readdirp@npm:^4.0.1": + version: 4.1.2 + resolution: "readdirp@npm:4.1.2" + checksum: 3242ee125422cb7c0e12d51452e993f507e6ed3d8c490bc8bf3366c5cdd09167562224e429b13e9cb2b98d4b8b2b11dc100d3c73883aa92d657ade5a21ded004 languageName: node linkType: hard @@ -17046,12 +18310,40 @@ __metadata: languageName: node linkType: hard -"recursive-readdir@npm:2.2.2": - version: 2.2.2 - resolution: "recursive-readdir@npm:2.2.2" +"recharts-scale@npm:^0.4.4": + version: 0.4.5 + resolution: "recharts-scale@npm:0.4.5" + dependencies: + decimal.js-light: ^2.4.1 + checksum: e970377190a610e684a32c7461c7684ac3603c2e0ac0020bbba1eea9d099b38138143a8e80bf769bb49c0b7cecf22a2f5c6854885efed2d56f4540d4aa7052bd + languageName: node + linkType: hard + +"recharts@npm:^2.15.3": + version: 2.15.4 + resolution: "recharts@npm:2.15.4" + dependencies: + clsx: ^2.0.0 + eventemitter3: ^4.0.1 + lodash: ^4.17.21 + react-is: ^18.3.1 + react-smooth: ^4.0.4 + recharts-scale: ^0.4.4 + tiny-invariant: ^1.3.1 + victory-vendor: ^36.6.8 + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 7d7d89da8875a7aa3e157d4caf6c8fdbaf22fcf111c70cd67d8259dca6b7f878287b6f2db5af9b2daf6a85046de06ca2dcf18cb7cd7bb5a6ddd3639690c5d888 + languageName: node + linkType: hard + +"recursive-readdir@npm:^2.2.2": + version: 2.2.3 + resolution: "recursive-readdir@npm:2.2.3" dependencies: - minimatch: 3.0.4 - checksum: a6b22994d76458443d4a27f5fd7147ac63ad31bba972666a291d511d4d819ee40ff71ba7524c14f6a565b8cfaf7f48b318f971804b913cf538d58f04e25d1fee + minimatch: ^3.0.5 + checksum: 88ec96e276237290607edc0872b4f9842837b95cfde0cdbb1e00ba9623dfdf3514d44cdd14496ab60a0c2dd180a6ef8a3f1c34599e6cf2273afac9b72a6fb2b5 languageName: node linkType: hard @@ -17065,27 +18357,35 @@ __metadata: languageName: node linkType: hard -"reflect.getprototypeof@npm:^1.0.4": - version: 1.0.6 - resolution: "reflect.getprototypeof@npm:1.0.6" +"redux@npm:^5.0.1": + version: 5.0.1 + resolution: "redux@npm:5.0.1" + checksum: e74affa9009dd5d994878b9a1ce30d6569d986117175056edb003de2651c05b10fe7819d6fa94aea1a94de9a82f252f986547f007a2fbeb35c317a2e5f5ecf2c + languageName: node + linkType: hard + +"reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9": + version: 1.0.10 + resolution: "reflect.getprototypeof@npm:1.0.10" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.8 define-properties: ^1.2.1 - es-abstract: ^1.23.1 + es-abstract: ^1.23.9 es-errors: ^1.3.0 - get-intrinsic: ^1.2.4 - globalthis: ^1.0.3 - which-builtin-type: ^1.1.3 - checksum: 88e9e65a7eaa0bf8e9a8bbf8ac07571363bc333ba8b6769ed5e013e0042ed7c385e97fae9049510b3b5fe4b42472d8f32de9ce8ce84902bc4297d4bbe3777dba + es-object-atoms: ^1.0.0 + get-intrinsic: ^1.2.7 + get-proto: ^1.0.1 + which-builtin-type: ^1.2.1 + checksum: ccc5debeb66125e276ae73909cecb27e47c35d9bb79d9cc8d8d055f008c58010ab8cb401299786e505e4aab733a64cba9daf5f312a58e96a43df66adad221870 languageName: node linkType: hard -"regenerate-unicode-properties@npm:^10.1.0": - version: 10.1.1 - resolution: "regenerate-unicode-properties@npm:10.1.1" +"regenerate-unicode-properties@npm:^10.2.2": + version: 10.2.2 + resolution: "regenerate-unicode-properties@npm:10.2.2" dependencies: regenerate: ^1.4.2 - checksum: b80958ef40f125275824c2c47d5081dfaefebd80bff26c76761e9236767c748a4a95a69c053fe29d2df881177f2ca85df4a71fe70a82360388b31159ef19adcf + checksum: 7ae4c1c32460c4360e3118c45eec0621424908f430fdd6f162c9172067786bf2b1682fbc885a33b26bc85e76e06f4d3f398b52425e801b0bb0cbae147dafb0b2 languageName: node linkType: hard @@ -17096,62 +18396,31 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.11.0": - version: 0.11.1 - resolution: "regenerator-runtime@npm:0.11.1" - checksum: 3c97bd2c7b2b3247e6f8e2147a002eb78c995323732dad5dc70fac8d8d0b758d0295e7015b90d3d444446ae77cbd24b9f9123ec3a77018e81d8999818301b4f4 - languageName: node - linkType: hard - -"regenerator-runtime@npm:^0.13.7": +"regenerator-runtime@npm:^0.13.9": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4 languageName: node linkType: hard -"regenerator-runtime@npm:^0.14.0": - version: 0.14.1 - resolution: "regenerator-runtime@npm:0.14.1" - checksum: 9f57c93277b5585d3c83b0cf76be47b473ae8c6d9142a46ce8b0291a04bb2cf902059f0f8445dcabb3fb7378e5fe4bb4ea1e008876343d42e46d3b484534ce38 - languageName: node - linkType: hard - -"regenerator-transform@npm:^0.15.2": - version: 0.15.2 - resolution: "regenerator-transform@npm:0.15.2" - dependencies: - "@babel/runtime": ^7.8.4 - checksum: 20b6f9377d65954980fe044cfdd160de98df415b4bff38fbade67b3337efaf078308c4fed943067cd759827cc8cfeca9cb28ccda1f08333b85d6a2acbd022c27 - languageName: node - linkType: hard - -"regex-not@npm:^1.0.0, regex-not@npm:^1.0.2": - version: 1.0.2 - resolution: "regex-not@npm:1.0.2" - dependencies: - extend-shallow: ^3.0.2 - safe-regex: ^1.1.0 - checksum: 3081403de79559387a35ef9d033740e41818a559512668cef3d12da4e8a29ef34ee13c8ed1256b07e27ae392790172e8a15c8a06b72962fd4550476cde3d8f77 - languageName: node - linkType: hard - "regex-parser@npm:^2.2.11": - version: 2.3.0 - resolution: "regex-parser@npm:2.3.0" - checksum: bcd1eb7e9b0775b6f44928ceb0280ad5b6e4da91e1070d3e9a653fcf72d2d04873c44190fb569141b6897fe94e9514fee1f3ac7ba112ccd9c9b5ad6eabab6bbd + version: 2.3.1 + resolution: "regex-parser@npm:2.3.1" + checksum: 37d5549040782207b98a5c007b739f85bf43f70249cbf813954d3fab370b93f3c8029534c62ca7c56e7a61e24848118b1bae15668b80ab7e67b4bb98465d54cc languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.2": - version: 1.5.2 - resolution: "regexp.prototype.flags@npm:1.5.2" +"regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": + version: 1.5.4 + resolution: "regexp.prototype.flags@npm:1.5.4" dependencies: - call-bind: ^1.0.6 + call-bind: ^1.0.8 define-properties: ^1.2.1 es-errors: ^1.3.0 - set-function-name: ^2.0.1 - checksum: d7f333667d5c564e2d7a97c56c3075d64c722c9bb51b2b4df6822b2e8096d623a5e63088fb4c83df919b6951ef8113841de8b47de7224872fa6838bc5d8a7d64 + get-proto: ^1.0.1 + gopd: ^1.2.0 + set-function-name: ^2.0.2 + checksum: 18cb667e56cb328d2dda569d7f04e3ea78f2683135b866d606538cf7b1d4271f7f749f09608c877527799e6cf350e531368f3c7a20ccd1bb41048a48926bdeeb languageName: node linkType: hard @@ -17162,28 +18431,35 @@ __metadata: languageName: node linkType: hard -"regexpu-core@npm:^5.3.1": - version: 5.3.2 - resolution: "regexpu-core@npm:5.3.2" +"regexpu-core@npm:^6.2.0": + version: 6.3.1 + resolution: "regexpu-core@npm:6.3.1" dependencies: - "@babel/regjsgen": ^0.8.0 regenerate: ^1.4.2 - regenerate-unicode-properties: ^10.1.0 - regjsparser: ^0.9.1 + regenerate-unicode-properties: ^10.2.2 + regjsgen: ^0.8.0 + regjsparser: ^0.12.0 unicode-match-property-ecmascript: ^2.0.0 - unicode-match-property-value-ecmascript: ^2.1.0 - checksum: 95bb97088419f5396e07769b7de96f995f58137ad75fac5811fb5fe53737766dfff35d66a0ee66babb1eb55386ef981feaef392f9df6d671f3c124812ba24da2 + unicode-match-property-value-ecmascript: ^2.2.1 + checksum: 601a8298bca4d074c239e3b989b3b5f7532e4c8bde4e6d45690d4ba01d4f331869df3899a260a0fd88ecdb8902082725845447b0e2a3e1b0a1364131970489cb + languageName: node + linkType: hard + +"regjsgen@npm:^0.8.0": + version: 0.8.0 + resolution: "regjsgen@npm:0.8.0" + checksum: a1d925ff14a4b2be774e45775ee6b33b256f89c42d480e6d85152d2133f18bd3d6af662161b226fa57466f7efec367eaf7ccd2a58c0ec2a1306667ba2ad07b0d languageName: node linkType: hard -"regjsparser@npm:^0.9.1": - version: 0.9.1 - resolution: "regjsparser@npm:0.9.1" +"regjsparser@npm:^0.12.0": + version: 0.12.0 + resolution: "regjsparser@npm:0.12.0" dependencies: - jsesc: ~0.5.0 + jsesc: ~3.0.2 bin: regjsparser: bin/parser - checksum: 5e1b76afe8f1d03c3beaf9e0d935dd467589c3625f6d65fb8ffa14f224d783a0fed4bf49c2c1b8211043ef92b6117313419edf055a098ed8342e340586741afc + checksum: 094b55b0ab3e1fd58f8ce5132a1d44dab08d91f7b0eea4132b0157b303ebb8ded20a9cbd893d25402d2aeddb23fac1f428ab4947b295d6fa51dd1c334a9e76f0 languageName: node linkType: hard @@ -17194,21 +18470,28 @@ __metadata: languageName: node linkType: hard -"remark-parse@npm:^9.0.0": - version: 9.0.0 - resolution: "remark-parse@npm:9.0.0" +"remark-parse@npm:^11.0.0": + version: 11.0.0 + resolution: "remark-parse@npm:11.0.0" dependencies: - mdast-util-from-markdown: ^0.8.0 - checksum: 50104880549639b7dd7ae6f1e23c214915fe9c054f02f3328abdaee3f6de6d7282bf4357c3c5b106958fe75e644a3c248c2197755df34f9955e8e028fc74868f + "@types/mdast": ^4.0.0 + mdast-util-from-markdown: ^2.0.0 + micromark-util-types: ^2.0.0 + unified: ^11.0.0 + checksum: d83d245290fa84bb04fb3e78111f09c74f7417e7c012a64dd8dc04fccc3699036d828fbd8eeec8944f774b6c30cc1d925c98f8c46495ebcee7c595496342ab7f languageName: node linkType: hard -"remark-rehype@npm:^8.0.0": - version: 8.1.0 - resolution: "remark-rehype@npm:8.1.0" +"remark-rehype@npm:^11.0.0": + version: 11.1.2 + resolution: "remark-rehype@npm:11.1.2" dependencies: - mdast-util-to-hast: ^10.2.0 - checksum: e1152464cfa83c14b570b1cb85eb9b3667795b5bed2f6b16d1c6e96c369816b07945a3c04eb0e1fd57a19cc1837969527d0056d5b6d179f1290688db2a7e2c5f + "@types/hast": ^3.0.0 + "@types/mdast": ^4.0.0 + mdast-util-to-hast: ^13.0.0 + unified: ^11.0.0 + vfile: ^6.0.0 + checksum: 6eab55cb3464ec01d8e002cc9fe02ae57f48162899693fd53b5ba553ac8699dae7b55fce9df7131a5981313b19b495d6fbfa98a9d6bd243e7485591364d9b5b3 languageName: node linkType: hard @@ -17219,37 +18502,16 @@ __metadata: languageName: node linkType: hard -"remove-trailing-separator@npm:^1.0.1": - version: 1.1.0 - resolution: "remove-trailing-separator@npm:1.1.0" - checksum: d3c20b5a2d987db13e1cca9385d56ecfa1641bae143b620835ac02a6b70ab88f68f117a0021838db826c57b31373d609d52e4f31aca75fc490c862732d595419 - languageName: node - linkType: hard - -"renderkid@npm:^2.0.4": - version: 2.0.7 - resolution: "renderkid@npm:2.0.7" +"renderkid@npm:^3.0.0": + version: 3.0.0 + resolution: "renderkid@npm:3.0.0" dependencies: css-select: ^4.1.3 dom-converter: ^0.2.0 htmlparser2: ^6.1.0 lodash: ^4.17.21 - strip-ansi: ^3.0.1 - checksum: d3d7562531fb8104154d4aa6aa977707783616318014088378a6c5bbc36318ada9289543d380ede707e531b7f5b96229e87d1b8944f675e5ec3686e62692c7c7 - languageName: node - linkType: hard - -"repeat-element@npm:^1.1.2": - version: 1.1.4 - resolution: "repeat-element@npm:1.1.4" - checksum: 1edd0301b7edad71808baad226f0890ba709443f03a698224c9ee4f2494c317892dc5211b2ba8cbea7194a9ddbcac01e283bd66de0467ab24ee1fc1a3711d8a9 - languageName: node - linkType: hard - -"repeat-string@npm:^1.6.1": - version: 1.6.1 - resolution: "repeat-string@npm:1.6.1" - checksum: 1b809fc6db97decdc68f5b12c4d1a671c8e3f65ec4a40c238bc5200e44e85bcc52a54f78268ab9c29fcf5fe4f1343e805420056d1f30fa9a9ee4c2d93e3cc6c0 + strip-ansi: ^6.0.1 + checksum: 77162b62d6f33ab81f337c39efce0439ff0d1f6d441e29c35183151f83041c7850774fb904da163d6c844264d440d10557714e6daa0b19e4561a5cd4ef305d41 languageName: node linkType: hard @@ -17295,12 +18557,10 @@ __metadata: languageName: node linkType: hard -"resolve-cwd@npm:^2.0.0": - version: 2.0.0 - resolution: "resolve-cwd@npm:2.0.0" - dependencies: - resolve-from: ^3.0.0 - checksum: e7c16880c460656e77f102d537a6dc82b3657d9173697cd6ea82ffce37df96f6c1fc79d0bb35fd73fff8871ac13f21b4396958b5f0a13e5b99c97d69f5e319fa +"resize-observer-polyfill@npm:1.5.0": + version: 1.5.0 + resolution: "resize-observer-polyfill@npm:1.5.0" + checksum: ecc6aab5d4f967f1b76cee0748c1967c8b6b5d8c4393764ca3b788dbd15c0f846326c4ebff9f4f39aba45fea8016cd42bb95e28e8fab1d14349e173790c58133 languageName: node linkType: hard @@ -17313,13 +18573,6 @@ __metadata: languageName: node linkType: hard -"resolve-from@npm:^3.0.0": - version: 3.0.0 - resolution: "resolve-from@npm:3.0.0" - checksum: fff9819254d2d62b57f74e5c2ca9c0bdd425ca47287c4d801bc15f947533148d858229ded7793b0f59e61e49e782fffd6722048add12996e1bd4333c29669062 - languageName: node - linkType: hard - "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -17341,51 +18594,44 @@ __metadata: languageName: node linkType: hard -"resolve-url-loader@npm:^3.1.2": - version: 3.1.5 - resolution: "resolve-url-loader@npm:3.1.5" - dependencies: - adjust-sourcemap-loader: 3.0.0 - camelcase: 5.3.1 - compose-function: 3.0.3 - convert-source-map: 1.7.0 - es6-iterator: 2.0.3 - loader-utils: ^1.2.3 - postcss: 7.0.36 +"resolve-url-loader@npm:^4.0.0": + version: 4.0.0 + resolution: "resolve-url-loader@npm:4.0.0" + dependencies: + adjust-sourcemap-loader: ^4.0.0 + convert-source-map: ^1.7.0 + loader-utils: ^2.0.0 + postcss: ^7.0.35 + source-map: 0.6.1 + peerDependencies: rework: 1.0.1 rework-visit: 1.0.0 - source-map: 0.6.1 - checksum: eb52911eff20723f07409cc12138d254fa0dd4a4f3b1ba11ee1b29912afb03f1272aaddb523658be1e3a946e0d1bf6f603d0e107753ab83d48ad2116cf04b7f6 - languageName: node - linkType: hard - -"resolve-url@npm:^0.2.1": - version: 0.2.1 - resolution: "resolve-url@npm:0.2.1" - checksum: 7b7035b9ed6e7bc7d289e90aef1eab5a43834539695dac6416ca6e91f1a94132ae4796bbd173cdacfdc2ade90b5f38a3fb6186bebc1b221cd157777a23b9ad14 + peerDependenciesMeta: + rework: + optional: true + rework-visit: + optional: true + checksum: 8e5bcf97867a5e128b6b86988d445b7fbd1214f7c5c0214332f835e8607438e153d9b3899799a03ddd03540254bb591e572feb330981a4478be934f6f045c925 languageName: node linkType: hard -"resolve@npm:1.18.1": - version: 1.18.1 - resolution: "resolve@npm:1.18.1" - dependencies: - is-core-module: ^2.0.0 - path-parse: ^1.0.6 - checksum: bab3686fa87576ac7e7f68481e25494f99b8413f3bc5048c5284eabe021f98917a50c625f8a1920a87ffc347b076c12a4a685d46d5fc98f337cf2dd3792014f4 +"resolve.exports@npm:^1.1.0": + version: 1.1.1 + resolution: "resolve.exports@npm:1.1.1" + checksum: 485aa10082eb388a569d696e17ad7b16f4186efc97dd34eadd029d95b811f21ffee13b1b733198bb4584dbb3cb296aa6f141835221fb7613b9606b84f1386655 languageName: node linkType: hard -"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.18.1, resolve@npm:^1.19.0, resolve@npm:^1.22.4, resolve@npm:^1.3.2": - version: 1.22.8 - resolution: "resolve@npm:1.22.8" +"resolve@npm:^1.1.7, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.10, resolve@npm:^1.22.4, resolve@npm:^1.22.8": + version: 1.22.10 + resolution: "resolve@npm:1.22.10" dependencies: - is-core-module: ^2.13.0 + is-core-module: ^2.16.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: f8a26958aa572c9b064562750b52131a37c29d072478ea32e129063e2da7f83e31f7f11e7087a18225a8561cfe8d2f0df9dbea7c9d331a897571c0a2527dbb4c + checksum: ab7a32ff4046fcd7c6fdd525b24a7527847d03c3650c733b909b01b757f92eb23510afa9cc3e9bf3f26a3e073b48c88c706dfd4c1d2fb4a16a96b73b6328ddcf languageName: node linkType: hard @@ -17402,26 +18648,16 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@1.18.1#~builtin": - version: 1.18.1 - resolution: "resolve@patch:resolve@npm%3A1.18.1#~builtin::version=1.18.1&hash=07638b" - dependencies: - is-core-module: ^2.0.0 - path-parse: ^1.0.6 - checksum: 7439c8f3d8fa00c9dc800ef3c8ed0bd8e8772823e6e4948b1a77487759e0fb905381808caae96398d135619af90654d8e74cac778e5b8c9d7138f2dd52bb2bba - languageName: node - linkType: hard - -"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.18.1#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.3.2#~builtin": - version: 1.22.8 - resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=07638b" +"resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.10#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.22.8#~builtin": + version: 1.22.10 + resolution: "resolve@patch:resolve@npm%3A1.22.10#~builtin::version=1.22.10&hash=07638b" dependencies: - is-core-module: ^2.13.0 + is-core-module: ^2.16.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 5479b7d431cacd5185f8db64bfcb7286ae5e31eb299f4c4f404ad8aa6098b77599563ac4257cb2c37a42f59dfc06a1bec2bcf283bb448f319e37f0feb9a09847 + checksum: 8aac1e4e4628bd00bf4b94b23de137dd3fe44097a8d528fd66db74484be929936e20c696e1a3edf4488f37e14180b73df6f600992baea3e089e8674291f16c9d languageName: node linkType: hard @@ -17438,23 +18674,6 @@ __metadata: languageName: node linkType: hard -"restore-cursor@npm:^3.1.0": - version: 3.1.0 - resolution: "restore-cursor@npm:3.1.0" - dependencies: - onetime: ^5.1.0 - signal-exit: ^3.0.2 - checksum: f877dd8741796b909f2a82454ec111afb84eb45890eb49ac947d87991379406b3b83ff9673a46012fca0d7844bb989f45cc5b788254cf1a39b6b5a9659de0630 - languageName: node - linkType: hard - -"ret@npm:~0.1.10": - version: 0.1.15 - resolution: "ret@npm:0.1.15" - checksum: d76a9159eb8c946586567bd934358dfc08a36367b3257f7a3d7255fdd7b56597235af23c6afa0d7f0254159e8051f93c918809962ebd6df24ca2a83dbe4d4151 - languageName: node - linkType: hard - "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -17469,41 +18688,17 @@ __metadata: languageName: node linkType: hard -"reusify@npm:^1.0.4": - version: 1.0.4 - resolution: "reusify@npm:1.0.4" - checksum: c3076ebcc22a6bc252cb0b9c77561795256c22b757f40c0d8110b1300723f15ec0fc8685e8d4ea6d7666f36c79ccc793b1939c748bf36f18f542744a4e379fcc - languageName: node - linkType: hard - -"rework-visit@npm:1.0.0": - version: 1.0.0 - resolution: "rework-visit@npm:1.0.0" - checksum: 969ca1f4e5bf4a1755c464a9b498da51eb3f28a798cf73da2cf0a3a3ab7b21a2f05c9d3bfa5fb81c8aaf5487dd31679efa67b8d0f418277ef5deb2a230b17c81 - languageName: node - linkType: hard - -"rework@npm:1.0.1": - version: 1.0.1 - resolution: "rework@npm:1.0.1" - dependencies: - convert-source-map: ^0.3.3 - css: ^2.0.0 - checksum: 13e5054d81ac84eee488fd4bacd20d08f35683bd8e296b4358e7f0a41b2d30a959313b7794f388f336705ad18d36af6ee7080e1b6c1313ecf33bc51d1bd95971 - languageName: node - linkType: hard - -"rgb-regex@npm:^1.0.1": - version: 1.0.1 - resolution: "rgb-regex@npm:1.0.1" - checksum: b270ce8bc14782d2d21d3184c1e6c65b465476d8f03e72b93ef57c95710a452b2fe280e1d516c88873aec06efd7f71373e673f114b9d99f3a4f9a0393eb00126 +"rettime@npm:^0.7.0": + version: 0.7.0 + resolution: "rettime@npm:0.7.0" + checksum: 1ad3984a4f8000adf56c623882170115d7453b3bbaed56429a40077b067fad98c1c5db9a58e63793add15a97006fa7c817516d985c3347df40b5d274dc087803 languageName: node linkType: hard -"rgba-regex@npm:^1.0.0": - version: 1.0.0 - resolution: "rgba-regex@npm:1.0.0" - checksum: 7f2cd271572700faea50753d82524cb2b98f17a5b9722965c7076f6cd674fe545f28145b7ef2cccabc9eca2475c793db16862cd5e7b3784a9f4b8d6496431057 +"reusify@npm:^1.0.4": + version: 1.1.0 + resolution: "reusify@npm:1.1.0" + checksum: 64cb3142ac5e9ad689aca289585cb41d22521f4571f73e9488af39f6b1bd62f0cbb3d65e2ecc768ec6494052523f473f1eb4b55c3e9014b3590c17fc6a03e22a languageName: node linkType: hard @@ -17518,102 +18713,134 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^2.5.4, rimraf@npm:^2.6.3": - version: 2.7.1 - resolution: "rimraf@npm:2.7.1" +"rimraf@npm:^6.0.1": + version: 6.0.1 + resolution: "rimraf@npm:6.0.1" dependencies: - glob: ^7.1.3 + glob: ^11.0.0 + package-json-from-dist: ^1.0.0 bin: - rimraf: ./bin.js - checksum: cdc7f6eacb17927f2a075117a823e1c5951792c6498ebcce81ca8203454a811d4cf8900314154d3259bb8f0b42ab17f67396a8694a54cae3283326e57ad250cd - languageName: node - linkType: hard - -"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": - version: 2.0.2 - resolution: "ripemd160@npm:2.0.2" - dependencies: - hash-base: ^3.0.0 - inherits: ^2.0.1 - checksum: 006accc40578ee2beae382757c4ce2908a826b27e2b079efdcd2959ee544ddf210b7b5d7d5e80467807604244e7388427330f5c6d4cd61e6edaddc5773ccc393 - languageName: node - linkType: hard - -"rollup-plugin-babel@npm:^4.3.3": - version: 4.4.0 - resolution: "rollup-plugin-babel@npm:4.4.0" - dependencies: - "@babel/helper-module-imports": ^7.0.0 - rollup-pluginutils: ^2.8.1 - peerDependencies: - "@babel/core": 7 || ^7.0.0-rc.2 - rollup: ">=0.60.0 <3" - checksum: 5b8ed7c0a4192d7c74689074c910c1670eb07dfc875b1f4af5694a94c46bcb168ba85e2c9753030131efd6261ece7c252b9695953d0ea96d944977c6e79930d3 + rimraf: dist/esm/bin.mjs + checksum: 8ba5b84131c1344e9417cb7e8c05d8368bb73cbe5dd4c1d5eb49fc0b558209781658d18c450460e30607d0b7865bb067482839a2f343b186b07ae87715837e66 languageName: node linkType: hard -"rollup-plugin-terser@npm:^5.3.1": - version: 5.3.1 - resolution: "rollup-plugin-terser@npm:5.3.1" +"rollup-plugin-terser@npm:^7.0.0": + version: 7.0.2 + resolution: "rollup-plugin-terser@npm:7.0.2" dependencies: - "@babel/code-frame": ^7.5.5 - jest-worker: ^24.9.0 - rollup-pluginutils: ^2.8.2 + "@babel/code-frame": ^7.10.4 + jest-worker: ^26.2.1 serialize-javascript: ^4.0.0 - terser: ^4.6.2 + terser: ^5.0.0 peerDependencies: - rollup: ">=0.66.0 <3" - checksum: 50f9e8fa6737fa5e8aeca6a52b59ea3bc66faebe743bdfe9ce0484298cd1978082026721b182d79bcc88240429842dc58feae88d6c238b47cafc1684e0320a73 - languageName: node - linkType: hard - -"rollup-pluginutils@npm:^2.8.1, rollup-pluginutils@npm:^2.8.2": - version: 2.8.2 - resolution: "rollup-pluginutils@npm:2.8.2" - dependencies: - estree-walker: ^0.6.1 - checksum: 339fdf866d8f4ff6e408fa274c0525412f7edb01dc46b5ccda51f575b7e0d20ad72965773376fb5db95a77a7fcfcab97bf841ec08dbadf5d6b08af02b7a2cf5e + rollup: ^2.0.0 + checksum: af84bb7a7a894cd00852b6486528dfb8653cf94df4c126f95f389a346f401d054b08c46bee519a2ab6a22b33804d1d6ac6d8c90b1b2bf8fffb097eed73fc3c72 languageName: node linkType: hard -"rollup@npm:^1.31.1": - version: 1.32.1 - resolution: "rollup@npm:1.32.1" +"rollup@npm:^2.43.1": + version: 2.79.2 + resolution: "rollup@npm:2.79.2" dependencies: - "@types/estree": "*" - "@types/node": "*" - acorn: ^7.1.0 + fsevents: ~2.3.2 + dependenciesMeta: + fsevents: + optional: true bin: rollup: dist/bin/rollup - checksum: 3a02731c20c71321fae647c9c9cab0febee0580c6af029fdcd5dd6f424b8c85119d92c8554c6837327fd323c2458e92d955bbebc90ca6bed87cc626695e7c31f - languageName: node - linkType: hard - -"rollup@npm:^3.27.1": - version: 3.29.4 - resolution: "rollup@npm:3.29.4" - dependencies: + checksum: df7aa4c8b95245dede157b06ab71e1921de6080757d30e9bf31f8fb142064d12dda865e2bafbab4349588f43425b2965a290c9a5da1c048246a70fc21734ebd7 + languageName: node + linkType: hard + +"rollup@npm:^4.20.0, rollup@npm:^4.23.0, rollup@npm:^4.43.0": + version: 4.50.2 + resolution: "rollup@npm:4.50.2" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.50.2 + "@rollup/rollup-android-arm64": 4.50.2 + "@rollup/rollup-darwin-arm64": 4.50.2 + "@rollup/rollup-darwin-x64": 4.50.2 + "@rollup/rollup-freebsd-arm64": 4.50.2 + "@rollup/rollup-freebsd-x64": 4.50.2 + "@rollup/rollup-linux-arm-gnueabihf": 4.50.2 + "@rollup/rollup-linux-arm-musleabihf": 4.50.2 + "@rollup/rollup-linux-arm64-gnu": 4.50.2 + "@rollup/rollup-linux-arm64-musl": 4.50.2 + "@rollup/rollup-linux-loong64-gnu": 4.50.2 + "@rollup/rollup-linux-ppc64-gnu": 4.50.2 + "@rollup/rollup-linux-riscv64-gnu": 4.50.2 + "@rollup/rollup-linux-riscv64-musl": 4.50.2 + "@rollup/rollup-linux-s390x-gnu": 4.50.2 + "@rollup/rollup-linux-x64-gnu": 4.50.2 + "@rollup/rollup-linux-x64-musl": 4.50.2 + "@rollup/rollup-openharmony-arm64": 4.50.2 + "@rollup/rollup-win32-arm64-msvc": 4.50.2 + "@rollup/rollup-win32-ia32-msvc": 4.50.2 + "@rollup/rollup-win32-x64-msvc": 4.50.2 + "@types/estree": 1.0.8 fsevents: ~2.3.2 dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loong64-gnu": + optional: true + "@rollup/rollup-linux-ppc64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-openharmony-arm64": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true fsevents: optional: true bin: rollup: dist/bin/rollup - checksum: 8bb20a39c8d91130825159c3823eccf4dc2295c9a0a5c4ed851a5bf2167dbf24d9a29f23461a54c955e5506395e6cc188eafc8ab0e20399d7489fb33793b184e - languageName: node - linkType: hard - -"rsvp@npm:^4.8.4": - version: 4.8.5 - resolution: "rsvp@npm:4.8.5" - checksum: 2d8ef30d8febdf05bdf856ccca38001ae3647e41835ca196bc1225333f79b94ae44def733121ca549ccc36209c9b689f6586905e2a043873262609744da8efc1 + checksum: fbdd9b470585fe1add3ec35edb760de289fe4413c9eb4ba5321fcf38638669d7f0d44ee54f9c55cd81404c69caa2c4b0598d2b4715e0b138cdace65bbe9a207a languageName: node linkType: hard -"run-async@npm:^2.4.0": - version: 2.4.1 - resolution: "run-async@npm:2.4.1" - checksum: a2c88aa15df176f091a2878eb840e68d0bdee319d8d97bbb89112223259cebecb94bc0defd735662b83c2f7a30bed8cddb7d1674eb48ae7322dc602b22d03797 +"router@npm:^2.2.0": + version: 2.2.0 + resolution: "router@npm:2.2.0" + dependencies: + debug: ^4.4.0 + depd: ^2.0.0 + is-promise: ^4.0.0 + parseurl: ^1.3.3 + path-to-regexp: ^8.0.0 + checksum: 4c3bec8011ed10bb07d1ee860bc715f245fff0fdff991d8319741d2932d89c3fe0a56766b4fa78e95444bc323fd2538e09c8e43bfbd442c2a7fab67456df7fa5 languageName: node linkType: hard @@ -17626,76 +18853,60 @@ __metadata: languageName: node linkType: hard -"run-queue@npm:^1.0.0, run-queue@npm:^1.0.3": - version: 1.0.3 - resolution: "run-queue@npm:1.0.3" - dependencies: - aproba: ^1.1.1 - checksum: c4541e18b5e056af60f398f2f1b3d89aae5c093d1524bf817c5ee68bcfa4851ad9976f457a9aea135b1d0d72ee9a91c386e3d136bcd95b699c367cd09c70be53 - languageName: node - linkType: hard - -"rxjs@npm:^6.5.2": - version: 6.6.7 - resolution: "rxjs@npm:6.6.7" - dependencies: - tslib: ^1.9.0 - checksum: bc334edef1bb8bbf56590b0b25734ba0deaf8825b703256a93714308ea36dff8a11d25533671adf8e104e5e8f256aa6fdfe39b2e248cdbd7a5f90c260acbbd1b - languageName: node - linkType: hard - -"rxjs@npm:^7.5.5": - version: 7.8.1 - resolution: "rxjs@npm:7.8.1" - dependencies: - tslib: ^2.1.0 - checksum: de4b53db1063e618ec2eca0f7965d9137cabe98cf6be9272efe6c86b47c17b987383df8574861bcced18ebd590764125a901d5506082be84a8b8e364bf05f119 - languageName: node - linkType: hard - -"safe-array-concat@npm:^1.1.2": - version: 1.1.2 - resolution: "safe-array-concat@npm:1.1.2" +"rxjs@npm:7.8.2": + version: 7.8.2 + resolution: "rxjs@npm:7.8.2" dependencies: - call-bind: ^1.0.7 - get-intrinsic: ^1.2.4 - has-symbols: ^1.0.3 - isarray: ^2.0.5 - checksum: a3b259694754ddfb73ae0663829e396977b99ff21cbe8607f35a469655656da8e271753497e59da8a7575baa94d2e684bea3e10ddd74ba046c0c9b4418ffa0c4 + tslib: ^2.1.0 + checksum: 2f233d7c832a6c255dabe0759014d7d9b1c9f1cb2f2f0d59690fd11c883c9826ea35a51740c06ab45b6ade0d9087bde9192f165cba20b6730d344b831ef80744 languageName: node linkType: hard -"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": - version: 5.1.2 - resolution: "safe-buffer@npm:5.1.2" - checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c +"safe-array-concat@npm:^1.1.2, safe-array-concat@npm:^1.1.3": + version: 1.1.3 + resolution: "safe-array-concat@npm:1.1.3" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.2 + get-intrinsic: ^1.2.6 + has-symbols: ^1.1.0 + isarray: ^2.0.5 + checksum: 00f6a68140e67e813f3ad5e73e6dedcf3e42a9fa01f04d44b0d3f7b1f4b257af876832a9bfc82ac76f307e8a6cc652e3cf95876048a26cbec451847cf6ae3707 languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 languageName: node linkType: hard -"safe-regex-test@npm:^1.0.3": - version: 1.0.3 - resolution: "safe-regex-test@npm:1.0.3" +"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": + version: 5.1.2 + resolution: "safe-buffer@npm:5.1.2" + checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c + languageName: node + linkType: hard + +"safe-push-apply@npm:^1.0.0": + version: 1.0.0 + resolution: "safe-push-apply@npm:1.0.0" dependencies: - call-bind: ^1.0.6 es-errors: ^1.3.0 - is-regex: ^1.1.4 - checksum: 6c7d392ff1ae7a3ae85273450ed02d1d131f1d2c76e177d6b03eb88e6df8fa062639070e7d311802c1615f351f18dc58f9454501c58e28d5ffd9b8f502ba6489 + isarray: ^2.0.5 + checksum: 8c11cbee6dc8ff5cc0f3d95eef7052e43494591384015902e4292aef4ae9e539908288520ed97179cee17d6ffb450fe5f05a46ce7a1749685f7524fd568ab5db languageName: node linkType: hard -"safe-regex@npm:^1.1.0": +"safe-regex-test@npm:^1.0.3, safe-regex-test@npm:^1.1.0": version: 1.1.0 - resolution: "safe-regex@npm:1.1.0" + resolution: "safe-regex-test@npm:1.1.0" dependencies: - ret: ~0.1.10 - checksum: 9a8bba57c87a841f7997b3b951e8e403b1128c1a4fd1182f40cc1a20e2d490593d7c2a21030fadfea320c8e859219019e136f678c6689ed5960b391b822f01d5 + call-bound: ^1.0.2 + es-errors: ^1.3.0 + is-regex: ^1.2.1 + checksum: 3c809abeb81977c9ed6c869c83aca6873ea0f3ab0f806b8edbba5582d51713f8a6e9757d24d2b4b088f563801475ea946c8e77e7713e8c65cdd02305b6caedab languageName: node linkType: hard @@ -17706,46 +18917,25 @@ __metadata: languageName: node linkType: hard -"sane@npm:^4.0.3": - version: 4.1.0 - resolution: "sane@npm:4.1.0" - dependencies: - "@cnakazawa/watch": ^1.0.3 - anymatch: ^2.0.0 - capture-exit: ^2.0.0 - exec-sh: ^0.3.2 - execa: ^1.0.0 - fb-watchman: ^2.0.0 - micromatch: ^3.1.4 - minimist: ^1.1.1 - walker: ~1.0.5 - bin: - sane: ./src/cli.js - checksum: 97716502d456c0d38670a902a4ea943d196dcdf998d1e40532d8f3e24e25d7eddfd4c3579025a1eee8eac09a48dfd05fba61a2156c56704e7feaa450eb249f7c - languageName: node - linkType: hard - -"sanitize.css@npm:^10.0.0": - version: 10.0.0 - resolution: "sanitize.css@npm:10.0.0" - checksum: 99932e53e864b83562a421f57383c9747ab03c51872437eb56170639cd6c634a945517e25d1b7005d10c8dc863f71c61c573e3452474d4ef25bcf5f7344e4ce3 +"sanitize.css@npm:*": + version: 13.0.0 + resolution: "sanitize.css@npm:13.0.0" + checksum: a99ca77c4d135800a4a93c3555e5aa4a2eb040a833df716dbe9132e1f2086fbf9acdb8021a579f40dcf77166d2d50f3358b4b6121a247d26fed5a0e6f5af3bb7 languageName: node linkType: hard -"sass-loader@npm:^10.0.5": - version: 10.5.2 - resolution: "sass-loader@npm:10.5.2" +"sass-loader@npm:^12.3.0": + version: 12.6.0 + resolution: "sass-loader@npm:12.6.0" dependencies: klona: ^2.0.4 - loader-utils: ^2.0.0 neo-async: ^2.6.2 - schema-utils: ^3.0.0 - semver: ^7.3.2 peerDependencies: fibers: ">= 3.1.0" - node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 sass: ^1.3.0 - webpack: ^4.36.0 || ^5.0.0 + sass-embedded: "*" + webpack: ^5.0.0 peerDependenciesMeta: fibers: optional: true @@ -17753,20 +18943,26 @@ __metadata: optional: true sass: optional: true - checksum: 416909a9d685aafeb4342d91575439b293f4e1d6fdf7f8f970e4b3158af38e3e7379b87c0a82d7b7b32165b1f54bcd7eca3c132ad143405a5105ea4ba79cdac2 + sass-embedded: + optional: true + checksum: 5d73a428588150f704016aa27397941bb9246cecd2ee083b573e95d969fc080ac6a16f2fe1cc64aca08f6e70da6f3c586ee68f0efc9f527fecc360e5f1c299ec languageName: node linkType: hard "sass@npm:^1.54.0": - version: 1.75.0 - resolution: "sass@npm:1.75.0" + version: 1.92.1 + resolution: "sass@npm:1.92.1" dependencies: - chokidar: ">=3.0.0 <4.0.0" - immutable: ^4.0.0 + "@parcel/watcher": ^2.4.1 + chokidar: ^4.0.0 + immutable: ^5.0.2 source-map-js: ">=0.6.2 <2.0.0" + dependenciesMeta: + "@parcel/watcher": + optional: true bin: sass: sass.js - checksum: bfb9f5ddb6a2e1fe0c1ba6191cdb17afa7b40c1eb892c7152f6a29ff2b06dc7a510bdb648f8cca0179dcb3965920ebeb8894f0710b0b450a99db563831345033 + checksum: ec0d4da639874f0f849b766f51f3db1fdff703840e7066ca3dd097999179630707b357744d83dde54289c02bba2f1ef8b34bba460cf4f703874b7922a86e32df languageName: node linkType: hard @@ -17786,27 +18982,25 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.0": - version: 0.23.0 - resolution: "scheduler@npm:0.23.0" - dependencies: - loose-envify: ^1.1.0 - checksum: d79192eeaa12abef860c195ea45d37cbf2bbf5f66e3c4dcd16f54a7da53b17788a70d109ee3d3dde1a0fd50e6a8fc171f4300356c5aee4fc0171de526bf35f8a +"scheduler@npm:^0.25.0": + version: 0.25.0 + resolution: "scheduler@npm:0.25.0" + checksum: b7bb9fddbf743e521e9aaa5198a03ae823f5e104ebee0cb9ec625392bb7da0baa1c28ab29cee4b1e407a94e76acc6eee91eeb749614f91f853efda2613531566 languageName: node linkType: hard -"schema-utils@npm:^1.0.0": - version: 1.0.0 - resolution: "schema-utils@npm:1.0.0" +"schema-utils@npm:2.7.0": + version: 2.7.0 + resolution: "schema-utils@npm:2.7.0" dependencies: - ajv: ^6.1.0 - ajv-errors: ^1.0.0 - ajv-keywords: ^3.1.0 - checksum: e8273b4f6eff9ddf4a4f4c11daf7b96b900237bf8859c86fa1e9b4fab416b72d7ea92468f8db89c18a3499a1070206e1c8a750c83b42d5325fc659cbb55eee88 + "@types/json-schema": ^7.0.4 + ajv: ^6.12.2 + ajv-keywords: ^3.4.1 + checksum: 8889325b0ee1ae6a8f5d6aaa855c71e136ebbb7fd731b01a9d3ec8225dcb245f644c47c50104db4c741983b528cdff8558570021257d4d397ec6aaecd9172a8e languageName: node linkType: hard -"schema-utils@npm:^2.6.5, schema-utils@npm:^2.7.0, schema-utils@npm:^2.7.1": +"schema-utils@npm:^2.6.5": version: 2.7.1 resolution: "schema-utils@npm:2.7.1" dependencies: @@ -17817,7 +19011,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1": +"schema-utils@npm:^3.0.0": version: 3.3.0 resolution: "schema-utils@npm:3.3.0" dependencies: @@ -17828,6 +19022,18 @@ __metadata: languageName: node linkType: hard +"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.2": + version: 4.3.2 + resolution: "schema-utils@npm:4.3.2" + dependencies: + "@types/json-schema": ^7.0.9 + ajv: ^8.9.0 + ajv-formats: ^2.1.1 + ajv-keywords: ^5.1.0 + checksum: d798b341ffa1371f8471629e8861af3aa99e8e15b89da2c0db28c5a80a02ee8c6ffc7daefbe28a2b8c1bc8e3f3e02d028775145d7ab3d9d1a413a9651a835466 + languageName: node + linkType: hard + "select-hose@npm:^2.0.0": version: 2.0.0 resolution: "select-hose@npm:2.0.0" @@ -17835,16 +19041,17 @@ __metadata: languageName: node linkType: hard -"selfsigned@npm:^1.10.8": - version: 1.10.14 - resolution: "selfsigned@npm:1.10.14" +"selfsigned@npm:^2.1.1": + version: 2.4.1 + resolution: "selfsigned@npm:2.4.1" dependencies: - node-forge: ^0.10.0 - checksum: 616d131b18516ba2876398f0230987511d50a13816e0709b9f0d20246a524a2e83dfb27ea46ce2bfe331519583a156afa67bc3ece8bf0f9804aec06e2e8c7a21 + "@types/node-forge": ^1.3.0 + node-forge: ^1 + checksum: 38b91c56f1d7949c0b77f9bbe4545b19518475cae15e7d7f0043f87b1626710b011ce89879a88969651f650a19d213bb15b7d5b4c2877df9eeeff7ba8f8b9bfa languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.1": +"semver@npm:^5.6.0, semver@npm:^5.7.1": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -17853,32 +19060,21 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.3.2": - version: 7.3.2 - resolution: "semver@npm:7.3.2" - bin: - semver: bin/semver.js - checksum: 692f4900dadb43919614b0df9af23fe05743051cda0d1735b5e4d76f93c9e43a266fae73cfc928f5d1489f022c5c0e65dfd2900fcf5b1839c4e9a239729afa7b - languageName: node - linkType: hard - -"semver@npm:7.x, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3": - version: 7.6.0 - resolution: "semver@npm:7.6.0" - dependencies: - lru-cache: ^6.0.0 +"semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" bin: semver: bin/semver.js - checksum: 7427f05b70786c696640edc29fdd4bc33b2acf3bbe1740b955029044f80575fc664e1a512e4113c3af21e767154a94b4aa214bf6cd6e42a1f6dba5914e0b208c + checksum: ae47d06de28836adb9d3e25f22a92943477371292d9b665fb023fae278d345d508ca1958232af086d85e0155aee22e313e100971898bbb8d5d89b8b1d4054ca2 languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": - version: 6.3.1 - resolution: "semver@npm:6.3.1" +"semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": + version: 7.7.2 + resolution: "semver@npm:7.7.2" bin: semver: bin/semver.js - checksum: ae47d06de28836adb9d3e25f22a92943477371292d9b665fb023fae278d345d508ca1958232af086d85e0155aee22e313e100971898bbb8d5d89b8b1d4054ca2 + checksum: dd94ba8f1cbc903d8eeb4dd8bf19f46b3deb14262b6717d0de3c804b594058ae785ef2e4b46c5c3b58733c99c83339068203002f9e37cfe44f7e2cc5e3d2f621 languageName: node linkType: hard @@ -17891,9 +19087,9 @@ __metadata: languageName: node linkType: hard -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" +"send@npm:0.19.0": + version: 0.19.0 + resolution: "send@npm:0.19.0" dependencies: debug: 2.6.9 depd: 2.0.0 @@ -17908,7 +19104,26 @@ __metadata: on-finished: 2.4.1 range-parser: ~1.2.1 statuses: 2.0.1 - checksum: 74fc07ebb58566b87b078ec63e5a3e41ecd987e4272ba67b7467e86c6ad51bc6b0b0154133b6d8b08a2ddda360464f71382f7ef864700f34844a76c8027817a8 + checksum: 5ae11bd900c1c2575525e2aa622e856804e2f96a09281ec1e39610d089f53aa69e13fd8db84b52f001d0318cf4bb0b3b904ad532fc4c0014eb90d32db0cff55f + languageName: node + linkType: hard + +"send@npm:^1.1.0, send@npm:^1.2.0": + version: 1.2.0 + resolution: "send@npm:1.2.0" + dependencies: + debug: ^4.3.5 + encodeurl: ^2.0.0 + escape-html: ^1.0.3 + etag: ^1.8.1 + fresh: ^2.0.0 + http-errors: ^2.0.0 + mime-types: ^3.0.1 + ms: ^2.1.3 + on-finished: ^2.4.1 + range-parser: ^1.2.1 + statuses: ^2.0.1 + checksum: 7557ee6c1c257a1c53b402b4fba8ed88c95800b08abe085fc79e0824869274f213491be2efb2df3de228c70e4d40ce2019e5f77b58c42adb97149135420c3f34 languageName: node linkType: hard @@ -17932,12 +19147,12 @@ __metadata: languageName: node linkType: hard -"serialize-javascript@npm:^5.0.1": - version: 5.0.1 - resolution: "serialize-javascript@npm:5.0.1" +"serialize-javascript@npm:^6.0.0, serialize-javascript@npm:^6.0.2": + version: 6.0.2 + resolution: "serialize-javascript@npm:6.0.2" dependencies: randombytes: ^2.1.0 - checksum: bb45a427690c3d2711e28499de0fbf25036af1e23c63c6a9237ed0aa572fd0941fcdefe50a2dccf26d9df8c8b86ae38659e19d8ba7afd3fbc1f1c7539a2a48d2 + checksum: c4839c6206c1d143c0f80763997a361310305751171dd95e4b57efee69b8f6edd8960a0b7fbfc45042aadff98b206d55428aee0dc276efe54f100899c7fa8ab7 languageName: node linkType: hard @@ -17956,15 +19171,27 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.15.0": - version: 1.15.0 - resolution: "serve-static@npm:1.15.0" +"serve-static@npm:1.16.2": + version: 1.16.2 + resolution: "serve-static@npm:1.16.2" dependencies: - encodeurl: ~1.0.2 + encodeurl: ~2.0.0 escape-html: ~1.0.3 parseurl: ~1.3.3 - send: 0.18.0 - checksum: af57fc13be40d90a12562e98c0b7855cf6e8bd4c107fe9a45c212bf023058d54a1871b1c89511c3958f70626fff47faeb795f5d83f8cf88514dbaeb2b724464d + send: 0.19.0 + checksum: dffc52feb4cc5c68e66d0c7f3c1824d4e989f71050aefc9bd5f822a42c54c9b814f595fc5f2b717f4c7cc05396145f3e90422af31186a93f76cf15f707019759 + languageName: node + linkType: hard + +"serve-static@npm:^2.2.0": + version: 2.2.0 + resolution: "serve-static@npm:2.2.0" + dependencies: + encodeurl: ^2.0.0 + escape-html: ^1.0.3 + parseurl: ^1.3.3 + send: ^1.2.0 + checksum: 74f39e88f0444aa6732aae3b9597739c47552adecdc83fa32aa42555e76f1daad480d791af73894655c27a2d378275a461e691cead33fb35d8b976f1e2d24665 languageName: node linkType: hard @@ -17975,14 +19202,7 @@ __metadata: languageName: node linkType: hard -"set-cookie-parser@npm:^2.4.6": - version: 2.6.0 - resolution: "set-cookie-parser@npm:2.6.0" - checksum: bf11ebc594c53d84588f1b4c04f1b8ce14e0498b1c011b3d76b5c6d5aac481bbc3f7c5260ec4ce99bdc1d9aed19f9fc315e73166a36ca74d0f12349a73f6bdc9 - languageName: node - linkType: hard - -"set-function-length@npm:^1.2.1": +"set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" dependencies: @@ -17996,7 +19216,7 @@ __metadata: languageName: node linkType: hard -"set-function-name@npm:^2.0.1, set-function-name@npm:^2.0.2": +"set-function-name@npm:^2.0.2": version: 2.0.2 resolution: "set-function-name@npm:2.0.2" dependencies: @@ -18008,22 +19228,14 @@ __metadata: languageName: node linkType: hard -"set-value@npm:^2.0.0, set-value@npm:^2.0.1": - version: 2.0.1 - resolution: "set-value@npm:2.0.1" +"set-proto@npm:^1.0.0": + version: 1.0.0 + resolution: "set-proto@npm:1.0.0" dependencies: - extend-shallow: ^2.0.1 - is-extendable: ^0.1.1 - is-plain-object: ^2.0.3 - split-string: ^3.0.1 - checksum: 09a4bc72c94641aeae950eb60dc2755943b863780fcc32e441eda964b64df5e3f50603d5ebdd33394ede722528bd55ed43aae26e9df469b4d32e2292b427b601 - languageName: node - linkType: hard - -"setimmediate@npm:^1.0.4": - version: 1.0.5 - resolution: "setimmediate@npm:1.0.5" - checksum: c9a6f2c5b51a2dabdc0247db9c46460152ffc62ee139f3157440bd48e7c59425093f42719ac1d7931f054f153e2d26cf37dfeb8da17a794a58198a2705e527fd + dunder-proto: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + checksum: ec27cbbe334598547e99024403e96da32aca3e530583e4dba7f5db1c43cbc4affa9adfbd77c7b2c210b9b8b2e7b2e600bad2a6c44fd62e804d8233f96bbb62f4 languageName: node linkType: hard @@ -18041,18 +19253,6 @@ __metadata: languageName: node linkType: hard -"sha.js@npm:^2.4.0, sha.js@npm:^2.4.8": - version: 2.4.11 - resolution: "sha.js@npm:2.4.11" - dependencies: - inherits: ^2.0.1 - safe-buffer: ^5.0.1 - bin: - sha.js: ./bin.js - checksum: ebd3f59d4b799000699097dadb831c8e3da3eb579144fd7eb7a19484cbcbb7aca3c68ba2bb362242eb09e33217de3b4ea56e4678184c334323eca24a58e3ad07 - languageName: node - linkType: hard - "shared@1.0.0, shared@workspace:src/shared": version: 0.0.0-use.local resolution: "shared@workspace:src/shared" @@ -18063,15 +19263,6 @@ __metadata: languageName: unknown linkType: soft -"shebang-command@npm:^1.2.0": - version: 1.2.0 - resolution: "shebang-command@npm:1.2.0" - dependencies: - shebang-regex: ^1.0.0 - checksum: 9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 - languageName: node - linkType: hard - "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -18081,13 +19272,6 @@ __metadata: languageName: node linkType: hard -"shebang-regex@npm:^1.0.0": - version: 1.0.0 - resolution: "shebang-regex@npm:1.0.0" - checksum: 404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 - languageName: node - linkType: hard - "shebang-regex@npm:^3.0.0": version: 3.0.0 resolution: "shebang-regex@npm:3.0.0" @@ -18095,29 +19279,58 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:1.7.2": - version: 1.7.2 - resolution: "shell-quote@npm:1.7.2" - checksum: efad426fb25d8a54d06363f1f45774aa9e195f62f14fa696d542b44bfe418ab41206448b63af18d726c62e099e66d9a3f4f44858b9ea2ce4b794b41b802672d1 +"shell-quote@npm:1.8.3, shell-quote@npm:^1.7.3, shell-quote@npm:^1.8.3": + version: 1.8.3 + resolution: "shell-quote@npm:1.8.3" + checksum: 550dd84e677f8915eb013d43689c80bb114860649ec5298eb978f40b8f3d4bc4ccb072b82c094eb3548dc587144bb3965a8676f0d685c1cf4c40b5dc27166242 languageName: node linkType: hard -"shellwords@npm:^0.1.1": - version: 0.1.1 - resolution: "shellwords@npm:0.1.1" - checksum: 8d73a5e9861f5e5f1068e2cfc39bc0002400fe58558ab5e5fa75630d2c3adf44ca1fac81957609c8320d5533e093802fcafc72904bf1a32b95de3c19a0b1c0d4 +"side-channel-list@npm:^1.0.0": + version: 1.0.0 + resolution: "side-channel-list@npm:1.0.0" + dependencies: + es-errors: ^1.3.0 + object-inspect: ^1.13.3 + checksum: 603b928997abd21c5a5f02ae6b9cc36b72e3176ad6827fab0417ead74580cc4fb4d5c7d0a8a2ff4ead34d0f9e35701ed7a41853dac8a6d1a664fcce1a044f86f languageName: node linkType: hard -"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": - version: 1.0.6 - resolution: "side-channel@npm:1.0.6" +"side-channel-map@npm:^1.0.1": + version: 1.0.1 + resolution: "side-channel-map@npm:1.0.1" dependencies: - call-bind: ^1.0.7 + call-bound: ^1.0.2 es-errors: ^1.3.0 - get-intrinsic: ^1.2.4 - object-inspect: ^1.13.1 - checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97 + get-intrinsic: ^1.2.5 + object-inspect: ^1.13.3 + checksum: 42501371cdf71f4ccbbc9c9e2eb00aaaab80a4c1c429d5e8da713fd4d39ef3b8d4a4b37ed4f275798a65260a551a7131fd87fe67e922dba4ac18586d6aab8b06 + languageName: node + linkType: hard + +"side-channel-weakmap@npm:^1.0.2": + version: 1.0.2 + resolution: "side-channel-weakmap@npm:1.0.2" + dependencies: + call-bound: ^1.0.2 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.5 + object-inspect: ^1.13.3 + side-channel-map: ^1.0.1 + checksum: a815c89bc78c5723c714ea1a77c938377ea710af20d4fb886d362b0d1f8ac73a17816a5f6640f354017d7e292a43da9c5e876c22145bac00b76cfb3468001736 + languageName: node + linkType: hard + +"side-channel@npm:^1.0.6, side-channel@npm:^1.1.0": + version: 1.1.0 + resolution: "side-channel@npm:1.1.0" + dependencies: + es-errors: ^1.3.0 + object-inspect: ^1.13.3 + side-channel-list: ^1.0.0 + side-channel-map: ^1.0.1 + side-channel-weakmap: ^1.0.2 + checksum: bf73d6d6682034603eb8e99c63b50155017ed78a522d27c2acec0388a792c3ede3238b878b953a08157093b85d05797217d270b7666ba1f111345fbe933380ff languageName: node linkType: hard @@ -18128,26 +19341,35 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2": +"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 languageName: node linkType: hard -"signal-exit@npm:^4.0.1": +"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" checksum: 64c757b498cb8629ffa5f75485340594d2f8189e9b08700e69199069c8e3070fb3e255f7ab873c05dc0b3cec412aea7402e10a5990cb6a050bd33ba062a6c549 languageName: node linkType: hard -"simple-swizzle@npm:^0.2.2": - version: 0.2.2 - resolution: "simple-swizzle@npm:0.2.2" +"simple-concat@npm:^1.0.0": + version: 1.0.1 + resolution: "simple-concat@npm:1.0.1" + checksum: 4d211042cc3d73a718c21ac6c4e7d7a0363e184be6a5ad25c8a1502e49df6d0a0253979e3d50dbdd3f60ef6c6c58d756b5d66ac1e05cda9cacd2e9fc59e3876a + languageName: node + linkType: hard + +"simple-get@npm:^4.0.0": + version: 4.0.1 + resolution: "simple-get@npm:4.0.1" dependencies: - is-arrayish: ^0.3.1 - checksum: a7f3f2ab5c76c4472d5c578df892e857323e452d9f392e1b5cf74b74db66e6294a1e1b8b390b519fa1b96b5b613f2a37db6cffef52c3f1f8f3c5ea64eb2d54c0 + decompress-response: ^6.0.0 + once: ^1.3.1 + simple-concat: ^1.0.0 + checksum: e4132fd27cf7af230d853fa45c1b8ce900cb430dd0a3c6d3829649fe4f2b26574c803698076c4006450efb0fad2ba8c5455fbb5755d4b0a5ec42d4f12b31d27e languageName: node linkType: hard @@ -18174,6 +19396,13 @@ __metadata: languageName: node linkType: hard +"slash@npm:^4.0.0": + version: 4.0.0 + resolution: "slash@npm:4.0.0" + checksum: da8e4af73712253acd21b7853b7e0dbba776b786e82b010a5bfc8b5051a1db38ed8aba8e1e8f400dd2c9f373be91eb1c42b66e91abb407ff42b10feece5e1d2d + languageName: node + linkType: hard + "slice-ansi@npm:^4.0.0": version: 4.0.0 resolution: "slice-ansi@npm:4.0.0" @@ -18202,56 +19431,7 @@ __metadata: languageName: node linkType: hard -"snapdragon-node@npm:^2.0.1": - version: 2.1.1 - resolution: "snapdragon-node@npm:2.1.1" - dependencies: - define-property: ^1.0.0 - isobject: ^3.0.0 - snapdragon-util: ^3.0.1 - checksum: 9bb57d759f9e2a27935dbab0e4a790137adebace832b393e350a8bf5db461ee9206bb642d4fe47568ee0b44080479c8b4a9ad0ebe3712422d77edf9992a672fd - languageName: node - linkType: hard - -"snapdragon-util@npm:^3.0.1": - version: 3.0.1 - resolution: "snapdragon-util@npm:3.0.1" - dependencies: - kind-of: ^3.2.0 - checksum: 684997dbe37ec995c03fd3f412fba2b711fc34cb4010452b7eb668be72e8811a86a12938b511e8b19baf853b325178c56d8b78d655305e5cfb0bb8b21677e7b7 - languageName: node - linkType: hard - -"snapdragon@npm:^0.8.1": - version: 0.8.2 - resolution: "snapdragon@npm:0.8.2" - dependencies: - base: ^0.11.1 - debug: ^2.2.0 - define-property: ^0.2.5 - extend-shallow: ^2.0.1 - map-cache: ^0.2.2 - source-map: ^0.5.6 - source-map-resolve: ^0.5.0 - use: ^3.1.0 - checksum: a197f242a8f48b11036563065b2487e9b7068f50a20dd81d9161eca6af422174fc158b8beeadbe59ce5ef172aa5718143312b3aebaae551c124b7824387c8312 - languageName: node - linkType: hard - -"sockjs-client@npm:^1.5.0": - version: 1.6.1 - resolution: "sockjs-client@npm:1.6.1" - dependencies: - debug: ^3.2.7 - eventsource: ^2.0.2 - faye-websocket: ^0.11.4 - inherits: ^2.0.4 - url-parse: ^1.5.10 - checksum: c7623bbc9891f427c1670145550a1c9c2d5379719e174a791606ba4f12c7d92e4cfb9acec6c17f91fda45d910b23c308a1f9fbcad4916ce5db4e982b24079fc7 - languageName: node - linkType: hard - -"sockjs@npm:^0.3.21": +"sockjs@npm:^0.3.24": version: 0.3.24 resolution: "sockjs@npm:0.3.24" dependencies: @@ -18263,63 +19443,54 @@ __metadata: linkType: hard "socks-proxy-agent@npm:^8.0.3": - version: 8.0.3 - resolution: "socks-proxy-agent@npm:8.0.3" + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" dependencies: - agent-base: ^7.1.1 + agent-base: ^7.1.2 debug: ^4.3.4 - socks: ^2.7.1 - checksum: 8fab38821c327c190c28f1658087bc520eb065d55bc07b4a0fdf8d1e0e7ad5d115abbb22a95f94f944723ea969dd771ad6416b1e3cde9060c4c71f705c8b85c5 + socks: ^2.8.3 + checksum: b4fbcdb7ad2d6eec445926e255a1fb95c975db0020543fbac8dfa6c47aecc6b3b619b7fb9c60a3f82c9b2969912a5e7e174a056ae4d98cb5322f3524d6036e1d languageName: node linkType: hard -"socks@npm:^2.7.1": - version: 2.8.3 - resolution: "socks@npm:2.8.3" +"socks@npm:^2.8.3": + version: 2.8.7 + resolution: "socks@npm:2.8.7" dependencies: - ip-address: ^9.0.5 + ip-address: ^10.0.1 smart-buffer: ^4.2.0 - checksum: 7a6b7f6eedf7482b9e4597d9a20e09505824208006ea8f2c49b71657427f3c137ca2ae662089baa73e1971c62322d535d9d0cf1c9235cf6f55e315c18203eadd + checksum: 4bbe2c88cf0eeaf49f94b7f11564a99b2571bde6fd1e714ff95b38f89e1f97858c19e0ab0e6d39eb7f6a984fa67366825895383ed563fe59962a1d57a1d55318 languageName: node linkType: hard -"sort-keys@npm:^1.0.0": - version: 1.1.2 - resolution: "sort-keys@npm:1.1.2" - dependencies: - is-plain-obj: ^1.0.0 - checksum: 5963fd191a2a185a5ec86f06e47721e8e04713eda43bb04ae60d2a8afb21241553dd5bc9d863ed2bd7c3d541b609b0c8d0e58836b1a3eb6764c09c094bcc8b00 - languageName: node - linkType: hard - -"source-list-map@npm:^2.0.0": +"source-list-map@npm:^2.0.0, source-list-map@npm:^2.0.1": version: 2.0.1 resolution: "source-list-map@npm:2.0.1" checksum: 806efc6f75e7cd31e4815e7a3aaf75a45c704871ea4075cb2eb49882c6fca28998f44fc5ac91adb6de03b2882ee6fb02f951fdc85e6a22b338c32bfe19557938 languageName: node linkType: hard -"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.2.0": - version: 1.2.0 - resolution: "source-map-js@npm:1.2.0" - checksum: 791a43306d9223792e84293b00458bf102a8946e7188f3db0e4e22d8d530b5f80a4ce468eb5ec0bf585443ad55ebbd630bf379c98db0b1f317fd902500217f97 +"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 4eb0cd997cdf228bc253bcaff9340afeb706176e64868ecd20efbe6efea931465f43955612346d6b7318789e5265bdc419bc7669c1cebe3db0eb255f57efa76b languageName: node linkType: hard -"source-map-resolve@npm:^0.5.0, source-map-resolve@npm:^0.5.2": - version: 0.5.3 - resolution: "source-map-resolve@npm:0.5.3" +"source-map-loader@npm:^3.0.0": + version: 3.0.2 + resolution: "source-map-loader@npm:3.0.2" dependencies: - atob: ^2.1.2 - decode-uri-component: ^0.2.0 - resolve-url: ^0.2.1 - source-map-url: ^0.4.0 - urix: ^0.1.0 - checksum: c73fa44ac00783f025f6ad9e038ab1a2e007cd6a6b86f47fe717c3d0765b4a08d264f6966f3bd7cd9dbcd69e4832783d5472e43247775b2a550d6f2155d24bae + abab: ^2.0.5 + iconv-lite: ^0.6.3 + source-map-js: ^1.0.1 + peerDependencies: + webpack: ^5.0.0 + checksum: d5a4e2ab190c93ae5cba68c247fbaa9fd560333c91060602b634c399a8a4b3205b8c07714c3bcdb0a11c6cc5476c06256bd8e824e71fbbb7981e8fad5cba4a00 languageName: node linkType: hard -"source-map-support@npm:^0.5.17, source-map-support@npm:^0.5.6, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.20": +"source-map-support@npm:^0.5.17, source-map-support@npm:^0.5.6, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -18329,13 +19500,6 @@ __metadata: languageName: node linkType: hard -"source-map-url@npm:^0.4.0": - version: 0.4.1 - resolution: "source-map-url@npm:0.4.1" - checksum: 64c5c2c77aff815a6e61a4120c309ae4cac01298d9bcbb3deb1b46a4dd4c46d4a1eaeda79ec9f684766ae80e8dc86367b89326ce9dd2b89947bd9291fc1ac08c - languageName: node - linkType: hard - "source-map@npm:0.6.1, source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" @@ -18343,7 +19507,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.0, source-map@npm:^0.5.6, source-map@npm:^0.5.7": +"source-map@npm:^0.5.7": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 5dc2043b93d2f194142c7f38f74a24670cd7a0063acdaf4bf01d2964b402257ae843c2a8fa822ad5b71013b5fcafa55af7421383da919752f22ff488bc553f4d @@ -18351,64 +19515,32 @@ __metadata: linkType: hard "source-map@npm:^0.7.3": - version: 0.7.4 - resolution: "source-map@npm:0.7.4" - checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5 - languageName: node - linkType: hard - -"sourcemap-codec@npm:^1.4.8": - version: 1.4.8 - resolution: "sourcemap-codec@npm:1.4.8" - checksum: b57981c05611afef31605732b598ccf65124a9fcb03b833532659ac4d29ac0f7bfacbc0d6c5a28a03e84c7510e7e556d758d0bb57786e214660016fb94279316 - languageName: node - linkType: hard - -"space-separated-tokens@npm:^1.1.0": - version: 1.1.5 - resolution: "space-separated-tokens@npm:1.1.5" - checksum: 8ef68f1cfa8ccad316b7f8d0df0919d0f1f6d32101e8faeee34ea3a923ce8509c1ad562f57388585ee4951e92d27afa211ed0a077d3d5995b5ba9180331be708 - languageName: node - linkType: hard - -"spawn-command@npm:^0.0.2-1": - version: 0.0.2 - resolution: "spawn-command@npm:0.0.2" - checksum: e35c5d28177b4d461d33c88cc11f6f3a5079e2b132c11e1746453bbb7a0c0b8a634f07541a2a234fa4758239d88203b758def509161b651e81958894c0b4b64b + version: 0.7.6 + resolution: "source-map@npm:0.7.6" + checksum: 932f4a2390aa7100e91357d88cc272de984ad29139ac09eedfde8cc78d46da35f389065d0c5343c5d71d054a6ebd4939a8c0f2c98d5df64fe97bb8a730596c2d languageName: node linkType: hard -"spdx-correct@npm:^3.0.0": - version: 3.2.0 - resolution: "spdx-correct@npm:3.2.0" +"source-map@npm:^0.8.0-beta.0": + version: 0.8.0-beta.0 + resolution: "source-map@npm:0.8.0-beta.0" dependencies: - spdx-expression-parse: ^3.0.0 - spdx-license-ids: ^3.0.0 - checksum: e9ae98d22f69c88e7aff5b8778dc01c361ef635580e82d29e5c60a6533cc8f4d820803e67d7432581af0cc4fb49973125076ee3b90df191d153e223c004193b2 + whatwg-url: ^7.0.0 + checksum: e94169be6461ab0ac0913313ad1719a14c60d402bd22b0ad96f4a6cffd79130d91ab5df0a5336a326b04d2df131c1409f563c9dc0d21a6ca6239a44b6c8dbd92 languageName: node linkType: hard -"spdx-exceptions@npm:^2.1.0": - version: 2.5.0 - resolution: "spdx-exceptions@npm:2.5.0" - checksum: bb127d6e2532de65b912f7c99fc66097cdea7d64c10d3ec9b5e96524dbbd7d20e01cba818a6ddb2ae75e62bb0c63d5e277a7e555a85cbc8ab40044984fa4ae15 - languageName: node - linkType: hard - -"spdx-expression-parse@npm:^3.0.0": - version: 3.0.1 - resolution: "spdx-expression-parse@npm:3.0.1" - dependencies: - spdx-exceptions: ^2.1.0 - spdx-license-ids: ^3.0.0 - checksum: a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde +"sourcemap-codec@npm:^1.4.8": + version: 1.4.8 + resolution: "sourcemap-codec@npm:1.4.8" + checksum: b57981c05611afef31605732b598ccf65124a9fcb03b833532659ac4d29ac0f7bfacbc0d6c5a28a03e84c7510e7e556d758d0bb57786e214660016fb94279316 languageName: node linkType: hard -"spdx-license-ids@npm:^3.0.0": - version: 3.0.17 - resolution: "spdx-license-ids@npm:3.0.17" - checksum: 0aba5d16292ff604dd20982200e23b4d425f6ba364765039bdbde2f6c956b9909fce1ad040a897916a5f87388e85e001f90cb64bf706b6e319f3908cfc445a59 +"space-separated-tokens@npm:^2.0.0": + version: 2.0.2 + resolution: "space-separated-tokens@npm:2.0.2" + checksum: 202e97d7ca1ba0758a0aa4fe226ff98142073bcceeff2da3aad037968878552c3bbce3b3231970025375bbba5aee00c5b8206eda408da837ab2dc9c0f26be990 languageName: node linkType: hard @@ -18439,22 +19571,6 @@ __metadata: languageName: node linkType: hard -"split-string@npm:^3.0.1, split-string@npm:^3.0.2": - version: 3.1.0 - resolution: "split-string@npm:3.1.0" - dependencies: - extend-shallow: ^3.0.0 - checksum: ae5af5c91bdc3633628821bde92fdf9492fa0e8a63cf6a0376ed6afde93c701422a1610916f59be61972717070119e848d10dfbbd5024b7729d6a71972d2a84c - languageName: node - linkType: hard - -"sprintf-js@npm:^1.1.3": - version: 1.1.3 - resolution: "sprintf-js@npm:1.1.3" - checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 - languageName: node - linkType: hard - "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -18462,30 +19578,12 @@ __metadata: languageName: node linkType: hard -"ssri@npm:^10.0.0": - version: 10.0.5 - resolution: "ssri@npm:10.0.5" +"ssri@npm:^12.0.0": + version: 12.0.0 + resolution: "ssri@npm:12.0.0" dependencies: minipass: ^7.0.3 - checksum: 0a31b65f21872dea1ed3f7c200d7bc1c1b91c15e419deca14f282508ba917cbb342c08a6814c7f68ca4ca4116dd1a85da2bbf39227480e50125a1ceffeecb750 - languageName: node - linkType: hard - -"ssri@npm:^6.0.1": - version: 6.0.2 - resolution: "ssri@npm:6.0.2" - dependencies: - figgy-pudding: ^3.5.1 - checksum: 7c2e5d442f6252559c8987b7114bcf389fe5614bf65de09ba3e6f9a57b9b65b2967de348fcc3acccff9c069adb168140dd2c5fc2f6f4a779e604a27ef1f7d551 - languageName: node - linkType: hard - -"ssri@npm:^8.0.1": - version: 8.0.1 - resolution: "ssri@npm:8.0.1" - dependencies: - minipass: ^3.1.1 - checksum: bc447f5af814fa9713aa201ec2522208ae0f4d8f3bda7a1f445a797c7b929a02720436ff7c478fb5edc4045adb02b1b88d2341b436a80798734e2494f1067b36 + checksum: ef4b6b0ae47b4a69896f5f1c4375f953b9435388c053c36d27998bc3d73e046969ccde61ab659e679142971a0b08e50478a1228f62edb994105b280f17900c98 languageName: node linkType: hard @@ -18496,7 +19594,7 @@ __metadata: languageName: node linkType: hard -"stack-utils@npm:^2.0.2, stack-utils@npm:^2.0.3": +"stack-utils@npm:^2.0.3": version: 2.0.6 resolution: "stack-utils@npm:2.0.6" dependencies: @@ -18528,17 +19626,7 @@ __metadata: languageName: node linkType: hard -"static-extend@npm:^0.1.1": - version: 0.1.2 - resolution: "static-extend@npm:0.1.2" - dependencies: - define-property: ^0.2.5 - object-copy: ^0.1.0 - checksum: 8657485b831f79e388a437260baf22784540417a9b29e11572c87735df24c22b84eda42107403a64b30861b2faf13df9f7fc5525d51f9d1d2303aba5cbf4e12c - languageName: node - linkType: hard - -"statuses@npm:2.0.1, statuses@npm:^2.0.0": +"statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" checksum: 18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb @@ -18552,59 +19640,27 @@ __metadata: languageName: node linkType: hard -"std-env@npm:^3.3.3": - version: 3.7.0 - resolution: "std-env@npm:3.7.0" - checksum: 4f489d13ff2ab838c9acd4ed6b786b51aa52ecacdfeaefe9275fcb220ff2ac80c6e95674723508fd29850a694569563a8caaaea738eb82ca16429b3a0b50e510 - languageName: node - linkType: hard - -"stop-iteration-iterator@npm:^1.0.0": - version: 1.0.0 - resolution: "stop-iteration-iterator@npm:1.0.0" - dependencies: - internal-slot: ^1.0.4 - checksum: d04173690b2efa40e24ab70e5e51a3ff31d56d699550cfad084104ab3381390daccb36652b25755e420245f3b0737de66c1879eaa2a8d4fc0a78f9bf892fcb42 - languageName: node - linkType: hard - -"stream-browserify@npm:^2.0.1": +"statuses@npm:^2.0.1": version: 2.0.2 - resolution: "stream-browserify@npm:2.0.2" - dependencies: - inherits: ~2.0.1 - readable-stream: ^2.0.2 - checksum: 8de7bcab5582e9a931ae1a4768be7efe8fa4b0b95fd368d16d8cf3e494b897d6b0a7238626de5d71686e53bddf417fd59d106cfa3af0ec055f61a8d1f8fc77b3 + resolution: "statuses@npm:2.0.2" + checksum: 6927feb50c2a75b2a4caab2c565491f7a93ad3d8dbad7b1398d52359e9243a20e2ebe35e33726dee945125ef7a515e9097d8a1b910ba2bbd818265a2f6c39879 languageName: node linkType: hard -"stream-each@npm:^1.1.0": - version: 1.2.3 - resolution: "stream-each@npm:1.2.3" - dependencies: - end-of-stream: ^1.1.0 - stream-shift: ^1.0.0 - checksum: f243de78e9fcc60757994efc4e8ecae9f01a4b2c6a505d786b11fcaa68b1a75ca54afc1669eac9e08f19ff0230792fc40d0f3e3e2935d76971b4903af18b76ab +"std-env@npm:^3.8.0, std-env@npm:^3.9.0": + version: 3.9.0 + resolution: "std-env@npm:3.9.0" + checksum: d40126e4a650f6e5456711e6c297420352a376ef99a9599e8224d2d8f2ff2b91a954f3264fcef888d94fce5c9ae14992c5569761c95556fc87248ce4602ed212 languageName: node linkType: hard -"stream-http@npm:^2.7.2": - version: 2.8.3 - resolution: "stream-http@npm:2.8.3" +"stop-iteration-iterator@npm:^1.1.0": + version: 1.1.0 + resolution: "stop-iteration-iterator@npm:1.1.0" dependencies: - builtin-status-codes: ^3.0.0 - inherits: ^2.0.1 - readable-stream: ^2.3.6 - to-arraybuffer: ^1.0.0 - xtend: ^4.0.0 - checksum: f57dfaa21a015f72e6ce6b199cf1762074cfe8acf0047bba8f005593754f1743ad0a91788f95308d9f3829ad55742399ad27b4624432f2752a08e62ef4346e05 - languageName: node - linkType: hard - -"stream-shift@npm:^1.0.0": - version: 1.0.3 - resolution: "stream-shift@npm:1.0.3" - checksum: a24c0a3f66a8f9024bd1d579a533a53be283b4475d4e6b4b3211b964031447bdf6532dd1f3c2b0ad66752554391b7c62bd7ca4559193381f766534e723d50242 + es-errors: ^1.3.0 + internal-slot: ^1.1.0 + checksum: be944489d8829fb3bdec1a1cc4a2142c6b6eb317305eeace1ece978d286d6997778afa1ae8cb3bd70e2b274b9aa8c69f93febb1e15b94b1359b11058f9d3c3a1 languageName: node linkType: hard @@ -18615,19 +19671,17 @@ __metadata: languageName: node linkType: hard -"strict-event-emitter@npm:^0.2.0, strict-event-emitter@npm:^0.2.4": - version: 0.2.8 - resolution: "strict-event-emitter@npm:0.2.8" - dependencies: - events: ^3.3.0 - checksum: 6ac06fe72a6ee6ae64d20f1dd42838ea67342f1b5f32b03b3050d73ee6ecee44b4d5c4ed2965a7154b47991e215f373d4e789e2b2be2769cd80e356126c2ca53 +"strict-event-emitter@npm:^0.5.1": + version: 0.5.1 + resolution: "strict-event-emitter@npm:0.5.1" + checksum: 350480431bc1c28fdb601ef4976c2f8155fc364b4740f9692dd03e5bdd48aafc99a5e021fe655fbd986d0b803e9f3fc5c4b018b35cb838c4690d60f2a26f1cf3 languageName: node linkType: hard -"strict-uri-encode@npm:^1.0.0": - version: 1.1.0 - resolution: "strict-uri-encode@npm:1.1.0" - checksum: 9466d371f7b36768d43f7803f26137657559e4c8b0161fb9e320efb8edba3ae22f8e99d4b0d91da023b05a13f62ec5412c3f4f764b5788fac11d1fea93720bb3 +"string-hash@npm:^1.1.3": + version: 1.1.3 + resolution: "string-hash@npm:1.1.3" + checksum: 104b8667a5e0dc71bfcd29fee09cb88c6102e27bfb07c55f95535d90587d016731d52299380052e514266f4028a7a5172e0d9ac58e2f8f5001be61dc77c0754d languageName: node linkType: hard @@ -18641,6 +19695,16 @@ __metadata: languageName: node linkType: hard +"string-length@npm:^5.0.1": + version: 5.0.1 + resolution: "string-length@npm:5.0.1" + dependencies: + char-regex: ^2.0.0 + strip-ansi: ^7.0.1 + checksum: 71f73b8c8a743e01dcd001bcf1b197db78d5e5e53b12bd898cddaf0961be09f947dfd8c429783db3694b55b05cb5a51de6406c5085ff1aaa10c4771440c8396d + languageName: node + linkType: hard + "string-natural-compare@npm:^3.0.1": version: 3.0.1 resolution: "string-natural-compare@npm:3.0.1" @@ -18654,19 +19718,8 @@ __metadata: dependencies: emoji-regex: ^8.0.0 is-fullwidth-code-point: ^3.0.0 - strip-ansi: ^6.0.1 - checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb - languageName: node - linkType: hard - -"string-width@npm:^3.0.0, string-width@npm:^3.1.0": - version: 3.1.0 - resolution: "string-width@npm:3.1.0" - dependencies: - emoji-regex: ^7.0.1 - is-fullwidth-code-point: ^2.0.0 - strip-ansi: ^5.1.0 - checksum: 57f7ca73d201682816d573dc68bd4bb8e1dff8dc9fcf10470fdfc3474135c97175fec12ea6a159e67339b41e86963112355b64529489af6e7e70f94a7caf08b2 + strip-ansi: ^6.0.1 + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb languageName: node linkType: hard @@ -18681,46 +19734,72 @@ __metadata: languageName: node linkType: hard -"string.prototype.matchall@npm:^4.0.10": - version: 4.0.11 - resolution: "string.prototype.matchall@npm:4.0.11" +"string.prototype.includes@npm:^2.0.1": + version: 2.0.1 + resolution: "string.prototype.includes@npm:2.0.1" dependencies: call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.23.2 + es-abstract: ^1.23.3 + checksum: ed4b7058b092f30d41c4df1e3e805eeea92479d2c7a886aa30f42ae32fde8924a10cc99cccc99c29b8e18c48216608a0fe6bf887f8b4aadf9559096a758f313a + languageName: node + linkType: hard + +"string.prototype.matchall@npm:^4.0.12, string.prototype.matchall@npm:^4.0.6": + version: 4.0.12 + resolution: "string.prototype.matchall@npm:4.0.12" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + es-abstract: ^1.23.6 es-errors: ^1.3.0 es-object-atoms: ^1.0.0 - get-intrinsic: ^1.2.4 - gopd: ^1.0.1 - has-symbols: ^1.0.3 - internal-slot: ^1.0.7 - regexp.prototype.flags: ^1.5.2 + get-intrinsic: ^1.2.6 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + internal-slot: ^1.1.0 + regexp.prototype.flags: ^1.5.3 set-function-name: ^2.0.2 - side-channel: ^1.0.6 - checksum: 6ac6566ed065c0c8489c91156078ca077db8ff64d683fda97ae652d00c52dfa5f39aaab0a710d8243031a857fd2c7c511e38b45524796764d25472d10d7075ae + side-channel: ^1.1.0 + checksum: 98a09d6af91bfc6ee25556f3d7cd6646d02f5f08bda55d45528ed273d266d55a71af7291fe3fc76854deffb9168cc1a917d0b07a7d5a178c7e9537c99e6d2b57 languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.9": - version: 1.2.9 - resolution: "string.prototype.trim@npm:1.2.9" +"string.prototype.repeat@npm:^1.0.0": + version: 1.0.0 + resolution: "string.prototype.repeat@npm:1.0.0" dependencies: - call-bind: ^1.0.7 + define-properties: ^1.1.3 + es-abstract: ^1.17.5 + checksum: 95dfc514ed7f328d80a066dabbfbbb1615c3e51490351085409db2eb7cbfed7ea29fdadaf277647fbf9f4a1e10e6dd9e95e78c0fd2c4e6bb6723ea6e59401004 + languageName: node + linkType: hard + +"string.prototype.trim@npm:^1.2.10": + version: 1.2.10 + resolution: "string.prototype.trim@npm:1.2.10" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.2 + define-data-property: ^1.1.4 define-properties: ^1.2.1 - es-abstract: ^1.23.0 + es-abstract: ^1.23.5 es-object-atoms: ^1.0.0 - checksum: ea2df6ec1e914c9d4e2dc856fa08228e8b1be59b59e50b17578c94a66a176888f417264bb763d4aac638ad3b3dad56e7a03d9317086a178078d131aa293ba193 + has-property-descriptors: ^1.0.2 + checksum: 87659cd8561237b6c69f5376328fda934693aedde17bb7a2c57008e9d9ff992d0c253a391c7d8d50114e0e49ff7daf86a362f7961cf92f7564cd01342ca2e385 languageName: node linkType: hard -"string.prototype.trimend@npm:^1.0.8": - version: 1.0.8 - resolution: "string.prototype.trimend@npm:1.0.8" +"string.prototype.trimend@npm:^1.0.9": + version: 1.0.9 + resolution: "string.prototype.trimend@npm:1.0.9" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.2 define-properties: ^1.2.1 es-object-atoms: ^1.0.0 - checksum: cc3bd2de08d8968a28787deba9a3cb3f17ca5f9f770c91e7e8fa3e7d47f079bad70fadce16f05dda9f261788be2c6e84a942f618c3bed31e42abc5c1084f8dfd + checksum: cb86f639f41d791a43627784be2175daa9ca3259c7cb83e7a207a729909b74f2ea0ec5d85de5761e6835e5f443e9420c6ff3f63a845378e4a61dd793177bc287 languageName: node linkType: hard @@ -18735,7 +19814,7 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:^1.0.0, string_decoder@npm:^1.1.1": +"string_decoder@npm:^1.1.1": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" dependencies: @@ -18753,6 +19832,16 @@ __metadata: languageName: node linkType: hard +"stringify-entities@npm:^4.0.0": + version: 4.0.4 + resolution: "stringify-entities@npm:4.0.4" + dependencies: + character-entities-html4: ^2.0.0 + character-entities-legacy: ^3.0.0 + checksum: ac1344ef211eacf6cf0a0a8feaf96f9c36083835b406560d2c6ff5a87406a41b13f2f0b4c570a3b391f465121c4fd6822b863ffb197e8c0601a64097862cc5b5 + languageName: node + linkType: hard + "stringify-object@npm:^3.3.0": version: 3.3.0 resolution: "stringify-object@npm:3.3.0" @@ -18773,39 +19862,12 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:6.0.0": - version: 6.0.0 - resolution: "strip-ansi@npm:6.0.0" - dependencies: - ansi-regex: ^5.0.0 - checksum: 04c3239ede44c4d195b0e66c0ad58b932f08bec7d05290416d361ff908ad282ecdaf5d9731e322c84f151d427436bde01f05b7422c3ec26dd927586736b0e5d0 - languageName: node - linkType: hard - -"strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1": - version: 3.0.1 - resolution: "strip-ansi@npm:3.0.1" - dependencies: - ansi-regex: ^2.0.0 - checksum: 9b974de611ce5075c70629c00fa98c46144043db92ae17748fb780f706f7a789e9989fd10597b7c2053ae8d1513fd707816a91f1879b2f71e6ac0b6a863db465 - languageName: node - linkType: hard - -"strip-ansi@npm:^5.0.0, strip-ansi@npm:^5.1.0, strip-ansi@npm:^5.2.0": - version: 5.2.0 - resolution: "strip-ansi@npm:5.2.0" - dependencies: - ansi-regex: ^4.1.0 - checksum: bdb5f76ade97062bd88e7723aa019adbfacdcba42223b19ccb528ffb9fb0b89a5be442c663c4a3fb25268eaa3f6ea19c7c3fbae830bd1562d55adccae1fcec46 - languageName: node - linkType: hard - "strip-ansi@npm:^7.0.1": - version: 7.1.0 - resolution: "strip-ansi@npm:7.1.0" + version: 7.1.2 + resolution: "strip-ansi@npm:7.1.2" dependencies: ansi-regex: ^6.0.1 - checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d + checksum: db0e3f9654e519c8a33c50fc9304d07df5649388e7da06d3aabf66d29e5ad65d5e6315d8519d409c15b32fa82c1df7e11ed6f8cd50b0e4404463f0c9d77c8d0b languageName: node linkType: hard @@ -18823,20 +19885,10 @@ __metadata: languageName: node linkType: hard -"strip-comments@npm:^1.0.2": - version: 1.0.2 - resolution: "strip-comments@npm:1.0.2" - dependencies: - babel-extract-comments: ^1.0.0 - babel-plugin-transform-object-rest-spread: ^6.26.0 - checksum: 19e6f659a617566aef011b29ef9ce50da0db24556073d9c8065c73072f89bf1238d1fcaaa485933fee038a50a09bb04493097f66e622cdfc3a114f5e9e99ee24 - languageName: node - linkType: hard - -"strip-eof@npm:^1.0.0": - version: 1.0.0 - resolution: "strip-eof@npm:1.0.0" - checksum: 40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 +"strip-comments@npm:^2.0.1": + version: 2.0.1 + resolution: "strip-comments@npm:2.0.1" + checksum: 36cd122e1c27b5be69df87e1687770a62fe183bdee9f3ff5cf85d30bbc98280afc012581f2fd50c7ad077c90f656f272560c9d2e520d28604b8b7ea3bc87d6f9 languageName: node linkType: hard @@ -18863,44 +19915,65 @@ __metadata: languageName: node linkType: hard -"strip-literal@npm:^1.0.1": - version: 1.3.0 - resolution: "strip-literal@npm:1.3.0" - dependencies: - acorn: ^8.10.0 - checksum: f5fa7e289df8ebe82e90091fd393974faf8871be087ca50114327506519323cf15f2f8fee6ebe68b5e58bfc795269cae8bdc7cb5a83e27b02b3fe953f37b0a89 +"strip-json-comments@npm:~2.0.1": + version: 2.0.1 + resolution: "strip-json-comments@npm:2.0.1" + checksum: 1074ccb63270d32ca28edfb0a281c96b94dc679077828135141f27d52a5a398ef5e78bcf22809d23cadc2b81dfbe345eb5fd8699b385c8b1128907dec4a7d1e1 languageName: node linkType: hard -"style-loader@npm:1.3.0": - version: 1.3.0 - resolution: "style-loader@npm:1.3.0" +"strip-literal@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-literal@npm:3.0.0" dependencies: - loader-utils: ^2.0.0 - schema-utils: ^2.7.0 + js-tokens: ^9.0.1 + checksum: f697a31c4ad82ad259e0c57e715cde4585084af2260e38b3c916f34f0d462cec2af294a8b8cf062cc6f40d940ece7b79b0ec8316beabb2ed13c6e13e95ca70f0 + languageName: node + linkType: hard + +"strnum@npm:^2.1.0": + version: 2.1.1 + resolution: "strnum@npm:2.1.1" + checksum: 566139b218ef13bdde2a69c744852ac41ea167588f624d46c3b3bebb5d1d1775c55bca4702a0ad2a6a66eb4b3b7de4cbbc83e8d40c5835feabebf6f9cc468993 + languageName: node + linkType: hard + +"style-loader@npm:^3.3.1": + version: 3.3.4 + resolution: "style-loader@npm:3.3.4" peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: 1be9e8705307f5b8eb89e80f3703fa27296dccec349d790eace7aabe212f08c7c8f3ea6b6cb97bc53e82fbebfb9aa0689259671a8315f4655e24a850781e062a + webpack: ^5.0.0 + checksum: caac3f2fe2c3c89e49b7a2a9329e1cfa515ecf5f36b9c4885f9b218019fda207a9029939b2c35821dec177a264a007e7c391ccdd3ff7401881ce6287b9c8f38b languageName: node linkType: hard -"style-to-object@npm:^0.3.0": - version: 0.3.0 - resolution: "style-to-object@npm:0.3.0" +"style-to-js@npm:^1.0.0": + version: 1.1.17 + resolution: "style-to-js@npm:1.1.17" dependencies: - inline-style-parser: 0.1.1 - checksum: 4d7084015207f2a606dfc10c29cb5ba569f2fe8005551df7396110dd694d6ff650f2debafa95bd5d147dfb4ca50f57868e2a7f91bf5d11ef734fe7ccbd7abf59 + style-to-object: 1.0.9 + checksum: cdf92a0a42383fcc535972b7ec73395b53e370e5eaa345faf4d360f7918789cd73a20a79eef6d764b6441ff2e532a42ad5830ab87fec60a9dfc177fa438a6876 languageName: node linkType: hard -"stylehacks@npm:^4.0.0": - version: 4.0.3 - resolution: "stylehacks@npm:4.0.3" +"style-to-object@npm:1.0.9": + version: 1.0.9 + resolution: "style-to-object@npm:1.0.9" dependencies: - browserslist: ^4.0.0 - postcss: ^7.0.0 - postcss-selector-parser: ^3.0.0 - checksum: 8acf28ea609bee6d7ba40121bcf53af8d899c1ec04f2c08de9349b8292b84b8aa7f82e14c623ae6956decf5b7a7eeea5472ab8e48de7bdcdb6d76640444f6753 + inline-style-parser: 0.2.4 + checksum: a89e229161a56c53e28d1b91dcdc902f482f577db8b13741d3f056df7df0fbff4ecb44e06e32960f11c3a477b26f056e889a223bef6bc72b162935c5e4828145 + languageName: node + linkType: hard + +"stylehacks@npm:^5.1.1": + version: 5.1.1 + resolution: "stylehacks@npm:5.1.1" + dependencies: + browserslist: ^4.21.4 + postcss-selector-parser: ^6.0.4 + peerDependencies: + postcss: ^8.2.15 + checksum: 11175366ef52de65bf06cefba0ddc9db286dc3a1451fd2989e74c6ea47091a02329a4bf6ce10b1a36950056927b6bbbe47c5ab3a1f4c7032df932d010fbde5a2 languageName: node linkType: hard @@ -18911,6 +19984,24 @@ __metadata: languageName: node linkType: hard +"sucrase@npm:^3.35.0": + version: 3.35.0 + resolution: "sucrase@npm:3.35.0" + 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 + checksum: 9fc5792a9ab8a14dcf9c47dcb704431d35c1cdff1d17d55d382a31c2e8e3063870ad32ce120a80915498486246d612e30cda44f1624d9d9a10423e1a43487ad1 + languageName: node + linkType: hard + "superagent@npm:^8.1.2": version: 8.1.2 resolution: "superagent@npm:8.1.2" @@ -18939,23 +20030,16 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^2.0.0": - version: 2.0.0 - resolution: "supports-color@npm:2.0.0" - checksum: 602538c5812b9006404370b5a4b885d3e2a1f6567d314f8b4a41974ffe7d08e525bf92ae0f9c7030e3b4c78e4e34ace55d6a67a74f1571bc205959f5972f88f0 - languageName: node - linkType: hard - -"supports-color@npm:^3.2.3": - version: 3.2.3 - resolution: "supports-color@npm:3.2.3" +"supports-color@npm:8.1.1, supports-color@npm:^8.0.0": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" dependencies: - has-flag: ^1.0.0 - checksum: 56afc05fa87d00100d90148c4d0a6e20a0af0d56dca5c54d4d40b2553ee737dab0ca4e8b53c4471afc035227b5b44dfa4824747a7f01ad733173536f7da6fbbb + has-flag: ^4.0.0 + checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 languageName: node linkType: hard -"supports-color@npm:^5.3.0, supports-color@npm:^5.4.0, supports-color@npm:^5.5.0": +"supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" dependencies: @@ -18964,15 +20048,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^6.1.0": - version: 6.1.0 - resolution: "supports-color@npm:6.1.0" - dependencies: - has-flag: ^3.0.0 - checksum: 74358f9535c83ee113fbaac354b11e808060f6e7d8722082ee43af3578469134e89d00026dce2a6b93ce4e5b89d0e9a10f638b2b9f64c7838c2fb2883a47b3d5 - languageName: node - linkType: hard - "supports-color@npm:^7.0.0, supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -18982,15 +20057,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: ^4.0.0 - checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 - languageName: node - linkType: hard - "supports-hyperlinks@npm:^2.0.0": version: 2.3.0 resolution: "supports-hyperlinks@npm:2.3.0" @@ -19015,7 +20081,7 @@ __metadata: languageName: node linkType: hard -"svgo@npm:^1.0.0, svgo@npm:^1.2.2": +"svgo@npm:^1.2.2": version: 1.3.2 resolution: "svgo@npm:1.3.2" dependencies: @@ -19038,6 +20104,23 @@ __metadata: languageName: node linkType: hard +"svgo@npm:^2.7.0": + version: 2.8.0 + resolution: "svgo@npm:2.8.0" + dependencies: + "@trysound/sax": 0.2.0 + commander: ^7.2.0 + css-select: ^4.1.3 + css-tree: ^1.1.3 + csso: ^4.2.0 + picocolors: ^1.0.0 + stable: ^0.1.8 + bin: + svgo: bin/svgo + checksum: b92f71a8541468ffd0b81b8cdb36b1e242eea320bf3c1a9b2c8809945853e9d8c80c19744267eb91cabf06ae9d5fff3592d677df85a31be4ed59ff78534fa420 + languageName: node + linkType: hard + "symbol-tree@npm:^3.2.4": version: 3.2.4 resolution: "symbol-tree@npm:3.2.4" @@ -19045,130 +20128,176 @@ __metadata: languageName: node linkType: hard +"synckit@npm:^0.11.7": + version: 0.11.11 + resolution: "synckit@npm:0.11.11" + dependencies: + "@pkgr/core": ^0.2.9 + checksum: bc896d4320525501495654766e6b0aa394e522476ea0547af603bdd9fd7e9b65dcd6e3a237bc7eb3ab7e196376712f228bf1bf6ed1e1809f4b32dc9baf7ad413 + languageName: node + linkType: hard + "table@npm:^6.0.9": - version: 6.8.2 - resolution: "table@npm:6.8.2" + version: 6.9.0 + resolution: "table@npm:6.9.0" dependencies: ajv: ^8.0.1 lodash.truncate: ^4.4.2 slice-ansi: ^4.0.0 string-width: ^4.2.3 strip-ansi: ^6.0.1 - checksum: 61188652f53a980d1759ca460ca8dea5c5322aece3210457e7084882f053c2b6a870041295e08a82cb1d676e31b056406845d94b0abf3c79a4b104777bec413b + checksum: f54a7d1c11cda8c676e1e9aff5e723646905ed4579cca14b3ce12d2b12eac3e18f5dbe2549fe0b79697164858e18961145db4dd0660bbeb0fb4032af0aaf32b4 + languageName: node + linkType: hard + +"tailwindcss@npm:^3.0.2": + version: 3.4.17 + resolution: "tailwindcss@npm:3.4.17" + 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: ^3.1.3 + 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 + checksum: bda962f30e9a2f0567e2ee936ec863d5178958078e577ced13da60b3af779062a53a7e95f2f32b5c558f12a7477dea3ce071441a7362c6d7bf50bc9e166728a4 languageName: node linkType: hard -"tapable@npm:^1.0.0, tapable@npm:^1.1.3": +"tapable@npm:^1.0.0": version: 1.1.3 resolution: "tapable@npm:1.1.3" checksum: 53ff4e7c3900051c38cc4faab428ebfd7e6ad0841af5a7ac6d5f3045c5b50e88497bfa8295b4b3fbcadd94993c9e358868b78b9fb249a76cb8b018ac8dccafd7 languageName: node linkType: hard -"tar@npm:^6.0.2, tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.2.1 - resolution: "tar@npm:6.2.1" - 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 - checksum: f1322768c9741a25356c11373bce918483f40fa9a25c69c59410c8a1247632487edef5fe76c5f12ac51a6356d2f1829e96d2bc34098668a2fc34d76050ac2b6c +"tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": + version: 2.2.3 + resolution: "tapable@npm:2.2.3" + checksum: 0bef252c4f12d3371353c4b16b38ea4fc7153598ab7f7770a4235277ed4d631925a27f42bf03caa754817e9ab017e3179fd2323a0a28409846d225e23f3bf722 languageName: node linkType: hard -"temp-dir@npm:^1.0.0": - version: 1.0.0 - resolution: "temp-dir@npm:1.0.0" - checksum: cb2b58ddfb12efa83e939091386ad73b425c9a8487ea0095fe4653192a40d49184a771a1beba99045fbd011e389fd563122d79f54f82be86a55620667e08a6b2 +"tar-fs@npm:^2.0.0": + version: 2.1.3 + resolution: "tar-fs@npm:2.1.3" + dependencies: + chownr: ^1.1.1 + mkdirp-classic: ^0.5.2 + pump: ^3.0.0 + tar-stream: ^2.1.4 + checksum: 8dd66c20779c1fe535df5cf2ab5132705c12aba3ab95283f225a798329c5aaa8bbe92144c8e21bc9404f46a0d3ce59fc4997f5c42bafc55b6a225d4ad15aa966 languageName: node linkType: hard -"tempy@npm:^0.3.0": - version: 0.3.0 - resolution: "tempy@npm:0.3.0" +"tar-stream@npm:^2.1.4": + version: 2.2.0 + resolution: "tar-stream@npm:2.2.0" dependencies: - temp-dir: ^1.0.0 - type-fest: ^0.3.1 - unique-string: ^1.0.0 - checksum: f81ef72a7ee6d512439af8d8891e4fc6595309451910d7ac9d760f1242a1f87272b2b97c830c8f74aaa93a3aa550483bb16db17e6345601f64d614d240edc322 + bl: ^4.0.3 + end-of-stream: ^1.4.1 + fs-constants: ^1.0.0 + inherits: ^2.0.3 + readable-stream: ^3.1.1 + checksum: 699831a8b97666ef50021c767f84924cfee21c142c2eb0e79c63254e140e6408d6d55a065a2992548e72b06de39237ef2b802b99e3ece93ca3904a37622a66f3 languageName: node linkType: hard -"terminal-link@npm:^2.0.0": - version: 2.1.1 - resolution: "terminal-link@npm:2.1.1" +"tar@npm:^7.4.3": + version: 7.4.3 + resolution: "tar@npm:7.4.3" dependencies: - ansi-escapes: ^4.2.1 - supports-hyperlinks: ^2.0.0 - checksum: ce3d2cd3a438c4a9453947aa664581519173ea40e77e2534d08c088ee6dda449eabdbe0a76d2a516b8b73c33262fedd10d5270ccf7576ae316e3db170ce6562f + "@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 + checksum: 8485350c0688331c94493031f417df069b778aadb25598abdad51862e007c39d1dd5310702c7be4a6784731a174799d8885d2fde0484269aea205b724d7b2ffa languageName: node linkType: hard -"terser-webpack-plugin@npm:4.2.3": - version: 4.2.3 - resolution: "terser-webpack-plugin@npm:4.2.3" +"temp-dir@npm:^2.0.0": + version: 2.0.0 + resolution: "temp-dir@npm:2.0.0" + checksum: cc4f0404bf8d6ae1a166e0e64f3f409b423f4d1274d8c02814a59a5529f07db6cd070a749664141b992b2c1af337fa9bb451a460a43bb9bcddc49f235d3115aa + languageName: node + linkType: hard + +"tempy@npm:^0.6.0": + version: 0.6.0 + resolution: "tempy@npm:0.6.0" dependencies: - cacache: ^15.0.5 - find-cache-dir: ^3.3.1 - jest-worker: ^26.5.0 - p-limit: ^3.0.2 - schema-utils: ^3.0.0 - serialize-javascript: ^5.0.1 - source-map: ^0.6.1 - terser: ^5.3.4 - webpack-sources: ^1.4.3 - peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: ec1b3a85e2645c57e359d5e4831f3e1d78eca2a0c94b156db70eb846ae35b5e6e98ad8784b12e153fc273e57445ce69d017075bbe9fc42868a258ef121f11537 + is-stream: ^2.0.0 + temp-dir: ^2.0.0 + type-fest: ^0.16.0 + unique-string: ^2.0.0 + checksum: dd09c8b6615e4b785ea878e9a18b17ac0bfe5dccf5a0e205ebd274bb356356aff3f5c90a6c917077d51c75efb7648b113a78b0492e2ffc81a7c9912eb872ac52 languageName: node linkType: hard -"terser-webpack-plugin@npm:^1.4.3": - version: 1.4.5 - resolution: "terser-webpack-plugin@npm:1.4.5" +"terminal-link@npm:^2.0.0": + version: 2.1.1 + resolution: "terminal-link@npm:2.1.1" dependencies: - cacache: ^12.0.2 - find-cache-dir: ^2.1.0 - is-wsl: ^1.1.0 - schema-utils: ^1.0.0 - serialize-javascript: ^4.0.0 - source-map: ^0.6.1 - terser: ^4.1.2 - webpack-sources: ^1.4.0 - worker-farm: ^1.7.0 - peerDependencies: - webpack: ^4.0.0 - checksum: 02aada80927d3c8105d69cb00384d307b73aed67d180db5d20023a8d649149f3803ad50f9cd2ef9eb2622005de87e677198ecc5088f51422bfac5d4d57472d0e + ansi-escapes: ^4.2.1 + supports-hyperlinks: ^2.0.0 + checksum: ce3d2cd3a438c4a9453947aa664581519173ea40e77e2534d08c088ee6dda449eabdbe0a76d2a516b8b73c33262fedd10d5270ccf7576ae316e3db170ce6562f languageName: node linkType: hard -"terser@npm:^4.1.2, terser@npm:^4.6.2, terser@npm:^4.6.3": - version: 4.8.1 - resolution: "terser@npm:4.8.1" +"terser-webpack-plugin@npm:^5.2.5, terser-webpack-plugin@npm:^5.3.11": + version: 5.3.14 + resolution: "terser-webpack-plugin@npm:5.3.14" dependencies: - commander: ^2.20.0 - source-map: ~0.6.1 - source-map-support: ~0.5.12 - bin: - terser: bin/terser - checksum: b342819bf7e82283059aaa3f22bb74deb1862d07573ba5a8947882190ad525fd9b44a15074986be083fd379c58b9a879457a330b66dcdb77b485c44267f9a55a + "@jridgewell/trace-mapping": ^0.3.25 + jest-worker: ^27.4.5 + schema-utils: ^4.3.0 + serialize-javascript: ^6.0.2 + terser: ^5.31.1 + peerDependencies: + webpack: ^5.1.0 + peerDependenciesMeta: + "@swc/core": + optional: true + esbuild: + optional: true + uglify-js: + optional: true + checksum: 13a1e67f1675a473b18d25cb0ce65c3f0a19b5e9a93213a99ea61dc4ca996ea93aa17a221965b526f5788d242836a8249ad00538fbb322e25cb69076eb55feab languageName: node linkType: hard -"terser@npm:^5.3.4": - version: 5.30.4 - resolution: "terser@npm:5.30.4" +"terser@npm:^5.0.0, terser@npm:^5.10.0, terser@npm:^5.31.1": + version: 5.44.0 + resolution: "terser@npm:5.44.0" dependencies: "@jridgewell/source-map": ^0.3.3 - acorn: ^8.8.2 + acorn: ^8.15.0 commander: ^2.20.0 source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: 4e33a98d451a1175c83f668cb1dd34e1b4573890ba3081e0389e71e6552ca501ebfda5b15cddeab33585f7b4c13f2e7ad9ba9613655b9e36bc919fde48ba2dcd + checksum: 4e1868d9662ea280dad7b49cfe61b7693187be2b529b31b1f86782db00833c03ba05f2b82fc513d928e937260f2a5fbf42a93724e86eaf55f069288f934ccdb3 languageName: node linkType: hard @@ -19183,34 +20312,35 @@ __metadata: languageName: node linkType: hard -"text-table@npm:0.2.0, text-table@npm:^0.2.0": +"text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a languageName: node linkType: hard -"throat@npm:^5.0.0": - version: 5.0.0 - resolution: "throat@npm:5.0.0" - checksum: 031ff7f4431618036c1dedd99c8aa82f5c33077320a8358ed829e84b320783781d1869fe58e8f76e948306803de966f5f7573766a437562c9f5c033297ad2fe2 +"thenify-all@npm:^1.0.0": + version: 1.6.0 + resolution: "thenify-all@npm:1.6.0" + dependencies: + thenify: ">= 3.1.0 < 4" + checksum: dba7cc8a23a154cdcb6acb7f51d61511c37a6b077ec5ab5da6e8b874272015937788402fd271fdfc5f187f8cb0948e38d0a42dcc89d554d731652ab458f5343e languageName: node linkType: hard -"through2@npm:^2.0.0": - version: 2.0.5 - resolution: "through2@npm:2.0.5" +"thenify@npm:>= 3.1.0 < 4": + version: 3.3.1 + resolution: "thenify@npm:3.3.1" dependencies: - readable-stream: ~2.3.6 - xtend: ~4.0.1 - checksum: beb0f338aa2931e5660ec7bf3ad949e6d2e068c31f4737b9525e5201b824ac40cac6a337224856b56bd1ddd866334bbfb92a9f57cd6f66bc3f18d3d86fc0fe50 + any-promise: ^1.0.0 + checksum: 84e1b804bfec49f3531215f17b4a6e50fd4397b5f7c1bccc427b9c656e1ecfb13ea79d899930184f78bc2f57285c54d9a50a590c8868f4f0cef5c1d9f898b05e languageName: node linkType: hard -"through@npm:^2.3.6": - version: 2.3.8 - resolution: "through@npm:2.3.8" - checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd +"throat@npm:^6.0.1": + version: 6.0.2 + resolution: "throat@npm:6.0.2" + checksum: 463093768d4884772020bb18b0f33d3fec8a2b4173f7da3958dfbe88ff0f1e686ffadf0f87333bf6f6db7306b1450efc7855df69c78bf0bfa61f6d84a3361fe8 languageName: node linkType: hard @@ -19221,23 +20351,14 @@ __metadata: languageName: node linkType: hard -"timers-browserify@npm:^2.0.4": - version: 2.0.12 - resolution: "timers-browserify@npm:2.0.12" - dependencies: - setimmediate: ^1.0.4 - checksum: ec37ae299066bef6c464dcac29c7adafba1999e7227a9bdc4e105a459bee0f0b27234a46bfd7ab4041da79619e06a58433472867a913d01c26f8a203f87cee70 - languageName: node - linkType: hard - -"timsort@npm:^0.3.0": - version: 0.3.0 - resolution: "timsort@npm:0.3.0" - checksum: 1a66cb897dacabd7dd7c91b7e2301498ca9e224de2edb9e42d19f5b17c4b6dc62a8d4cbc64f28be82aaf1541cb5a78ab49aa818f42a2989ebe049a64af731e2a +"tiny-case@npm:^1.0.3": + version: 1.0.3 + resolution: "tiny-case@npm:1.0.3" + checksum: 3f7a30c39d5b0e1bc097b0b271bec14eb5b836093db034f35a0de26c14422380b50dc12bfd37498cf35b192f5df06f28a710712c87ead68872a9e37ad6f6049d languageName: node linkType: hard -"tiny-invariant@npm:^1.0.2": +"tiny-invariant@npm:^1.0.0, tiny-invariant@npm:^1.0.2, tiny-invariant@npm:^1.0.6, tiny-invariant@npm:^1.3.1": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 5e185c8cc2266967984ce3b352a4e57cb89dad5a8abb0dea21468a6ecaa67cd5bb47a3b7a85d08041008644af4f667fb8b6575ba38ba5fb00b3b5068306e59fe @@ -19251,73 +20372,87 @@ __metadata: languageName: node linkType: hard -"tinybench@npm:^2.5.0": - version: 2.8.0 - resolution: "tinybench@npm:2.8.0" - checksum: 024a307c6a71f6e2903e110952457ee3dfa606093b45d7f49efcfd01d452650e099474080677ff650b0fd76b49074425ac68ff2a70561699a78515a278bf0862 +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 1ab00d7dfe0d1f127cbf00822bacd9024f7a50a3ecd1f354a8168e0b7d2b53a639a24414e707c27879d1adc0f5153141d51d76ebd7b4d37fe245e742e5d91fe8 languageName: node linkType: hard -"tinypool@npm:^0.5.0": - version: 0.5.0 - resolution: "tinypool@npm:0.5.0" - checksum: 4e0dfd8f28666d541c1d92304222edc4613f05d74fe2243c8520d466a2cc6596011a7072c1c41a7de7522351b82fda07e8038198e8f43673d8d69401c5903f8c +"tinyexec@npm:^0.3.1, tinyexec@npm:^0.3.2": + version: 0.3.2 + resolution: "tinyexec@npm:0.3.2" + checksum: bd491923020610bdeadb0d8cf5d70e7cbad5a3201620fd01048c9bf3b31ffaa75c33254e1540e13b993ce4e8187852b0b5a93057bb598e7a57afa2ca2048a35c languageName: node linkType: hard -"tinyspy@npm:^2.1.1": - version: 2.2.1 - resolution: "tinyspy@npm:2.2.1" - checksum: 170d6232e87f9044f537b50b406a38fbfd6f79a261cd12b92879947bd340939a833a678632ce4f5c4a6feab4477e9c21cd43faac3b90b68b77dd0536c4149736 +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": + version: 0.2.15 + resolution: "tinyglobby@npm:0.2.15" + dependencies: + fdir: ^6.5.0 + picomatch: ^4.0.3 + checksum: 0e33b8babff966c6ab86e9b825a350a6a98a63700fa0bb7ae6cf36a7770a508892383adc272f7f9d17aaf46a9d622b455e775b9949a3f951eaaf5dfb26331d44 languageName: node linkType: hard -"tmp@npm:^0.0.33": - version: 0.0.33 - resolution: "tmp@npm:0.0.33" - dependencies: - os-tmpdir: ~1.0.2 - checksum: 902d7aceb74453ea02abbf58c203f4a8fc1cead89b60b31e354f74ed5b3fb09ea817f94fb310f884a5d16987dd9fa5a735412a7c2dd088dd3d415aa819ae3a28 +"tinypool@npm:^1.0.1, tinypool@npm:^1.1.1": + version: 1.1.1 + resolution: "tinypool@npm:1.1.1" + checksum: 0258abe108df8be395a2cbdc8b4390c94908850250530f7bea83a129fa33d49a8c93246f76bf81cd458534abd81322f4d4cb3a40690254f8d9044ff449f328a8 languageName: node linkType: hard -"tmpl@npm:1.0.5": - version: 1.0.5 - resolution: "tmpl@npm:1.0.5" - checksum: cd922d9b853c00fe414c5a774817be65b058d54a2d01ebb415840960406c669a0fc632f66df885e24cb022ec812739199ccbdb8d1164c3e513f85bfca5ab2873 +"tinyrainbow@npm:^1.2.0": + version: 1.2.0 + resolution: "tinyrainbow@npm:1.2.0" + checksum: d1e2cb5400032c0092be00e4a3da5450bea8b4fad58bfb5d3c58ca37ff5c5e252f7fcfb9af247914854af79c46014add9d1042fe044358c305a129ed55c8be35 languageName: node linkType: hard -"to-arraybuffer@npm:^1.0.0": - version: 1.0.1 - resolution: "to-arraybuffer@npm:1.0.1" - checksum: 31433c10b388722729f5da04c6b2a06f40dc84f797bb802a5a171ced1e599454099c6c5bc5118f4b9105e7d049d3ad9d0f71182b77650e4fdb04539695489941 +"tinyrainbow@npm:^2.0.0": + version: 2.0.0 + resolution: "tinyrainbow@npm:2.0.0" + checksum: 26360631d97e43955a07cfb70fe40a154ce4e2bcd14fa3d37ce8e2ed8f4fa9e5ba00783e4906bbfefe6dcabef5d3510f5bee207cb693bee4e4e7553f5454bef1 languageName: node linkType: hard -"to-fast-properties@npm:^2.0.0": - version: 2.0.0 - resolution: "to-fast-properties@npm:2.0.0" - checksum: be2de62fe58ead94e3e592680052683b1ec986c72d589e7b21e5697f8744cdbf48c266fa72f6c15932894c10187b5f54573a3bcf7da0bfd964d5caf23d436168 +"tinyspy@npm:^3.0.2": + version: 3.0.2 + resolution: "tinyspy@npm:3.0.2" + checksum: 5db671b2ff5cd309de650c8c4761ca945459d7204afb1776db9a04fb4efa28a75f08517a8620c01ee32a577748802231ad92f7d5b194dc003ee7f987a2a06337 languageName: node linkType: hard -"to-object-path@npm:^0.3.0": - version: 0.3.0 - resolution: "to-object-path@npm:0.3.0" - dependencies: - kind-of: ^3.0.2 - checksum: 9425effee5b43e61d720940fa2b889623f77473d459c2ce3d4a580a4405df4403eec7be6b857455908070566352f9e2417304641ed158dda6f6a365fe3e66d70 +"tinyspy@npm:^4.0.3": + version: 4.0.3 + resolution: "tinyspy@npm:4.0.3" + checksum: cd5e52d09e2a67946d3a96e6cd68377e1281eb6aaddc9d38129bcec8971a55337ab438ac672857b983f5c620a9f978e784679054322155329d483d00d9291ba9 languageName: node linkType: hard -"to-regex-range@npm:^2.1.0": - version: 2.1.1 - resolution: "to-regex-range@npm:2.1.1" +"tldts-core@npm:^7.0.14": + version: 7.0.14 + resolution: "tldts-core@npm:7.0.14" + checksum: bc13d721605fb66dab2baaf3ae665a8a48722f5b86e2b8a9b299cdbdc34c2a3b7167a08566afe52eed3064a3a0fc08680c456aa170fa9a50d85b9421f787c6db + languageName: node + linkType: hard + +"tldts@npm:^7.0.5": + version: 7.0.14 + resolution: "tldts@npm:7.0.14" dependencies: - is-number: ^3.0.0 - repeat-string: ^1.6.1 - checksum: 46093cc14be2da905cc931e442d280b2e544e2bfdb9a24b3cf821be8d342f804785e5736c108d5be026021a05d7b38144980a61917eee3c88de0a5e710e10320 + tldts-core: ^7.0.14 + bin: + tldts: bin/cli.js + checksum: dfd07fe27f2d4bfb7219391dcf666e60ca5041c17e037a7eee3171d4a809e003f71abd73295ab846586c1b589f4aa727439038810e19ef86a8e74ac780deb421 + languageName: node + linkType: hard + +"tmpl@npm:1.0.5": + version: 1.0.5 + resolution: "tmpl@npm:1.0.5" + checksum: cd922d9b853c00fe414c5a774817be65b058d54a2d01ebb415840960406c669a0fc632f66df885e24cb022ec812739199ccbdb8d1164c3e513f85bfca5ab2873 languageName: node linkType: hard @@ -19330,18 +20465,6 @@ __metadata: languageName: node linkType: hard -"to-regex@npm:^3.0.1, to-regex@npm:^3.0.2": - version: 3.0.2 - resolution: "to-regex@npm:3.0.2" - dependencies: - define-property: ^2.0.2 - extend-shallow: ^3.0.2 - regex-not: ^1.0.2 - safe-regex: ^1.1.0 - checksum: 4ed4a619059b64e204aad84e4e5f3ea82d97410988bcece7cf6cbfdbf193d11bff48cf53842d88b8bb00b1bfc0d048f61f20f0709e6f393fd8fe0122662d9db4 - languageName: node - linkType: hard - "toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" @@ -19357,25 +20480,41 @@ __metadata: linkType: hard "touch@npm:^3.1.0": - version: 3.1.0 - resolution: "touch@npm:3.1.0" - dependencies: - nopt: ~1.0.10 + version: 3.1.1 + resolution: "touch@npm:3.1.1" bin: - nodetouch: ./bin/nodetouch.js - checksum: e0be589cb5b0e6dbfce6e7e077d4a0d5f0aba558ef769c6d9c33f635e00d73d5be49da6f8631db302ee073919d82b5b7f56da2987feb28765c95a7673af68647 + nodetouch: bin/nodetouch.js + checksum: fb8c54207500eb760b6b9d77b9c5626cc027c9ad44431eed4268845f00f8c6bbfc95ce7e9da8e487f020aa921982a8bc5d8e909d0606e82686bd0a08a8e0539b languageName: node linkType: hard "tough-cookie@npm:^4.0.0": - version: 4.1.3 - resolution: "tough-cookie@npm:4.1.3" + version: 4.1.4 + resolution: "tough-cookie@npm:4.1.4" dependencies: psl: ^1.1.33 punycode: ^2.1.1 universalify: ^0.2.0 url-parse: ^1.5.3 - checksum: c9226afff36492a52118432611af083d1d8493a53ff41ec4ea48e5b583aec744b989e4280bcf476c910ec1525a89a4a0f1cae81c08b18fb2ec3a9b3a72b91dcc + checksum: 5815059f014c31179a303c673f753f7899a6fce94ac93712c88ea5f3c26e0c042b5f0c7a599a00f8e0feeca4615dba75c3dffc54f3c1a489978aa8205e09307c + languageName: node + linkType: hard + +"tough-cookie@npm:^6.0.0": + version: 6.0.0 + resolution: "tough-cookie@npm:6.0.0" + dependencies: + tldts: ^7.0.5 + checksum: 66d32ee40e1c6c61be5388e1c124674871dae0a684c30853f1628a4da2c5ad4199a825d1b0a7ba424dadfba7b5a9b37e8c761eafbf48f1b9f75a4629e73b14bc + languageName: node + linkType: hard + +"tr46@npm:^1.0.1": + version: 1.0.1 + resolution: "tr46@npm:1.0.1" + dependencies: + punycode: ^2.1.0 + checksum: 96d4ed46bc161db75dbf9247a236ea0bfcaf5758baae6749e92afab0bc5a09cb59af21788ede7e55080f2bf02dce3e4a8f2a484cc45164e29f4b5e68f7cbcc1a languageName: node linkType: hard @@ -19395,7 +20534,7 @@ __metadata: languageName: node linkType: hard -"tree-kill@npm:^1.2.2": +"tree-kill@npm:1.2.2": version: 1.2.2 resolution: "tree-kill@npm:1.2.2" bin: @@ -19404,10 +20543,17 @@ __metadata: languageName: node linkType: hard -"trough@npm:^1.0.0": - version: 1.0.5 - resolution: "trough@npm:1.0.5" - checksum: d6c8564903ed00e5258bab92134b020724dbbe83148dc72e4bf6306c03ed8843efa1bcc773fa62410dd89161ecb067432dd5916501793508a9506cacbc408e25 +"trim-lines@npm:^3.0.0": + version: 3.0.1 + resolution: "trim-lines@npm:3.0.1" + checksum: e241da104682a0e0d807222cc1496b92e716af4db7a002f4aeff33ae6a0024fef93165d49eab11aa07c71e1347c42d46563f91dfaa4d3fb945aa535cdead53ed + languageName: node + linkType: hard + +"trough@npm:^2.0.0": + version: 2.2.0 + resolution: "trough@npm:2.2.0" + checksum: 6097df63169aca1f9b08c263b1b501a9b878387f46e161dde93f6d0bba7febba93c95f876a293c5ea370f6cb03bcb687b2488c8955c3cfb66c2c0161ea8c00f6 languageName: node linkType: hard @@ -19418,26 +20564,19 @@ __metadata: languageName: node linkType: hard -"ts-jest@npm:^26.2.0": - version: 26.5.6 - resolution: "ts-jest@npm:26.5.6" - dependencies: - bs-logger: 0.x - buffer-from: 1.x - fast-json-stable-stringify: 2.x - jest-util: ^26.1.0 - json5: 2.x - lodash: 4.x - make-error: 1.x - mkdirp: 1.x - semver: 7.x - yargs-parser: 20.x - peerDependencies: - jest: ">=26 <27" - typescript: ">=3.8 <5.0" - bin: - ts-jest: cli.js - checksum: 6f65ad4fe67ab3f0fd4c7f9954acbee863af05b2b3f88dd0f490bbcdc58002960fac908b2cb9f009ec14da6fe13cb00a39e291260d6e555abe72448d1c0a017f +"ts-api-utils@npm:^2.0.0": + version: 2.1.0 + resolution: "ts-api-utils@npm:2.1.0" + peerDependencies: + typescript: ">=4.8.4" + checksum: 5b1ef89105654d93d67582308bd8dfe4bbf6874fccbcaa729b08fbb00a940fd4c691ca6d0d2b18c3c70878d9a7e503421b7cc473dbc3d0d54258b86401d4b15d + languageName: node + linkType: hard + +"ts-interface-checker@npm:^0.1.9": + version: 0.1.13 + resolution: "ts-interface-checker@npm:0.1.13" + checksum: 20c29189c2dd6067a8775e07823ddf8d59a33e2ffc47a1bd59a5cb28bb0121a2969a816d5e77eda2ed85b18171aa5d1c4005a6b88ae8499ec7cc49f78571cb5e languageName: node linkType: hard @@ -19499,16 +20638,6 @@ __metadata: languageName: node linkType: hard -"ts-pnp@npm:1.2.0, ts-pnp@npm:^1.1.6": - version: 1.2.0 - resolution: "ts-pnp@npm:1.2.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: c2a698b85d521298fe6f2435fbf2d3dc5834b423ea25abd321805ead3f399dbeedce7ca09492d7eb005b9d2c009c6b9587055bc3ab273dc6b9e40eefd7edb5b2 - languageName: node - linkType: hard - "tsconfig-paths@npm:^3.15.0": version: 3.15.0 resolution: "tsconfig-paths@npm:3.15.0" @@ -19521,21 +20650,28 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.11.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0": +"tslib@npm:^1.11.1, tslib@npm:^1.8.1": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.1.0": - version: 2.6.2 - resolution: "tslib@npm:2.6.2" - checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad +"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.6.2": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a + languageName: node + linkType: hard + +"tsscmp@npm:^1.0.6": + version: 1.0.6 + resolution: "tsscmp@npm:1.0.6" + checksum: 1512384def36bccc9125cabbd4c3b0e68608d7ee08127ceaa0b84a71797263f1a01c7f82fa69be8a3bd3c1396e2965d2f7b52d581d3a5eeaf3967fbc52e3b3bf languageName: node linkType: hard -"tsutils@npm:^3.17.1, tsutils@npm:^3.21.0": +"tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" dependencies: @@ -19546,10 +20682,12 @@ __metadata: languageName: node linkType: hard -"tty-browserify@npm:0.0.0": - version: 0.0.0 - resolution: "tty-browserify@npm:0.0.0" - checksum: a06f746acc419cb2527ba19b6f3bd97b4a208c03823bfb37b2982629d2effe30ebd17eaed0d7e2fc741f3c4f2a0c43455bd5fb4194354b378e78cfb7ca687f59 +"tunnel-agent@npm:^0.6.0": + version: 0.6.0 + resolution: "tunnel-agent@npm:0.6.0" + dependencies: + safe-buffer: ^5.0.1 + checksum: 05f6510358f8afc62a057b8b692f05d70c1782b70db86d6a1e0d5e28a32389e52fa6e7707b6c5ecccacc031462e4bc35af85ecfe4bbc341767917b7cf6965711 languageName: node linkType: hard @@ -19571,13 +20709,20 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8, type-detect@npm:^4.0.0, type-detect@npm:^4.0.8": +"type-detect@npm:4.0.8": version: 4.0.8 resolution: "type-detect@npm:4.0.8" checksum: 62b5628bff67c0eb0b66afa371bd73e230399a8d2ad30d852716efcc4656a7516904570cd8631a49a3ce57c10225adf5d0cbdcb47f6b0255fe6557c453925a15 languageName: node linkType: hard +"type-fest@npm:^0.16.0": + version: 0.16.0 + resolution: "type-fest@npm:0.16.0" + checksum: 1a4102c06dc109db00418c753062e206cab65befd469d000ece4452ee649bf2a9cf57686d96fb42326bc9d918d9a194d4452897b486dcc41989e5c99e4e87094 + languageName: node + linkType: hard + "type-fest@npm:^0.20.2": version: 0.20.2 resolution: "type-fest@npm:0.20.2" @@ -19592,31 +20737,17 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.3.1": - version: 0.3.1 - resolution: "type-fest@npm:0.3.1" - checksum: 347ff46c2285616635cb59f722e7f396bee81b8988b6fc1f1536b725077f2abf6ccfa22ab7a78e9b6ce7debea0e6614bbf5946cbec6674ec1bde12113af3a65c - languageName: node - linkType: hard - -"type-fest@npm:^0.6.0": - version: 0.6.0 - resolution: "type-fest@npm:0.6.0" - checksum: b2188e6e4b21557f6e92960ec496d28a51d68658018cba8b597bd3ef757721d1db309f120ae987abeeda874511d14b776157ff809f23c6d1ce8f83b9b2b7d60f - languageName: node - linkType: hard - -"type-fest@npm:^0.8.1": - version: 0.8.1 - resolution: "type-fest@npm:0.8.1" - checksum: d61c4b2eba24009033ae4500d7d818a94fd6d1b481a8111612ee141400d5f1db46f199c014766b9fa9b31a6a7374d96fc748c6d688a78a3ce5a33123839becb7 +"type-fest@npm:^2.19.0": + version: 2.19.0 + resolution: "type-fest@npm:2.19.0" + checksum: a4ef07ece297c9fba78fc1bd6d85dff4472fe043ede98bd4710d2615d15776902b595abf62bd78339ed6278f021235fb28a96361f8be86ed754f778973a0d278 languageName: node linkType: hard -"type-fest@npm:^1.2.2": - version: 1.4.0 - resolution: "type-fest@npm:1.4.0" - checksum: b011c3388665b097ae6a109a437a04d6f61d81b7357f74cbcb02246f2f5bd72b888ae33631b99871388122ba0a87f4ff1c94078e7119ff22c70e52c0ff828201 +"type-fest@npm:^4.26.1": + version: 4.41.0 + resolution: "type-fest@npm:4.41.0" + checksum: 7055c0e3eb188425d07403f1d5dc175ca4c4f093556f26871fe22041bc93d137d54bef5851afa320638ca1379106c594f5aa153caa654ac1a7f22c71588a4e80 languageName: node linkType: hard @@ -19630,82 +20761,88 @@ __metadata: languageName: node linkType: hard -"type@npm:^2.7.2": - version: 2.7.2 - resolution: "type@npm:2.7.2" - checksum: 0f42379a8adb67fe529add238a3e3d16699d95b42d01adfe7b9a7c5da297f5c1ba93de39265ba30ffeb37dfd0afb3fb66ae09f58d6515da442219c086219f6f4 +"type-is@npm:^2.0.0, type-is@npm:^2.0.1": + version: 2.0.1 + resolution: "type-is@npm:2.0.1" + dependencies: + content-type: ^1.0.5 + media-typer: ^1.1.0 + mime-types: ^3.0.0 + checksum: 0266e7c782238128292e8c45e60037174d48c6366bb2d45e6bd6422b611c193f83409a8341518b6b5f33f8e4d5a959f38658cacfea77f0a3505b9f7ac1ddec8f languageName: node linkType: hard -"typed-array-buffer@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-buffer@npm:1.0.2" +"typed-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "typed-array-buffer@npm:1.0.3" dependencies: - call-bind: ^1.0.7 + call-bound: ^1.0.3 es-errors: ^1.3.0 - is-typed-array: ^1.1.13 - checksum: 02ffc185d29c6df07968272b15d5319a1610817916ec8d4cd670ded5d1efe72901541ff2202fcc622730d8a549c76e198a2f74e312eabbfb712ed907d45cbb0b + is-typed-array: ^1.1.14 + checksum: 3fb91f0735fb413b2bbaaca9fabe7b8fc14a3fa5a5a7546bab8a57e755be0e3788d893195ad9c2b842620592de0e68d4c077d4c2c41f04ec25b8b5bb82fa9a80 languageName: node linkType: hard -"typed-array-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "typed-array-byte-length@npm:1.0.1" +"typed-array-byte-length@npm:^1.0.3": + version: 1.0.3 + resolution: "typed-array-byte-length@npm:1.0.3" dependencies: - call-bind: ^1.0.7 + call-bind: ^1.0.8 for-each: ^0.3.3 - gopd: ^1.0.1 - has-proto: ^1.0.3 - is-typed-array: ^1.1.13 - checksum: f65e5ecd1cf76b1a2d0d6f631f3ea3cdb5e08da106c6703ffe687d583e49954d570cc80434816d3746e18be889ffe53c58bf3e538081ea4077c26a41055b216d + gopd: ^1.2.0 + has-proto: ^1.2.0 + is-typed-array: ^1.1.14 + checksum: cda9352178ebeab073ad6499b03e938ebc30c4efaea63a26839d89c4b1da9d2640b0d937fc2bd1f049eb0a38def6fbe8a061b601292ae62fe079a410ce56e3a6 languageName: node linkType: hard -"typed-array-byte-offset@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-byte-offset@npm:1.0.2" +"typed-array-byte-offset@npm:^1.0.4": + version: 1.0.4 + resolution: "typed-array-byte-offset@npm:1.0.4" dependencies: available-typed-arrays: ^1.0.7 - call-bind: ^1.0.7 + call-bind: ^1.0.8 for-each: ^0.3.3 - gopd: ^1.0.1 - has-proto: ^1.0.3 - is-typed-array: ^1.1.13 - checksum: c8645c8794a621a0adcc142e0e2c57b1823bbfa4d590ad2c76b266aa3823895cf7afb9a893bf6685e18454ab1b0241e1a8d885a2d1340948efa4b56add4b5f67 + gopd: ^1.2.0 + has-proto: ^1.2.0 + is-typed-array: ^1.1.15 + reflect.getprototypeof: ^1.0.9 + checksum: 670b7e6bb1d3c2cf6160f27f9f529e60c3f6f9611c67e47ca70ca5cfa24ad95415694c49d1dbfeda016d3372cab7dfc9e38c7b3e1bb8d692cae13a63d3c144d7 languageName: node linkType: hard -"typed-array-length@npm:^1.0.6": - version: 1.0.6 - resolution: "typed-array-length@npm:1.0.6" +"typed-array-length@npm:^1.0.7": + version: 1.0.7 + resolution: "typed-array-length@npm:1.0.7" dependencies: call-bind: ^1.0.7 for-each: ^0.3.3 gopd: ^1.0.1 - has-proto: ^1.0.3 is-typed-array: ^1.1.13 possible-typed-array-names: ^1.0.0 - checksum: f0315e5b8f0168c29d390ff410ad13e4d511c78e6006df4a104576844812ee447fcc32daab1f3a76c9ef4f64eff808e134528b5b2439de335586b392e9750e5c + reflect.getprototypeof: ^1.0.6 + checksum: deb1a4ffdb27cd930b02c7030cb3e8e0993084c643208e52696e18ea6dd3953dfc37b939df06ff78170423d353dc8b10d5bae5796f3711c1b3abe52872b3774c languageName: node linkType: hard -"typed-scss-modules@npm:^6.5.0": - version: 6.6.0 - resolution: "typed-scss-modules@npm:6.6.0" +"typed-scss-modules@npm:^8.1.1": + version: 8.1.1 + resolution: "typed-scss-modules@npm:8.1.1" dependencies: - bundle-require: ^3.0.4 + bundle-require: ^4.0.4 chalk: 4.1.2 change-case: ^4.1.2 chokidar: ^3.5.3 - css-modules-loader-core: ^1.1.0 - esbuild: ^0.14.21 + esbuild: ^0.17.0 glob: ^7.2.0 joycon: ^3.1.1 + postcss: ^8.4.27 + postcss-modules: ^6.0.0 reserved-words: ^0.1.2 slash: ^3.0.0 yargs: ^17.3.1 peerDependencies: - node-sass: ^4.12.0 + node-sass: ^7.0.3 || ^8.0.0 sass: ^1.49.7 peerDependenciesMeta: node-sass: @@ -19714,7 +20851,7 @@ __metadata: optional: true bin: typed-scss-modules: dist/lib/cli.js - checksum: aa039f1c26cb3a3fa5a445f25bf7f3f9754bcc55a9701b7d55fb380ac767eeb60ca2c17f1d983ad8cec4c9e92779e9f8bd57f2859a991ec8f31d6c3acd56856b + checksum: a5fb33bbe16722e58d192b744c7915c5e35610f9e3c9faa4f4193c7f36d2d9c6381e2069323b0201d56231ed1de253d34519cb56fae620944b928cff2ea30af6 languageName: node linkType: hard @@ -19734,6 +20871,16 @@ __metadata: languageName: node linkType: hard +"typescript@npm:5.7.3": + version: 5.7.3 + resolution: "typescript@npm:5.7.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 6c38b1e989918e576f0307e6ee013522ea480dfce5f3ca85c9b2d8adb1edeffd37f4f30cd68de0c38a44563d12ba922bdb7e36aa2dac9c51de5d561e6e9a2e9c + languageName: node + linkType: hard + "typescript@npm:^4.1.5": version: 4.9.5 resolution: "typescript@npm:4.9.5" @@ -19744,6 +20891,26 @@ __metadata: languageName: node linkType: hard +"typescript@npm:^5.7.3": + version: 5.9.2 + resolution: "typescript@npm:5.9.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: f619cf6773cfe31409279711afd68cdf0859780006c50bc2a7a0c3227f85dea89a3b97248846326f3a17dad72ea90ec27cf61a8387772c680b2252fd02d8497b + languageName: node + linkType: hard + +"typescript@patch:typescript@5.7.3#~builtin": + version: 5.7.3 + resolution: "typescript@patch:typescript@npm%3A5.7.3#~builtin::version=5.7.3&hash=7ad353" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 633cd749d6cd7bc842c6b6245847173bba99742a60776fae3c0fbcc0d1733cd51a733995e5f4dadd8afb0e64e57d3c7dbbeae953a072ee303940eca69e22f311 + languageName: node + linkType: hard + "typescript@patch:typescript@^4.1.5#~builtin": version: 4.9.5 resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=7ad353" @@ -19754,22 +20921,25 @@ __metadata: languageName: node linkType: hard -"ufo@npm:^1.3.2": - version: 1.5.3 - resolution: "ufo@npm:1.5.3" - checksum: 2f54fa543b2e689cc4ab341fe2194937afe37c5ee43cd782e6ecc184e36859e84d4197a43ae4cd6e9a56f793ca7c5b950dfff3f16fadaeef9b6b88b05c88c8ef +"typescript@patch:typescript@^5.7.3#~builtin": + version: 5.9.2 + resolution: "typescript@patch:typescript@npm%3A5.9.2#~builtin::version=5.9.2&hash=7ad353" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: e42a701947325500008334622321a6ad073f842f5e7d5e7b588a6346b31fdf51d56082b9ce5cef24312ecd3e48d6c0d4d44da7555f65e2feec18cf62ec540385 languageName: node linkType: hard -"unbox-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "unbox-primitive@npm:1.0.2" +"unbox-primitive@npm:^1.1.0": + version: 1.1.0 + resolution: "unbox-primitive@npm:1.1.0" dependencies: - call-bind: ^1.0.2 + call-bound: ^1.0.3 has-bigints: ^1.0.2 - has-symbols: ^1.0.3 - which-boxed-primitive: ^1.0.2 - checksum: b7a1cf5862b5e4b5deb091672ffa579aa274f648410009c81cca63fed3b62b610c4f3b773f912ce545bb4e31edc3138975b5bc777fc6e4817dca51affb6380e9 + has-symbols: ^1.1.0 + which-boxed-primitive: ^1.1.1 + checksum: 729f13b84a5bfa3fead1d8139cee5c38514e63a8d6a437819a473e241ba87eeb593646568621c7fc7f133db300ef18d65d1a5a60dc9c7beb9000364d93c581df languageName: node linkType: hard @@ -19787,17 +20957,24 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~5.26.4": - version: 5.26.5 - resolution: "undici-types@npm:5.26.5" - checksum: 3192ef6f3fd5df652f2dc1cd782b49d6ff14dc98e5dced492aa8a8c65425227da5da6aafe22523c67f035a272c599bb89cfe803c1db6311e44bed3042fc25487 +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 46331c7d6016bf85b3e8f20c159d62f5ae471aba1eb3dc52fff35a0259d58dcc7d592d4cc4f00c5f9243fa738a11cfa48bd20203040d4a9e6bc25e807fab7ab3 + languageName: node + linkType: hard + +"undici-types@npm:~7.12.0": + version: 7.12.0 + resolution: "undici-types@npm:7.12.0" + checksum: 4ad2770b92835757eee6416e8518972d83fc77286c11af81d368a55578d9e4f7ab1b8a3b13c304b0e25a400583e66f3c58464a051f8b5c801ab5d092da13903e languageName: node linkType: hard "unicode-canonical-property-names-ecmascript@npm:^2.0.0": - version: 2.0.0 - resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.0" - checksum: 39be078afd014c14dcd957a7a46a60061bc37c4508ba146517f85f60361acf4c7539552645ece25de840e17e293baa5556268d091ca6762747fdd0c705001a45 + version: 2.0.1 + resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1" + checksum: 3c3dabdb1d22aef4904399f9e810d0b71c0b12b3815169d96fac97e56d5642840c6071cf709adcace2252bc6bb80242396c2ec74b37224eb015c5f7aca40bad7 languageName: node linkType: hard @@ -19811,167 +20988,107 @@ __metadata: languageName: node linkType: hard -"unicode-match-property-value-ecmascript@npm:^2.1.0": - version: 2.1.0 - resolution: "unicode-match-property-value-ecmascript@npm:2.1.0" - checksum: 8d6f5f586b9ce1ed0e84a37df6b42fdba1317a05b5df0c249962bd5da89528771e2d149837cad11aa26bcb84c35355cb9f58a10c3d41fa3b899181ece6c85220 +"unicode-match-property-value-ecmascript@npm:^2.2.1": + version: 2.2.1 + resolution: "unicode-match-property-value-ecmascript@npm:2.2.1" + checksum: e6c73e07bb4dc4aa399797a14b170e84a30ed290bcf97cc4305cf67dde8744119721ce17cef03f4f9d4ff48654bfa26eadc7fe1e8dd4b71b8f3b2e9a9742f013 languageName: node linkType: hard "unicode-property-aliases-ecmascript@npm:^2.0.0": - version: 2.1.0 - resolution: "unicode-property-aliases-ecmascript@npm:2.1.0" - checksum: 243524431893649b62cc674d877bd64ef292d6071dd2fd01ab4d5ad26efbc104ffcd064f93f8a06b7e4ec54c172bf03f6417921a0d8c3a9994161fe1f88f815b + version: 2.2.0 + resolution: "unicode-property-aliases-ecmascript@npm:2.2.0" + checksum: 0dd0f6e70130c59b4a841bac206758f70227b113145e4afe238161e3e8540e8eb79963e7a228cd90ad13d499e96f7ef4ee8940835404b2181ad9bf9c174818e3 languageName: node linkType: hard -"unified@npm:^9.0.0": - version: 9.2.2 - resolution: "unified@npm:9.2.2" +"unified@npm:^11.0.0": + version: 11.0.5 + resolution: "unified@npm:11.0.5" dependencies: - bail: ^1.0.0 + "@types/unist": ^3.0.0 + bail: ^2.0.0 + devlop: ^1.0.0 extend: ^3.0.0 - is-buffer: ^2.0.0 - is-plain-obj: ^2.0.0 - trough: ^1.0.0 - vfile: ^4.0.0 - checksum: 7c24461be7de4145939739ce50d18227c5fbdf9b3bc5a29dabb1ce26dd3e8bd4a1c385865f6f825f3b49230953ee8b591f23beab3bb3643e3e9dc37aa8a089d5 + is-plain-obj: ^4.0.0 + trough: ^2.0.0 + vfile: ^6.0.0 + checksum: b3bf7fd6f568cc261e074dae21188483b0f2a8ab858d62e6e85b75b96cc655f59532906ae3c64d56a9b257408722d71f1d4135292b3d7ee02907c8b592fb3cf0 languageName: node linkType: hard -"union-value@npm:^1.0.0": - version: 1.0.1 - resolution: "union-value@npm:1.0.1" +"unique-filename@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-filename@npm:4.0.0" dependencies: - arr-union: ^3.1.0 - get-value: ^2.0.6 - is-extendable: ^0.1.1 - set-value: ^2.0.1 - checksum: a3464097d3f27f6aa90cf103ed9387541bccfc006517559381a10e0dffa62f465a9d9a09c9b9c3d26d0f4cbe61d4d010e2fbd710fd4bf1267a768ba8a774b0ba + unique-slug: ^5.0.0 + checksum: 6a62094fcac286b9ec39edbd1f8f64ff92383baa430af303dfed1ffda5e47a08a6b316408554abfddd9730c78b6106bef4ca4d02c1231a735ddd56ced77573df languageName: node linkType: hard -"uniq@npm:^1.0.1": - version: 1.0.1 - resolution: "uniq@npm:1.0.1" - checksum: 8206535f83745ea83f9da7035f3b983fd6ed5e35b8ed7745441944e4065b616bc67cf0d0a23a86b40ee0074426f0607f0a138f9b78e124eb6a7a6a6966055709 +"unique-slug@npm:^5.0.0": + version: 5.0.0 + resolution: "unique-slug@npm:5.0.0" + dependencies: + imurmurhash: ^0.1.4 + checksum: 222d0322bc7bbf6e45c08967863212398313ef73423f4125e075f893a02405a5ffdbaaf150f7dd1e99f8861348a486dd079186d27c5f2c60e465b7dcbb1d3e5b languageName: node linkType: hard -"uniqs@npm:^2.0.0": +"unique-string@npm:^2.0.0": version: 2.0.0 - resolution: "uniqs@npm:2.0.0" - checksum: 5ace63e0521fd1ae2c161b3fa167cf6846fc45a71c00496729e0146402c3ae467c6f025a68fbd6766300a9bfbac9f240f2f0198164283bef48012b39db83f81f - languageName: node - linkType: hard - -"unique-filename@npm:^1.1.1": - version: 1.1.1 - resolution: "unique-filename@npm:1.1.1" + resolution: "unique-string@npm:2.0.0" dependencies: - unique-slug: ^2.0.0 - checksum: cf4998c9228cc7647ba7814e255dec51be43673903897b1786eff2ac2d670f54d4d733357eb08dea969aa5e6875d0e1bd391d668fbdb5a179744e7c7551a6f80 + crypto-random-string: ^2.0.0 + checksum: ef68f639136bcfe040cf7e3cd7a8dff076a665288122855148a6f7134092e6ed33bf83a7f3a9185e46c98dddc445a0da6ac25612afa1a7c38b8b654d6c02498e languageName: node linkType: hard -"unique-filename@npm:^3.0.0": - version: 3.0.0 - resolution: "unique-filename@npm:3.0.0" +"unist-util-is@npm:^6.0.0": + version: 6.0.0 + resolution: "unist-util-is@npm:6.0.0" dependencies: - unique-slug: ^4.0.0 - checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + "@types/unist": ^3.0.0 + checksum: f630a925126594af9993b091cf807b86811371e465b5049a6283e08537d3e6ba0f7e248e1e7dab52cfe33f9002606acef093441137181b327f6fe504884b20e2 languageName: node linkType: hard -"unique-slug@npm:^2.0.0": - version: 2.0.2 - resolution: "unique-slug@npm:2.0.2" +"unist-util-position@npm:^5.0.0": + version: 5.0.0 + resolution: "unist-util-position@npm:5.0.0" dependencies: - imurmurhash: ^0.1.4 - checksum: 5b6876a645da08d505dedb970d1571f6cebdf87044cb6b740c8dbb24f0d6e1dc8bdbf46825fd09f994d7cf50760e6f6e063cfa197d51c5902c00a861702eb75a + "@types/unist": ^3.0.0 + checksum: f89b27989b19f07878de9579cd8db2aa0194c8360db69e2c99bd2124a480d79c08f04b73a64daf01a8fb3af7cba65ff4b45a0b978ca243226084ad5f5d441dde languageName: node linkType: hard -"unique-slug@npm:^4.0.0": +"unist-util-stringify-position@npm:^4.0.0": version: 4.0.0 - resolution: "unique-slug@npm:4.0.0" - dependencies: - imurmurhash: ^0.1.4 - checksum: 0884b58365af59f89739e6f71e3feacb5b1b41f2df2d842d0757933620e6de08eff347d27e9d499b43c40476cbaf7988638d3acb2ffbcb9d35fd035591adfd15 - languageName: node - linkType: hard - -"unique-string@npm:^1.0.0": - version: 1.0.0 - resolution: "unique-string@npm:1.0.0" - dependencies: - crypto-random-string: ^1.0.0 - checksum: 588f16bd4ec99b5130f237793d1a5694156adde20460366726573238e41e93b739b87987e863792aeb2392b26f8afb292490ace119c82ed12c46816c9c859f5f - languageName: node - linkType: hard - -"unist-builder@npm:^2.0.0": - version: 2.0.3 - resolution: "unist-builder@npm:2.0.3" - checksum: e946fdf77dbfc320feaece137ce4959ae2da6614abd1623bd39512dc741a9d5f313eb2ba79f8887d941365dccddec7fef4e953827475e392bf49b45336f597f6 - languageName: node - linkType: hard - -"unist-util-generated@npm:^1.0.0": - version: 1.1.6 - resolution: "unist-util-generated@npm:1.1.6" - checksum: 86239ff88a08800d52198f2f0e15911f05bab2dad17cef95550f7c2728f15ebb0344694fcc3101d05762d88adaf86cb85aa7a3300fedabd0b6d7d00b41cdcb7f - languageName: node - linkType: hard - -"unist-util-is@npm:^4.0.0": - version: 4.1.0 - resolution: "unist-util-is@npm:4.1.0" - checksum: 726484cd2adc9be75a939aeedd48720f88294899c2e4a3143da413ae593f2b28037570730d5cf5fd910ff41f3bc1501e3d636b6814c478d71126581ef695f7ea - languageName: node - linkType: hard - -"unist-util-position@npm:^3.0.0": - version: 3.1.0 - resolution: "unist-util-position@npm:3.1.0" - checksum: 10b3952e32a1ffabbecad41c3946237f7059f5bb6436796da05531a285f50b97e4f37cfc2f7164676d041063f40fe1ad92fbb8ca38d3ae8747328ebe738d738f - languageName: node - linkType: hard - -"unist-util-stringify-position@npm:^2.0.0": - version: 2.0.3 - resolution: "unist-util-stringify-position@npm:2.0.3" + resolution: "unist-util-stringify-position@npm:4.0.0" dependencies: - "@types/unist": ^2.0.2 - checksum: f755cadc959f9074fe999578a1a242761296705a7fe87f333a37c00044de74ab4b184b3812989a57d4cd12211f0b14ad397b327c3a594c7af84361b1c25a7f09 + "@types/unist": ^3.0.0 + checksum: e2e7aee4b92ddb64d314b4ac89eef7a46e4c829cbd3ee4aee516d100772b490eb6b4974f653ba0717a0071ca6ea0770bf22b0a2ea62c65fcba1d071285e96324 languageName: node linkType: hard -"unist-util-visit-parents@npm:^3.0.0": - version: 3.1.1 - resolution: "unist-util-visit-parents@npm:3.1.1" +"unist-util-visit-parents@npm:^6.0.0": + version: 6.0.1 + resolution: "unist-util-visit-parents@npm:6.0.1" dependencies: - "@types/unist": ^2.0.0 - unist-util-is: ^4.0.0 - checksum: 1170e397dff88fab01e76d5154981666eb0291019d2462cff7a2961a3e76d3533b42eaa16b5b7e2d41ad42a5ea7d112301458283d255993e660511387bf67bc3 + "@types/unist": ^3.0.0 + unist-util-is: ^6.0.0 + checksum: 08927647c579f63b91aafcbec9966dc4a7d0af1e5e26fc69f4e3e6a01215084835a2321b06f3cbe7bf7914a852830fc1439f0fc3d7153d8804ac3ef851ddfa20 languageName: node linkType: hard -"unist-util-visit@npm:^2.0.0": - version: 2.0.3 - resolution: "unist-util-visit@npm:2.0.3" +"unist-util-visit@npm:^5.0.0": + version: 5.0.0 + resolution: "unist-util-visit@npm:5.0.0" dependencies: - "@types/unist": ^2.0.0 - unist-util-is: ^4.0.0 - unist-util-visit-parents: ^3.0.0 - checksum: 1fe19d500e212128f96d8c3cfa3312846e586b797748a1fd195fe6479f06bc90a6f6904deb08eefc00dd58e83a1c8a32fb8677252d2273ad7a5e624525b69b8f - languageName: node - linkType: hard - -"universalify@npm:^0.1.0": - version: 0.1.2 - resolution: "universalify@npm:0.1.2" - checksum: 40cdc60f6e61070fe658ca36016a8f4ec216b29bf04a55dce14e3710cc84c7448538ef4dad3728d0bfe29975ccd7bfb5f414c45e7b78883567fb31b246f02dff + "@types/unist": ^3.0.0 + unist-util-is: ^6.0.0 + unist-util-visit-parents: ^6.0.0 + checksum: 9ec42e618e7e5d0202f3c191cd30791b51641285732767ee2e6bcd035931032e3c1b29093f4d7fd0c79175bbc1f26f24f26ee49770d32be76f8730a652a857e6 languageName: node linkType: hard @@ -20013,34 +21130,24 @@ __metadata: languageName: node linkType: hard -"unset-value@npm:^1.0.0": - version: 1.0.0 - resolution: "unset-value@npm:1.0.0" - dependencies: - has-value: ^0.3.1 - isobject: ^3.0.0 - checksum: 5990ecf660672be2781fc9fb322543c4aa592b68ed9a3312fa4df0e9ba709d42e823af090fc8f95775b4cd2c9a5169f7388f0cec39238b6d0d55a69fc2ab6b29 - languageName: node - linkType: hard - -"upath@npm:^1.1.1, upath@npm:^1.1.2, upath@npm:^1.2.0": +"upath@npm:^1.2.0": version: 1.2.0 resolution: "upath@npm:1.2.0" checksum: 4c05c094797cb733193a0784774dbea5b1889d502fc9f0572164177e185e4a59ba7099bf0b0adf945b232e2ac60363f9bf18aac9b2206fb99cbef971a8455445 languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.13": - version: 1.0.13 - resolution: "update-browserslist-db@npm:1.0.13" +"update-browserslist-db@npm:^1.1.3": + version: 1.1.3 + resolution: "update-browserslist-db@npm:1.1.3" dependencies: - escalade: ^3.1.1 - picocolors: ^1.0.0 + escalade: ^3.2.0 + picocolors: ^1.1.1 peerDependencies: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 1e47d80182ab6e4ad35396ad8b61008ae2a1330221175d0abd37689658bdb61af9b705bfc41057fd16682474d79944fb2d86767c5ed5ae34b6276b9bed353322 + checksum: 7b6d8d08c34af25ee435bccac542bedcb9e57c710f3c42421615631a80aa6dd28b0a81c9d2afbef53799d482fb41453f714b8a7a0a8003e3b4ec8fb1abb819af languageName: node linkType: hard @@ -20071,31 +21178,7 @@ __metadata: languageName: node linkType: hard -"urix@npm:^0.1.0": - version: 0.1.0 - resolution: "urix@npm:0.1.0" - checksum: 4c076ecfbf3411e888547fe844e52378ab5ada2d2f27625139011eada79925e77f7fbf0e4016d45e6a9e9adb6b7e64981bd49b22700c7c401c5fc15f423303b3 - languageName: node - linkType: hard - -"url-loader@npm:4.1.1": - version: 4.1.1 - resolution: "url-loader@npm:4.1.1" - dependencies: - loader-utils: ^2.0.0 - mime-types: ^2.1.27 - schema-utils: ^3.0.0 - peerDependencies: - file-loader: "*" - webpack: ^4.0.0 || ^5.0.0 - peerDependenciesMeta: - file-loader: - optional: true - checksum: c1122a992c6cff70a7e56dfc2b7474534d48eb40b2cc75467cde0c6972e7597faf8e43acb4f45f93c2473645dfd803bcbc20960b57544dd1e4c96e77f72ba6fd - languageName: node - linkType: hard - -"url-parse@npm:^1.5.10, url-parse@npm:^1.5.3": +"url-parse@npm:^1.5.3": version: 1.5.10 resolution: "url-parse@npm:1.5.10" dependencies: @@ -20112,20 +21195,21 @@ __metadata: languageName: node linkType: hard -"url@npm:^0.11.0": - version: 0.11.3 - resolution: "url@npm:0.11.3" - dependencies: - punycode: ^1.4.1 - qs: ^6.11.2 - checksum: f9e7886f46a16f96d2e42fbcc5d682c231c55ef5442c1ff66150c0f6556f6e3a97d094a84f51be15ec2432711d212eb60426659ce418f5fcadeaa3f601532c4e +"use-memo-one@npm:^1.1.3": + version: 1.1.3 + resolution: "use-memo-one@npm:1.1.3" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 8f08eba26d69406b61bb4b8dacdd5a92bd6aef5b53d346dfe87954f7330ee10ecabc937cc7854635155d46053828e85c10b5a5aff7a04720e6a97b9f42999bac languageName: node linkType: hard -"use@npm:^3.1.0": - version: 3.1.1 - resolution: "use@npm:3.1.1" - checksum: 08a130289f5238fcbf8f59a18951286a6e660d17acccc9d58d9b69dfa0ee19aa038e8f95721b00b432c36d1629a9e32a464bf2e7e0ae6a244c42ddb30bdd8b33 +"use-sync-external-store@npm:^1.4.0": + version: 1.5.0 + resolution: "use-sync-external-store@npm:1.5.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 5e639c9273200adb6985b512c96a3a02c458bc8ca1a72e91da9cdc6426144fc6538dca434b0f99b28fb1baabc82e1c383ba7900b25ccdcb43758fb058dc66c34 languageName: node linkType: hard @@ -20136,16 +21220,6 @@ __metadata: languageName: node linkType: hard -"util.promisify@npm:1.0.0": - version: 1.0.0 - resolution: "util.promisify@npm:1.0.0" - dependencies: - define-properties: ^1.1.2 - object.getownpropertydescriptors: ^2.0.3 - checksum: 482e857d676adee506c5c3a10212fd6a06a51d827a9b6d5396a8e593db53b4bb7064f77c5071357d8cd76072542de5cc1c08bc6d7c10cf43fa22dc3bc67556f1 - languageName: node - linkType: hard - "util.promisify@npm:~1.0.0": version: 1.0.1 resolution: "util.promisify@npm:1.0.1" @@ -20158,37 +21232,6 @@ __metadata: languageName: node linkType: hard -"util@npm:^0.10.4": - version: 0.10.4 - resolution: "util@npm:0.10.4" - dependencies: - inherits: 2.0.3 - checksum: 913f9a90d05a60e91f91af01b8bd37e06bca4cc02d7b49e01089f9d5b78be2fffd61fb1a41b517de7238c5fc7337fa939c62d1fb4eb82e014894c7bee6637aaf - languageName: node - linkType: hard - -"util@npm:^0.11.0": - version: 0.11.1 - resolution: "util@npm:0.11.1" - dependencies: - inherits: 2.0.3 - checksum: 80bee6a2edf5ab08dcb97bfe55ca62289b4e66f762ada201f2c5104cb5e46474c8b334f6504d055c0e6a8fda10999add9bcbd81ba765e7f37b17dc767331aa55 - languageName: node - linkType: hard - -"util@npm:^0.12.3": - version: 0.12.5 - resolution: "util@npm:0.12.5" - dependencies: - inherits: ^2.0.3 - is-arguments: ^1.0.4 - is-generator-function: ^1.0.7 - is-typed-array: ^1.1.3 - which-typed-array: ^1.1.2 - checksum: 705e51f0de5b446f4edec10739752ac25856541e0254ea1e7e45e5b9f9b0cb105bc4bd415736a6210edc68245a7f903bf085ffb08dd7deb8a0e847f60538a38a - languageName: node - linkType: hard - "utila@npm:~0.4": version: 0.4.0 resolution: "utila@npm:0.4.0" @@ -20203,16 +21246,16 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^3.3.2": - version: 3.4.0 - resolution: "uuid@npm:3.4.0" +"uuid@npm:^11.1.0": + version: 11.1.0 + resolution: "uuid@npm:11.1.0" bin: - uuid: ./bin/uuid - checksum: 58de2feed61c59060b40f8203c0e4ed7fd6f99d42534a499f1741218a1dd0c129f4aa1de797bcf822c8ea5da7e4137aa3673431a96dae729047f7aca7b27866f + uuid: dist/esm/bin/uuid + checksum: 840f19758543c4631e58a29439e51b5b669d5f34b4dd2700b6a1d15c5708c7a6e0c3e2c8c4a2eae761a3a7caa7e9884d00c86c02622ba91137bd3deade6b4b4a languageName: node linkType: hard -"uuid@npm:^8.3.0, uuid@npm:^8.3.2": +"uuid@npm:^8.3.2": version: 8.3.2 resolution: "uuid@npm:8.3.2" bin: @@ -20221,7 +21264,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^9.0.0": +"uuid@npm:^9.0.0, uuid@npm:^9.0.1": version: 9.0.1 resolution: "uuid@npm:9.0.1" bin: @@ -20244,31 +21287,21 @@ __metadata: languageName: node linkType: hard -"v8-to-istanbul@npm:^7.0.0": - version: 7.1.2 - resolution: "v8-to-istanbul@npm:7.1.2" +"v8-to-istanbul@npm:^8.1.0": + version: 8.1.1 + resolution: "v8-to-istanbul@npm:8.1.1" dependencies: "@types/istanbul-lib-coverage": ^2.0.1 convert-source-map: ^1.6.0 source-map: ^0.7.3 - checksum: e52b48764f55aed62ff87f2b5f710c874f992cd1313eac8f438bf65aeeb0689153d85bb76e39514fd90ba3521d6ebea929a8ae1339b6d7b0cf18fb0ed13d8b40 - languageName: node - linkType: hard - -"validate-npm-package-license@npm:^3.0.1": - version: 3.0.4 - resolution: "validate-npm-package-license@npm:3.0.4" - dependencies: - spdx-correct: ^3.0.0 - spdx-expression-parse: ^3.0.0 - checksum: 35703ac889d419cf2aceef63daeadbe4e77227c39ab6287eeb6c1b36a746b364f50ba22e88591f5d017bc54685d8137bc2d328d0a896e4d3fd22093c0f32a9ad + checksum: 54ce92bec2727879626f623d02c8d193f0c7e919941fa373ec135189a8382265117f5316ea317a1e12a5f9c13d84d8449052a731fe3306fa4beaafbfa4cab229 languageName: node linkType: hard "validator@npm:^13.9.0": - version: 13.11.0 - resolution: "validator@npm:13.11.0" - checksum: d1e0c27022681420756da25bc03eb08d5f0c66fb008f8ff02ebc95812b77c6be6e03d3bd05cf80ca702e23eeb73dadd66b4b3683173ea2a0bc7cc72820bee131 + version: 13.15.15 + resolution: "validator@npm:13.15.15" + checksum: 10c1b9215a25c31497c481cf4a3ee3e17dcf0b8a219445788e7167ed1b93b8597bbf657bd5c8ca22199b699c3ab41df902c23526cc514075c4b71bd19a13d02c languageName: node linkType: hard @@ -20279,71 +21312,151 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:~1.1.2": +"vary@npm:^1, vary@npm:^1.1.2, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: ae0123222c6df65b437669d63dfa8c36cee20a504101b2fcd97b8bf76f91259c17f9f2b4d70a1e3c6bbcee7f51b28392833adb6b2770b23b01abec84e369660b languageName: node linkType: hard -"vendors@npm:^1.0.0": - version: 1.0.4 - resolution: "vendors@npm:1.0.4" - checksum: 4b16e0bc18dbdd7ac8dd745c776c08f6c73e9a7f620ffd9faf94a3d86a35feaf4c6cb1bbdb304d2381548a30d0abe69b83eeb1b7b1bf5bb33935e64b28812681 +"vfile-message@npm:^4.0.0": + version: 4.0.3 + resolution: "vfile-message@npm:4.0.3" + dependencies: + "@types/unist": ^3.0.0 + unist-util-stringify-position: ^4.0.0 + checksum: f5e8516f2aa0feb4c866d507543d4e90f9ab309e2c988577dbf4ebd268d495f72f2b48149849d14300164d5d60b5f74b5641cd285bb4408a3942b758683d9276 languageName: node linkType: hard -"vfile-message@npm:^2.0.0": - version: 2.0.4 - resolution: "vfile-message@npm:2.0.4" +"vfile@npm:^6.0.0": + version: 6.0.3 + resolution: "vfile@npm:6.0.3" dependencies: - "@types/unist": ^2.0.0 - unist-util-stringify-position: ^2.0.0 - checksum: 1bade499790f46ca5aba04bdce07a1e37c2636a8872e05cf32c26becc912826710b7eb063d30c5754fdfaeedc8a7658e78df10b3bc535c844890ec8a184f5643 + "@types/unist": ^3.0.0 + vfile-message: ^4.0.0 + checksum: 152b6729be1af70df723efb65c1a1170fd483d41086557da3651eea69a1dd1f0c22ea4344834d56d30734b9185bcab63e22edc81d3f0e9bed8aa4660d61080af languageName: node linkType: hard -"vfile@npm:^4.0.0": - version: 4.2.1 - resolution: "vfile@npm:4.2.1" +"victory-vendor@npm:^36.6.8": + version: 36.9.2 + resolution: "victory-vendor@npm:36.9.2" dependencies: - "@types/unist": ^2.0.0 - is-buffer: ^2.0.0 - unist-util-stringify-position: ^2.0.0 - vfile-message: ^2.0.0 - checksum: ee5726e10d170472cde778fc22e0f7499caa096eb85babea5d0ce0941455b721037ee1c9e6ae506ca2803250acd313d0f464328ead0b55cfe7cb6315f1b462d6 + "@types/d3-array": ^3.0.3 + "@types/d3-ease": ^3.0.0 + "@types/d3-interpolate": ^3.0.1 + "@types/d3-scale": ^4.0.2 + "@types/d3-shape": ^3.1.0 + "@types/d3-time": ^3.0.0 + "@types/d3-timer": ^3.0.0 + d3-array: ^3.1.6 + d3-ease: ^3.0.1 + d3-interpolate: ^3.0.1 + d3-scale: ^4.0.2 + d3-shape: ^3.1.0 + d3-time: ^3.0.0 + d3-timer: ^3.0.1 + checksum: a755110e287b700202d08ac81982093ab100edaa9d61beef1476d59e9705605bd8299a3aa41fa04b933a12bd66737f4c8f7d18448dd6488c69d4f72480023a2e languageName: node linkType: hard -"vite-node@npm:0.32.4": - version: 0.32.4 - resolution: "vite-node@npm:0.32.4" +"vite-node@npm:2.1.9": + version: 2.1.9 + resolution: "vite-node@npm:2.1.9" dependencies: cac: ^6.7.14 - debug: ^4.3.4 - mlly: ^1.4.0 - pathe: ^1.1.1 - picocolors: ^1.0.0 - vite: ^3.0.0 || ^4.0.0 + debug: ^4.3.7 + es-module-lexer: ^1.5.4 + pathe: ^1.1.2 + vite: ^5.0.0 bin: vite-node: vite-node.mjs - checksum: 6edb7aafcc30b97213435e7b3bfa43e2133feadd46680c0e54b44064f9e38f9b6e3a75f7c0ccde6bf3b6f34cb9681ec6510fb966a11f9ca7239e9473200a4a24 + checksum: 716d37649834ecea547b43121ee89b2e4f9ca65ff6ce26214770ecfefe070b8c7245c9fdd0f92fb232d266e153629d04af9a4dc4fc350abfa521e5e46434b7b2 languageName: node linkType: hard -"vite@npm:^3.0.0 || ^4.0.0, vite@npm:^4.4.5": - version: 4.5.3 - resolution: "vite@npm:4.5.3" +"vite-node@npm:3.2.4": + version: 3.2.4 + resolution: "vite-node@npm:3.2.4" dependencies: - esbuild: ^0.18.10 - fsevents: ~2.3.2 - postcss: ^8.4.27 - rollup: ^3.27.1 + cac: ^6.7.14 + debug: ^4.4.1 + es-module-lexer: ^1.7.0 + pathe: ^2.0.3 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + bin: + vite-node: vite-node.mjs + checksum: 2051394d48f5eefdee4afc9c5fd5dcbf7eb36d345043ba035c7782e10b33fbbd14318062c4e32e00d473a31a559fb628d67c023e82a4903016db3ac6bfdb3fe7 + languageName: node + linkType: hard + +"vite@npm:6.0.7": + version: 6.0.7 + resolution: "vite@npm:6.0.7" + dependencies: + esbuild: ^0.24.2 + fsevents: ~2.3.3 + postcss: ^8.4.49 + rollup: ^4.23.0 + peerDependencies: + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: ">=1.21.0" + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 0a948bcd33cf1891a1079ccea6d7e2d1e030ed5d1ad86c9de41a5cb2935da50f77ef699a57ea12fa4a332d9def5494e80d75ea6504758d9d1d9a139f3c1c7fbe + languageName: node + linkType: hard + +"vite@npm:^5.0.0": + version: 5.4.20 + resolution: "vite@npm:5.4.20" + dependencies: + esbuild: ^0.21.3 + fsevents: ~2.3.3 + postcss: ^8.4.43 + rollup: ^4.20.0 peerDependencies: - "@types/node": ">= 14" + "@types/node": ^18.0.0 || >=20.0.0 less: "*" lightningcss: ^1.21.0 sass: "*" + sass-embedded: "*" stylus: "*" sugarss: "*" terser: ^5.4.0 @@ -20359,6 +21472,8 @@ __metadata: optional: true sass: optional: true + sass-embedded: + optional: true stylus: optional: true sugarss: @@ -20367,50 +21482,101 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: fd3f512ce48ca2a1fe60ad0376283b832de9272725fdbc65064ae9248f792de87b0f27a89573115e23e26784800daca329f8a9234d298ba6f60e808a9c63883c + checksum: 67af97e818977e92d1e55bc35d45f58d41eba6fc87f2a18435d3402adb07f4c4ec1ba838d954829f80f7784e65b65f8d147db695cfaefe45f667ee283530770d languageName: node linkType: hard -"vitest@npm:^0.32.1": - version: 0.32.4 - resolution: "vitest@npm:0.32.4" +"vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": + version: 7.1.5 + resolution: "vite@npm:7.1.5" dependencies: - "@types/chai": ^4.3.5 - "@types/chai-subset": ^1.3.3 - "@types/node": "*" - "@vitest/expect": 0.32.4 - "@vitest/runner": 0.32.4 - "@vitest/snapshot": 0.32.4 - "@vitest/spy": 0.32.4 - "@vitest/utils": 0.32.4 - acorn: ^8.9.0 - acorn-walk: ^8.2.0 - cac: ^6.7.14 - chai: ^4.3.7 - debug: ^4.3.4 - local-pkg: ^0.4.3 - magic-string: ^0.30.0 - pathe: ^1.1.1 - picocolors: ^1.0.0 - std-env: ^3.3.3 - strip-literal: ^1.0.1 - tinybench: ^2.5.0 - tinypool: ^0.5.0 - vite: ^3.0.0 || ^4.0.0 - vite-node: 0.32.4 - why-is-node-running: ^2.2.2 + esbuild: ^0.25.0 + fdir: ^6.5.0 + fsevents: ~2.3.3 + picomatch: ^4.0.3 + postcss: ^8.5.6 + rollup: ^4.43.0 + tinyglobby: ^0.2.15 + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 14922d98024a1d93ebe8f3ce38af586c83d55f037f8c5fe8664103d7aa0785d0747f3edf8cb6550dcfa071b90bfd40bce56581d9cb14a19a53d29abb9f3415f5 + languageName: node + linkType: hard + +"vitest@npm:^2.1.8": + version: 2.1.9 + resolution: "vitest@npm:2.1.9" + dependencies: + "@vitest/expect": 2.1.9 + "@vitest/mocker": 2.1.9 + "@vitest/pretty-format": ^2.1.9 + "@vitest/runner": 2.1.9 + "@vitest/snapshot": 2.1.9 + "@vitest/spy": 2.1.9 + "@vitest/utils": 2.1.9 + chai: ^5.1.2 + debug: ^4.3.7 + expect-type: ^1.1.0 + magic-string: ^0.30.12 + pathe: ^1.1.2 + std-env: ^3.8.0 + tinybench: ^2.9.0 + tinyexec: ^0.3.1 + tinypool: ^1.0.1 + tinyrainbow: ^1.2.0 + vite: ^5.0.0 + vite-node: 2.1.9 + why-is-node-running: ^2.3.0 peerDependencies: "@edge-runtime/vm": "*" - "@vitest/browser": "*" - "@vitest/ui": "*" + "@types/node": ^18.0.0 || >=20.0.0 + "@vitest/browser": 2.1.9 + "@vitest/ui": 2.1.9 happy-dom: "*" jsdom: "*" - playwright: "*" - safaridriver: "*" - webdriverio: "*" peerDependenciesMeta: "@edge-runtime/vm": optional: true + "@types/node": + optional: true "@vitest/browser": optional: true "@vitest/ui": @@ -20419,22 +21585,65 @@ __metadata: optional: true jsdom: optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true bin: vitest: vitest.mjs - checksum: 0f3347aac5656e6ba14c2f82d8fc5bfa333766ec745f7250f02a28d4cf6b35e645a300f0116a7db542430f59edb96cfeb3d2bc87856b84c776c25d10581f051b + checksum: 20db77529f843930ef1626103c898b27528d6d68d6c44753ec823e318f26bbdeb3bc56e6fb80e3f1ecc34382107d32e1f4e709e23198f414fecc9298ab225fa8 languageName: node linkType: hard -"vm-browserify@npm:^1.0.1": - version: 1.1.2 - resolution: "vm-browserify@npm:1.1.2" - checksum: 10a1c50aab54ff8b4c9042c15fc64aefccce8d2fb90c0640403242db0ee7fb269f9b102bdb69cfb435d7ef3180d61fd4fb004a043a12709abaf9056cfd7e039d +"vitest@npm:^3.0.0": + version: 3.2.4 + resolution: "vitest@npm:3.2.4" + dependencies: + "@types/chai": ^5.2.2 + "@vitest/expect": 3.2.4 + "@vitest/mocker": 3.2.4 + "@vitest/pretty-format": ^3.2.4 + "@vitest/runner": 3.2.4 + "@vitest/snapshot": 3.2.4 + "@vitest/spy": 3.2.4 + "@vitest/utils": 3.2.4 + chai: ^5.2.0 + debug: ^4.4.1 + expect-type: ^1.2.1 + magic-string: ^0.30.17 + pathe: ^2.0.3 + picomatch: ^4.0.2 + std-env: ^3.9.0 + tinybench: ^2.9.0 + tinyexec: ^0.3.2 + tinyglobby: ^0.2.14 + tinypool: ^1.1.1 + tinyrainbow: ^2.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + vite-node: 3.2.4 + why-is-node-running: ^2.3.0 + peerDependencies: + "@edge-runtime/vm": "*" + "@types/debug": ^4.1.12 + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@vitest/browser": 3.2.4 + "@vitest/ui": 3.2.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/debug": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: e9aa14a2c4471c2e0364d1d7032303db8754fac9e5e9ada92fca8ebf61ee78d2c5d4386bff25913940a22ea7d78ab435c8dd85785d681b23e2c489d6c17dd382 languageName: node linkType: hard @@ -20456,7 +21665,7 @@ __metadata: languageName: node linkType: hard -"walker@npm:^1.0.7, walker@npm:~1.0.5": +"walker@npm:^1.0.7": version: 1.0.8 resolution: "walker@npm:1.0.8" dependencies: @@ -20465,29 +21674,22 @@ __metadata: languageName: node linkType: hard -"watchpack-chokidar2@npm:^2.0.1": - version: 2.0.1 - resolution: "watchpack-chokidar2@npm:2.0.1" +"warning@npm:^4.0.0": + version: 4.0.3 + resolution: "warning@npm:4.0.3" dependencies: - chokidar: ^2.1.8 - checksum: acf0f9ebca0c0b2fd1fe87ba557670477a6c0410bf1a653a726e68eb0620aa94fd9a43027a160a76bc793a21ea12e215e1e87dafe762682c13ef92ad4daf7b58 + loose-envify: ^1.0.0 + checksum: 4f2cb6a9575e4faf71ddad9ad1ae7a00d0a75d24521c193fa464f30e6b04027bd97aa5d9546b0e13d3a150ab402eda216d59c1d0f2d6ca60124d96cd40dfa35c languageName: node linkType: hard -"watchpack@npm:^1.7.4": - version: 1.7.5 - resolution: "watchpack@npm:1.7.5" +"watchpack@npm:^2.4.1": + version: 2.4.4 + resolution: "watchpack@npm:2.4.4" dependencies: - chokidar: ^3.4.1 + glob-to-regexp: ^0.4.1 graceful-fs: ^4.1.2 - neo-async: ^2.5.0 - watchpack-chokidar2: ^2.0.1 - dependenciesMeta: - chokidar: - optional: true - watchpack-chokidar2: - optional: true - checksum: 8b7cb8c8df8f4dd0e8ac47693c0141c4f020a4b031411247d600eca31522fde6f1f9a3a6f6518b46e71f7971b0ed5734c08c60d7fdd2530e7262776286f69236 + checksum: 469514a04bcdd7ea77d4b3c62d1f087eafbce64cbc728c89355d5710ee01311533456122da7c585d3654d5bfcf09e6085db1a6eb274c4762a18e370526d17561 languageName: node linkType: hard @@ -20500,32 +21702,10 @@ __metadata: languageName: node linkType: hard -"wcwidth@npm:^1.0.1": - version: 1.0.1 - resolution: "wcwidth@npm:1.0.1" - dependencies: - defaults: ^1.0.3 - checksum: 814e9d1ddcc9798f7377ffa448a5a3892232b9275ebb30a41b529607691c0491de47cba426e917a4d08ded3ee7e9ba2f3fe32e62ee3cd9c7d3bafb7754bd553c - languageName: node - linkType: hard - -"web-encoding@npm:^1.1.5": - version: 1.1.5 - resolution: "web-encoding@npm:1.1.5" - dependencies: - "@zxing/text-encoding": 0.9.0 - util: ^0.12.3 - dependenciesMeta: - "@zxing/text-encoding": - optional: true - checksum: 2234a2b122f41006ce07859b3c0bf2e18f46144fda2907d5db0b571b76aa5c26977c646100ad9c00d2f8a4f6f2b848bc02147845d8c447ab365ec4eff376338d - languageName: node - linkType: hard - -"web-vitals@npm:^0.2.4": - version: 0.2.4 - resolution: "web-vitals@npm:0.2.4" - checksum: 128a4e87730b0a02fb6af3eef7d31f9a79b4646e83cfe4465aa8ce6054fe16f7b1f4125a384f1b4f039091bd9513cb54b4e559c0b10ae953c01900786a16b1c2 +"web-vitals@npm:^4.2.4": + version: 4.2.4 + resolution: "web-vitals@npm:4.2.4" + checksum: 5b3ffe1db33f23aebf8cc8560ac574401a95939baafde5841835c1bb1c01f9a2478442f319f77aa0d7914739fc2f6b020c5d5b128c16c5c77ca6be2f9dfbbde6 languageName: node linkType: hard @@ -20536,6 +21716,13 @@ __metadata: languageName: node linkType: hard +"webidl-conversions@npm:^4.0.2": + version: 4.0.2 + resolution: "webidl-conversions@npm:4.0.2" + checksum: c93d8dfe908a0140a4ae9c0ebc87a33805b416a33ee638a605b551523eec94a9632165e54632f6d57a39c5f948c4bab10e0e066525e9a4b87a79f0d04fbca374 + languageName: node + linkType: hard + "webidl-conversions@npm:^5.0.0": version: 5.0.0 resolution: "webidl-conversions@npm:5.0.0" @@ -20550,94 +21737,81 @@ __metadata: languageName: node linkType: hard -"webpack-dev-middleware@npm:^3.7.2": - version: 3.7.3 - resolution: "webpack-dev-middleware@npm:3.7.3" +"webpack-dev-middleware@npm:^5.3.4": + version: 5.3.4 + resolution: "webpack-dev-middleware@npm:5.3.4" dependencies: - memory-fs: ^0.4.1 - mime: ^2.4.4 - mkdirp: ^0.5.1 + colorette: ^2.0.10 + memfs: ^3.4.3 + mime-types: ^2.1.31 range-parser: ^1.2.1 - webpack-log: ^2.0.0 + schema-utils: ^4.0.0 peerDependencies: webpack: ^4.0.0 || ^5.0.0 - checksum: faa3cdd7b82d23c35b8f45903556eadd92b0795c76f3e08e234d53f7bab3de13331096a71968e7e9905770ae5de7a4f75ddf09f66d1e0bbabfecbb30db0f71e3 + checksum: 90cf3e27d0714c1a745454a1794f491b7076434939340605b9ee8718ba2b85385b120939754e9fdbd6569811e749dee53eec319e0d600e70e0b0baffd8e3fb13 languageName: node linkType: hard -"webpack-dev-server@npm:3.11.1": - version: 3.11.1 - resolution: "webpack-dev-server@npm:3.11.1" +"webpack-dev-server@npm:^4.6.0": + version: 4.15.2 + resolution: "webpack-dev-server@npm:4.15.2" dependencies: - ansi-html: 0.0.7 - bonjour: ^3.5.0 - chokidar: ^2.1.8 + "@types/bonjour": ^3.5.9 + "@types/connect-history-api-fallback": ^1.3.5 + "@types/express": ^4.17.13 + "@types/serve-index": ^1.9.1 + "@types/serve-static": ^1.13.10 + "@types/sockjs": ^0.3.33 + "@types/ws": ^8.5.5 + ansi-html-community: ^0.0.8 + bonjour-service: ^1.0.11 + chokidar: ^3.5.3 + colorette: ^2.0.10 compression: ^1.7.4 - connect-history-api-fallback: ^1.6.0 - debug: ^4.1.1 - del: ^4.1.1 - express: ^4.17.1 - html-entities: ^1.3.1 - http-proxy-middleware: 0.19.1 - import-local: ^2.0.0 - internal-ip: ^4.3.0 - ip: ^1.1.5 - is-absolute-url: ^3.0.3 - killable: ^1.0.1 - loglevel: ^1.6.8 - opn: ^5.5.0 - p-retry: ^3.0.1 - portfinder: ^1.0.26 - schema-utils: ^1.0.0 - selfsigned: ^1.10.8 - semver: ^6.3.0 + connect-history-api-fallback: ^2.0.0 + default-gateway: ^6.0.3 + express: ^4.17.3 + graceful-fs: ^4.2.6 + html-entities: ^2.3.2 + http-proxy-middleware: ^2.0.3 + ipaddr.js: ^2.0.1 + launch-editor: ^2.6.0 + open: ^8.0.9 + p-retry: ^4.5.0 + rimraf: ^3.0.2 + schema-utils: ^4.0.0 + selfsigned: ^2.1.1 serve-index: ^1.9.1 - sockjs: ^0.3.21 - sockjs-client: ^1.5.0 + sockjs: ^0.3.24 spdy: ^4.0.2 - strip-ansi: ^3.0.1 - supports-color: ^6.1.0 - url: ^0.11.0 - webpack-dev-middleware: ^3.7.2 - webpack-log: ^2.0.0 - ws: ^6.2.1 - yargs: ^13.3.2 + webpack-dev-middleware: ^5.3.4 + ws: ^8.13.0 peerDependencies: - webpack: ^4.0.0 || ^5.0.0 + webpack: ^4.37.0 || ^5.0.0 peerDependenciesMeta: + webpack: + optional: true webpack-cli: optional: true bin: webpack-dev-server: bin/webpack-dev-server.js - checksum: 6c6e6b6c207c192585f9943fc9945058832a39a12bbf0368798d73a96264b813ab816cb14985c1ca3c90cc567f59fcad6f2fada8f30f2f0136904cfaf43eb87d - languageName: node - linkType: hard - -"webpack-log@npm:^2.0.0": - version: 2.0.0 - resolution: "webpack-log@npm:2.0.0" - dependencies: - ansi-colors: ^3.0.0 - uuid: ^3.3.2 - checksum: 4757179310995e20633ec2d77a8c1ac11e4135c84745f57148692f8195f1c0f8ec122c77d0dc16fc484b7d301df6674f36c9fc6b1ff06b5cf142abaaf5d24f4f + checksum: 123507129cb4d55fdc5fabdd177574f31133605748372bb11353307b7a583ef25c6fd27b6addf56bf070ba44c88d5da861771c2ec55f52405082ec9efd01f039 languageName: node linkType: hard -"webpack-manifest-plugin@npm:2.2.0": - version: 2.2.0 - resolution: "webpack-manifest-plugin@npm:2.2.0" +"webpack-manifest-plugin@npm:^4.0.2": + version: 4.1.1 + resolution: "webpack-manifest-plugin@npm:4.1.1" dependencies: - fs-extra: ^7.0.0 - lodash: ">=3.5 <5" - object.entries: ^1.1.0 - tapable: ^1.0.0 + tapable: ^2.0.0 + webpack-sources: ^2.2.0 peerDependencies: - webpack: 2 || 3 || 4 - checksum: ed1387774031a59bc1bd5f79150e7a49dcf5048a6d5e9652672637bed7f93df6220cbd88b2e371e7c8c8e7640b3a8ed6895f771c6b05a8bb90b721f82001ac25 + webpack: ^4.44.2 || ^5.47.0 + checksum: 426982030d3b0ef26432d98960ee1fa33889d8f0ed79b3d2c8e37be9b4e4beba7524c60631297ea557c642a340b76d70b0eb6a1e08b86a769409037185795038 languageName: node linkType: hard -"webpack-sources@npm:^1.1.0, webpack-sources@npm:^1.3.0, webpack-sources@npm:^1.4.0, webpack-sources@npm:^1.4.1, webpack-sources@npm:^1.4.3": +"webpack-sources@npm:^1.4.3": version: 1.4.3 resolution: "webpack-sources@npm:1.4.3" dependencies: @@ -20647,41 +21821,58 @@ __metadata: languageName: node linkType: hard -"webpack@npm:4.44.2": - version: 4.44.2 - resolution: "webpack@npm:4.44.2" +"webpack-sources@npm:^2.2.0": + version: 2.3.1 + resolution: "webpack-sources@npm:2.3.1" dependencies: - "@webassemblyjs/ast": 1.9.0 - "@webassemblyjs/helper-module-context": 1.9.0 - "@webassemblyjs/wasm-edit": 1.9.0 - "@webassemblyjs/wasm-parser": 1.9.0 - acorn: ^6.4.1 - ajv: ^6.10.2 - ajv-keywords: ^3.4.1 + source-list-map: ^2.0.1 + source-map: ^0.6.1 + checksum: 6fd67f2274a84c5f51ad89767112ec8b47727134bf0f2ba0cff458c970f18966939a24128bdbddba621cd66eeb2bef0552642a9333cd8e54514f7b2a71776346 + languageName: node + linkType: hard + +"webpack-sources@npm:^3.3.3": + version: 3.3.3 + resolution: "webpack-sources@npm:3.3.3" + checksum: 243d438ec4dfe805cca20fa66d111114b1f277b8ecfa95bb6ee0a6c7d996aee682539952028c2b203a6c170e6ef56f71ecf3e366e90bf1cb58b0ae982176b651 + languageName: node + linkType: hard + +"webpack@npm:^5.64.4": + version: 5.101.3 + resolution: "webpack@npm:5.101.3" + dependencies: + "@types/eslint-scope": ^3.7.7 + "@types/estree": ^1.0.8 + "@types/json-schema": ^7.0.15 + "@webassemblyjs/ast": ^1.14.1 + "@webassemblyjs/wasm-edit": ^1.14.1 + "@webassemblyjs/wasm-parser": ^1.14.1 + acorn: ^8.15.0 + acorn-import-phases: ^1.0.3 + browserslist: ^4.24.0 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^4.3.0 - eslint-scope: ^4.0.3 - json-parse-better-errors: ^1.0.2 - loader-runner: ^2.4.0 - loader-utils: ^1.2.3 - memory-fs: ^0.4.1 - micromatch: ^3.1.10 - mkdirp: ^0.5.3 - neo-async: ^2.6.1 - node-libs-browser: ^2.2.1 - schema-utils: ^1.0.0 - tapable: ^1.1.3 - terser-webpack-plugin: ^1.4.3 - watchpack: ^1.7.4 - webpack-sources: ^1.4.1 + enhanced-resolve: ^5.17.3 + 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: ^4.3.2 + tapable: ^2.1.1 + terser-webpack-plugin: ^5.3.11 + watchpack: ^2.4.1 + webpack-sources: ^3.3.3 peerDependenciesMeta: webpack-cli: optional: true - webpack-command: - optional: true bin: webpack: bin/webpack.js - checksum: 3d42ee6af7a0ff14fc00136d02f4a36381fd5b6ad0636b95a8b83e6d99bc7e02f888f4994c095ae986e567033fe7bb1d445e27afe49d2872b8fe5c3a57d20de6 + checksum: d23fd86b6bc9854f9b488830d9aa123a7f654ee22849bc8670d0a22add88951f6d9cab1d04087758b642fc31115e3b97e0ac56b80b2200c04c486067aa945663 languageName: node linkType: hard @@ -20712,7 +21903,7 @@ __metadata: languageName: node linkType: hard -"whatwg-fetch@npm:^3.4.1": +"whatwg-fetch@npm:^3.6.2": version: 3.6.20 resolution: "whatwg-fetch@npm:3.6.20" checksum: c58851ea2c4efe5c2235f13450f426824cf0253c1d45da28f45900290ae602a20aff2ab43346f16ec58917d5562e159cd691efa368354b2e82918c2146a519c5 @@ -20736,6 +21927,17 @@ __metadata: languageName: node linkType: hard +"whatwg-url@npm:^7.0.0": + version: 7.1.0 + resolution: "whatwg-url@npm:7.1.0" + dependencies: + lodash.sortby: ^4.7.0 + tr46: ^1.0.1 + webidl-conversions: ^4.0.2 + checksum: fecb07c87290b47d2ec2fb6d6ca26daad3c9e211e0e531dd7566e7ff95b5b3525a57d4f32640ad4adf057717e0c215731db842ad761e61d947e81010e05cf5fd + languageName: node + linkType: hard + "whatwg-url@npm:^8.0.0, whatwg-url@npm:^8.5.0": version: 8.7.0 resolution: "whatwg-url@npm:8.7.0" @@ -20747,40 +21949,41 @@ __metadata: languageName: node linkType: hard -"which-boxed-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "which-boxed-primitive@npm:1.0.2" +"which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1": + version: 1.1.1 + resolution: "which-boxed-primitive@npm:1.1.1" dependencies: - is-bigint: ^1.0.1 - is-boolean-object: ^1.1.0 - is-number-object: ^1.0.4 - is-string: ^1.0.5 - is-symbol: ^1.0.3 - checksum: 53ce774c7379071729533922adcca47220228405e1895f26673bbd71bdf7fb09bee38c1d6399395927c6289476b5ae0629863427fd151491b71c4b6cb04f3a5e + is-bigint: ^1.1.0 + is-boolean-object: ^1.2.1 + is-number-object: ^1.1.1 + is-string: ^1.1.1 + is-symbol: ^1.1.1 + checksum: ee41d0260e4fd39551ad77700c7047d3d281ec03d356f5e5c8393fe160ba0db53ef446ff547d05f76ffabfd8ad9df7c9a827e12d4cccdbc8fccf9239ff8ac21e languageName: node linkType: hard -"which-builtin-type@npm:^1.1.3": - version: 1.1.3 - resolution: "which-builtin-type@npm:1.1.3" +"which-builtin-type@npm:^1.2.1": + version: 1.2.1 + resolution: "which-builtin-type@npm:1.2.1" dependencies: - function.prototype.name: ^1.1.5 - has-tostringtag: ^1.0.0 + call-bound: ^1.0.2 + function.prototype.name: ^1.1.6 + has-tostringtag: ^1.0.2 is-async-function: ^2.0.0 - is-date-object: ^1.0.5 - is-finalizationregistry: ^1.0.2 + is-date-object: ^1.1.0 + is-finalizationregistry: ^1.1.0 is-generator-function: ^1.0.10 - is-regex: ^1.1.4 + is-regex: ^1.2.1 is-weakref: ^1.0.2 isarray: ^2.0.5 - which-boxed-primitive: ^1.0.2 - which-collection: ^1.0.1 - which-typed-array: ^1.1.9 - checksum: 43730f7d8660ff9e33d1d3f9f9451c4784265ee7bf222babc35e61674a11a08e1c2925019d6c03154fcaaca4541df43abe35d2720843b9b4cbcebdcc31408f36 + which-boxed-primitive: ^1.1.0 + which-collection: ^1.0.2 + which-typed-array: ^1.1.16 + checksum: 7a3617ba0e7cafb795f74db418df889867d12bce39a477f3ee29c6092aa64d396955bf2a64eae3726d8578440e26777695544057b373c45a8bcf5fbe920bf633 languageName: node linkType: hard -"which-collection@npm:^1.0.1": +"which-collection@npm:^1.0.2": version: 1.0.2 resolution: "which-collection@npm:1.0.2" dependencies: @@ -20799,20 +22002,22 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": - version: 1.1.15 - resolution: "which-typed-array@npm:1.1.15" +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19": + version: 1.1.19 + resolution: "which-typed-array@npm:1.1.19" dependencies: available-typed-arrays: ^1.0.7 - call-bind: ^1.0.7 - for-each: ^0.3.3 - gopd: ^1.0.1 + call-bind: ^1.0.8 + call-bound: ^1.0.4 + for-each: ^0.3.5 + get-proto: ^1.0.1 + gopd: ^1.2.0 has-tostringtag: ^1.0.2 - checksum: 65227dcbfadf5677aacc43ec84356d17b5500cb8b8753059bb4397de5cd0c2de681d24e1a7bd575633f976a95f88233abfd6549c2105ef4ebd58af8aa1807c75 + checksum: 162d2a07f68ea323f88ed9419861487ce5d02cb876f2cf9dd1e428d04a63133f93a54f89308f337b27cabd312ee3d027cae4a79002b2f0a85b79b9ef4c190670 languageName: node linkType: hard -"which@npm:^1.2.9, which@npm:^1.3.1": +"which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" dependencies: @@ -20823,7 +22028,7 @@ __metadata: languageName: node linkType: hard -"which@npm:^2.0.1, which@npm:^2.0.2": +"which@npm:^2.0.1": version: 2.0.2 resolution: "which@npm:2.0.2" dependencies: @@ -20834,238 +22039,238 @@ __metadata: languageName: node linkType: hard -"which@npm:^4.0.0": - version: 4.0.0 - resolution: "which@npm:4.0.0" +"which@npm:^5.0.0": + version: 5.0.0 + resolution: "which@npm:5.0.0" dependencies: isexe: ^3.1.1 bin: node-which: bin/which.js - checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + checksum: 6ec99e89ba32c7e748b8a3144e64bfc74aa63e2b2eacbb61a0060ad0b961eb1a632b08fb1de067ed59b002cec3e21de18299216ebf2325ef0f78e0f121e14e90 languageName: node linkType: hard -"why-is-node-running@npm:^2.2.2": - version: 2.2.2 - resolution: "why-is-node-running@npm:2.2.2" +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" dependencies: siginfo: ^2.0.0 stackback: 0.0.2 bin: why-is-node-running: cli.js - checksum: 50820428f6a82dfc3cbce661570bcae9b658723217359b6037b67e495255409b4c8bc7931745f5c175df71210450464517cab32b2f7458ac9c40b4925065200a + checksum: 58ebbf406e243ace97083027f0df7ff4c2108baf2595bb29317718ef207cc7a8104e41b711ff65d6fa354f25daa8756b67f2f04931a4fd6ba9d13ae8197496fb languageName: node linkType: hard -"word-wrap@npm:~1.2.3": +"word-wrap@npm:^1.2.5, word-wrap@npm:~1.2.3": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" checksum: f93ba3586fc181f94afdaff3a6fef27920b4b6d9eaefed0f428f8e07adea2a7f54a5f2830ce59406c8416f033f86902b91eb824072354645eea687dff3691ccb languageName: node linkType: hard -"workbox-background-sync@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-background-sync@npm:5.1.4" +"workbox-background-sync@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-background-sync@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - checksum: 14655d0254813d2580935c88fe4768eb4794158a3c0700505aa06784dcd8d7498563e8b55152f0a4afb609163e76787a3a3eb61813b810bd76830c866d6ceb9e + idb: ^7.0.1 + workbox-core: 6.6.0 + checksum: ac2990110643aef62ca0be54e962296de7b09593b0262bd09fe4893978a42fa1f256c6d989ed472a31ae500b2255b80c6678530a6024eafb0b2f3a93a3c94a5f languageName: node linkType: hard -"workbox-broadcast-update@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-broadcast-update@npm:5.1.4" +"workbox-broadcast-update@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-broadcast-update@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - checksum: b56df2fde652c2efa8afbb8880562aaac6932be313ddcbbb688bb48beeb3164c928a644407f359168789a31592c765f63526608afe6cd803ac89402f786064d1 + workbox-core: 6.6.0 + checksum: 46a74b3b703244eb363e1731a2d6fe1fb2cd9b82d454733dfc6941fd35b76a852685f56db92408383ac50d564c2fd4282f0c6c4db60ba9beb5f311ea8f944dc7 languageName: node linkType: hard -"workbox-build@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-build@npm:5.1.4" - dependencies: - "@babel/core": ^7.8.4 - "@babel/preset-env": ^7.8.4 - "@babel/runtime": ^7.8.4 - "@hapi/joi": ^15.1.0 - "@rollup/plugin-node-resolve": ^7.1.1 - "@rollup/plugin-replace": ^2.3.1 - "@surma/rollup-plugin-off-main-thread": ^1.1.1 +"workbox-build@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-build@npm:6.6.0" + dependencies: + "@apideck/better-ajv-errors": ^0.3.1 + "@babel/core": ^7.11.1 + "@babel/preset-env": ^7.11.0 + "@babel/runtime": ^7.11.2 + "@rollup/plugin-babel": ^5.2.0 + "@rollup/plugin-node-resolve": ^11.2.1 + "@rollup/plugin-replace": ^2.4.1 + "@surma/rollup-plugin-off-main-thread": ^2.2.3 + ajv: ^8.6.0 common-tags: ^1.8.0 fast-json-stable-stringify: ^2.1.0 - fs-extra: ^8.1.0 + fs-extra: ^9.0.1 glob: ^7.1.6 - lodash.template: ^4.5.0 + lodash: ^4.17.20 pretty-bytes: ^5.3.0 - rollup: ^1.31.1 - rollup-plugin-babel: ^4.3.3 - rollup-plugin-terser: ^5.3.1 - source-map: ^0.7.3 - source-map-url: ^0.4.0 + rollup: ^2.43.1 + rollup-plugin-terser: ^7.0.0 + source-map: ^0.8.0-beta.0 stringify-object: ^3.3.0 - strip-comments: ^1.0.2 - tempy: ^0.3.0 + strip-comments: ^2.0.1 + tempy: ^0.6.0 upath: ^1.2.0 - workbox-background-sync: ^5.1.4 - workbox-broadcast-update: ^5.1.4 - workbox-cacheable-response: ^5.1.4 - workbox-core: ^5.1.4 - workbox-expiration: ^5.1.4 - workbox-google-analytics: ^5.1.4 - workbox-navigation-preload: ^5.1.4 - workbox-precaching: ^5.1.4 - workbox-range-requests: ^5.1.4 - workbox-routing: ^5.1.4 - workbox-strategies: ^5.1.4 - workbox-streams: ^5.1.4 - workbox-sw: ^5.1.4 - workbox-window: ^5.1.4 - checksum: 873833d0ea5c39c3f9adae9b2cd8ff33c013ff57f189dbec94d4d02917281495f38bbfa508d24425176ea8d31d6a27590658c83c30d44d9d5a9f4eb4d0798694 - languageName: node - linkType: hard - -"workbox-cacheable-response@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-cacheable-response@npm:5.1.4" + workbox-background-sync: 6.6.0 + workbox-broadcast-update: 6.6.0 + workbox-cacheable-response: 6.6.0 + workbox-core: 6.6.0 + workbox-expiration: 6.6.0 + workbox-google-analytics: 6.6.0 + workbox-navigation-preload: 6.6.0 + workbox-precaching: 6.6.0 + workbox-range-requests: 6.6.0 + workbox-recipes: 6.6.0 + workbox-routing: 6.6.0 + workbox-strategies: 6.6.0 + workbox-streams: 6.6.0 + workbox-sw: 6.6.0 + workbox-window: 6.6.0 + checksum: cd1a6c413659c2fd66f4438012f65b211cc748bb594c79bf0d9a60de0cefff3f8a4a23ab06f32c62064c37397ffffc1b77d3328658b7556ea7ff88e57f6ee4fd + languageName: node + linkType: hard + +"workbox-cacheable-response@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-cacheable-response@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - checksum: 3d8940dbee11880fdd86d76f85c063cf0a42d722be828332acf2f69ff5eaaedc8a0d779e44175adba4e8485f98392052539b2126df79125cebcec57dea0bee3c + workbox-core: 6.6.0 + checksum: 9e4e00c53679fd2020874cbdf54bb17560fd12353120ea08ca6213e5a11bf08139072616d79f5f8ab80d09f00efde94b003fe9bf5b6e23815be30d7aca760835 languageName: node linkType: hard -"workbox-core@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-core@npm:5.1.4" - checksum: 6062bc3131bb7fcf1922be619cbc28ba528b033ba18acced5e42eb62b6c0a763814e905106c081c1c100a5d520ef104957e99e592e5e954767df76db49a7c874 +"workbox-core@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-core@npm:6.6.0" + checksum: 7d773a866b73a733780c52b895f9cf7bec926c9187395c307174deefba9a0a2fcd1edce0d1ca12b8a6c95ca9cf7755ccc1885b03bc82ebcfc4843e015bd84d7b languageName: node linkType: hard -"workbox-expiration@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-expiration@npm:5.1.4" +"workbox-expiration@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-expiration@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - checksum: c4648a008d19ee1281d5d588e10f14bd01530d8601c6ebf27e63b109663530fd381709539f1dd8a32e75d68a04e40e5f31ec6fbcc9ea052ee39000a2d76ade50 + idb: ^7.0.1 + workbox-core: 6.6.0 + checksum: b100b9c512754bc3e1a9c7c7d20d215d72c601a7b956333ca7753704a771a9f00e1732e9b774da4549bae390dd3cd138c6392f6a25fd67f7dcd84f89b0df7e9c languageName: node linkType: hard -"workbox-google-analytics@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-google-analytics@npm:5.1.4" +"workbox-google-analytics@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-google-analytics@npm:6.6.0" dependencies: - workbox-background-sync: ^5.1.4 - workbox-core: ^5.1.4 - workbox-routing: ^5.1.4 - workbox-strategies: ^5.1.4 - checksum: 2783e93f8a5aeccc038f51a9960c05aebd104fd8d113b5fd78a09bac2da8ed8e2be4c9fd7d8a6751682301d6b5e36ba055240a74a3591b4e887aabb2784cd531 + workbox-background-sync: 6.6.0 + workbox-core: 6.6.0 + workbox-routing: 6.6.0 + workbox-strategies: 6.6.0 + checksum: 7b287da7517ae416aae8ea1494830bb517a29ab9786b2a8b8bf98971377b83715070e784399065ab101d4bba381ab0abbb8bd0962b3010bc01f54fdafb0b6702 languageName: node linkType: hard -"workbox-navigation-preload@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-navigation-preload@npm:5.1.4" +"workbox-navigation-preload@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-navigation-preload@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - checksum: ed6b19f063f17e2dd12ef08594ea338fcf96d994ea8f7d9b2987099cb08a890c73f139a23b68c9c5523308fba4634f24aca079deb7d00684c8d76fdfb07b0fc9 + workbox-core: 6.6.0 + checksum: d254465648e45ec6b6d7c3471354336501901d3872622ea9ba1aa1f935d4d52941d0f92fa6c06e7363e10dbac4874d5d4bff7d99cbe094925046f562a37e88cc languageName: node linkType: hard -"workbox-precaching@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-precaching@npm:5.1.4" +"workbox-precaching@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-precaching@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - checksum: 5593c5b9c3c928bb5d3b4c998625be610d05a3b55523e5abb0fc5f12ff2e32412114e933e60d54ba9e2661fa3cbbbab7e11f91c7170742cfe9525437d1c44ae8 + workbox-core: 6.6.0 + workbox-routing: 6.6.0 + workbox-strategies: 6.6.0 + checksum: 62e5ee2e40568a56d4131bba461623579f56b9bd273aa7d2805e43151057f413c2ef32fb3d007aff0a5ac3ad84d5feae87408284249a487a5d51c3775c46c816 languageName: node linkType: hard -"workbox-range-requests@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-range-requests@npm:5.1.4" +"workbox-range-requests@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-range-requests@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - checksum: c67b467023e85a45599c411079907585c4d4b7aab77205dd905cd0d8b1487aa248469bc2f89045e8bd4a08eed4ede14795fc9089d01beff65ff3c6f2f1deff45 + workbox-core: 6.6.0 + checksum: a55d1a364b2155548695dc8f6f85baade196d7d1bec980bcdbda80236803b14167995a81b944cffe932a94c4d556466773121afe3661a6f0a13403cbe96d8d9f languageName: node linkType: hard -"workbox-routing@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-routing@npm:5.1.4" +"workbox-recipes@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-recipes@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - checksum: 4199a02b433eb645dfcaf2a5056a04d79f337b6f368b1ab5aa18262857835d4b995536062c294d6f4db6da236235b5736af4b29d0ea1b0c3f0db339b04d3cd40 + workbox-cacheable-response: 6.6.0 + workbox-core: 6.6.0 + workbox-expiration: 6.6.0 + workbox-precaching: 6.6.0 + workbox-routing: 6.6.0 + workbox-strategies: 6.6.0 + checksum: f2ecf38502260703e4b0dcef67e3ac26d615f2c90f6d863ca7308db52454f67934ba842fd577ee807d9f510f1a277fd66af7caf57d39e50a181d05dbb3e550a7 languageName: node linkType: hard -"workbox-strategies@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-strategies@npm:5.1.4" +"workbox-routing@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-routing@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - workbox-routing: ^5.1.4 - checksum: 6ed247bfc0037331043cd0e772c6fd8d48e487875fac75d6692eb3936536ca2d4ac5ac9d12ec9b0ad5eefd4a69afd1ad2a993829ce3a373390880a019fd33d3d + workbox-core: 6.6.0 + checksum: 7a70b836196eb67332d33a94c0b57859781fe869e81a9c95452d3f4f368d3199f8c3da632dbc10425fde902a1930cf8cfd83f6434ad2b586904ce68cd9f35c6d languageName: node linkType: hard -"workbox-streams@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-streams@npm:5.1.4" +"workbox-strategies@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-strategies@npm:6.6.0" dependencies: - workbox-core: ^5.1.4 - workbox-routing: ^5.1.4 - checksum: daaedb22dae6eb4723e7a21d758854adb36b75f1fa2453a914b6768628d91555e3db76fccb70a101f5cf1a39056e783eab1c8b0f4a59649f7ef4fad173c6f7d3 - languageName: node - linkType: hard - -"workbox-sw@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-sw@npm:5.1.4" - checksum: eda970f62c26715b806828cab3000240843bab2e6577c341ccd30747a77a60d23f4f08d8d85fba680bfefa95c673c4d48a62a969a2540916dcf6506c627c69cc + workbox-core: 6.6.0 + checksum: 236232a77fb4a4847d1e9ae6c7c9bd9c6b9449209baab9d8d90f78240326a9c0f69551b408ebf9e76610d86da15563bf27439b7e885a7bac01dfd08047c0dd7b languageName: node linkType: hard -"workbox-webpack-plugin@npm:5.1.4": - version: 5.1.4 - resolution: "workbox-webpack-plugin@npm:5.1.4" +"workbox-streams@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-streams@npm:6.6.0" dependencies: - "@babel/runtime": ^7.5.5 - fast-json-stable-stringify: ^2.0.0 - source-map-url: ^0.4.0 - upath: ^1.1.2 - webpack-sources: ^1.3.0 - workbox-build: ^5.1.4 - peerDependencies: - webpack: ^4.0.0 - checksum: 7a9093d4ccfedc27ee6716443bcb7ce12d1f92831f48d09e6cf829a62d2ba7948a84ed38964923136d6b296e8f60bda359645a82c5a19e2c5a8e8aab6dae0a55 + workbox-core: 6.6.0 + workbox-routing: 6.6.0 + checksum: 64a295e48e44e3fa4743b5baec646fc9117428e7592033475e38c461e45c294910712f322c32417d354b22999902ef8035119e070e61e159e531d878d991fc33 languageName: node linkType: hard -"workbox-window@npm:^5.1.4": - version: 5.1.4 - resolution: "workbox-window@npm:5.1.4" - dependencies: - workbox-core: ^5.1.4 - checksum: bd5bc967ea1202c555db4360892518f5479027d05e4bd02fd38ebef3faf6605ee7e3887225e0920624cd2685e5217c3c4bd43a7d458860d186400c12f410df5b +"workbox-sw@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-sw@npm:6.6.0" + checksum: bb5f8695de02f89c7955465dcbd568299915565008dc8a068c5d19c1347f75d417640b9f61590e16b169b703e77d02f8b1e10c4b241f74f43cfe76175bfa5fed languageName: node linkType: hard -"worker-farm@npm:^1.7.0": - version: 1.7.0 - resolution: "worker-farm@npm:1.7.0" +"workbox-webpack-plugin@npm:^6.4.1": + version: 6.6.0 + resolution: "workbox-webpack-plugin@npm:6.6.0" dependencies: - errno: ~0.1.7 - checksum: eab917530e1feddf157ec749e9c91b73a886142daa7fdf3490bccbf7b548b2576c43ab8d0a98e72ac755cbc101ca8647a7b1ff2485fddb9e8f53c40c77f5a719 + fast-json-stable-stringify: ^2.1.0 + pretty-bytes: ^5.4.1 + upath: ^1.2.0 + webpack-sources: ^1.4.3 + workbox-build: 6.6.0 + peerDependencies: + webpack: ^4.4.0 || ^5.9.0 + checksum: b8e04a342f2d45086f28ae56e4806d74dd153c3b750855533a55954f4e85752113e76a6d79a32206eb697a342725897834c9e7976894374d8698cd950477d37a languageName: node linkType: hard -"worker-rpc@npm:^0.1.0": - version: 0.1.1 - resolution: "worker-rpc@npm:0.1.1" +"workbox-window@npm:6.6.0": + version: 6.6.0 + resolution: "workbox-window@npm:6.6.0" dependencies: - microevent.ts: ~0.1.1 - checksum: 8f8607506172f44c05490f3ccf13e5c1f430eeb9b6116a405919c186b8b17add13bbb22467a0dbcd18ec7fcb080709a15738182e0003c5fbe2144721ea00f357 + "@types/trusted-types": ^2.0.2 + workbox-core: 6.6.0 + checksum: bb1dd031c1525317ceffbdc3e4f502a70dce461fd6355146e1050c1090f3c640bf65edf42a5d2a3b91b4d0c313df32c1405d88bf701d44c0e3ebc492cd77fe14 languageName: node linkType: hard @@ -21080,18 +22285,7 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^5.1.0": - version: 5.1.0 - resolution: "wrap-ansi@npm:5.1.0" - dependencies: - ansi-styles: ^3.2.0 - string-width: ^3.0.0 - strip-ansi: ^5.0.0 - checksum: 9b48c862220e541eb0daa22661b38b947973fc57054e91be5b0f2dcc77741a6875ccab4ebe970a394b4682c8dfc17e888266a105fb8b0a9b23c19245e781ceae - languageName: node - linkType: hard - -"wrap-ansi@npm:^6.0.1, wrap-ansi@npm:^6.2.0": +"wrap-ansi@npm:^6.2.0": version: 6.2.0 resolution: "wrap-ansi@npm:6.2.0" dependencies: @@ -21132,27 +22326,33 @@ __metadata: languageName: node linkType: hard -"ws@npm:^6.2.1": - version: 6.2.2 - resolution: "ws@npm:6.2.2" - dependencies: - async-limiter: ~1.0.0 - checksum: aec3154ec51477c094ac2cb5946a156e17561a581fa27005cbf22c53ac57f8d4e5f791dd4bbba6a488602cb28778c8ab7df06251d590507c3c550fd8ebeee949 +"ws@npm:^7.4.6": + version: 7.5.10 + resolution: "ws@npm:7.5.10" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: f9bb062abf54cc8f02d94ca86dcd349c3945d63851f5d07a3a61c2fcb755b15a88e943a63cf580cbdb5b74436d67ef6b67f745b8f7c0814e411379138e1863cb languageName: node linkType: hard -"ws@npm:^7.4.6": - version: 7.5.9 - resolution: "ws@npm:7.5.9" +"ws@npm:^8.13.0": + version: 8.18.3 + resolution: "ws@npm:8.18.3" peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 + utf-8-validate: ">=5.0.2" peerDependenciesMeta: bufferutil: optional: true utf-8-validate: optional: true - checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 + checksum: d64ef1631227bd0c5fe21b3eb3646c9c91229402fb963d12d87b49af0a1ef757277083af23a5f85742bae1e520feddfb434cb882ea59249b15673c16dc3f36e0 languageName: node linkType: hard @@ -21170,7 +22370,7 @@ __metadata: languageName: node linkType: hard -"xtend@npm:^4.0.0, xtend@npm:~4.0.1": +"xtend@npm:^4.0.0": version: 4.0.2 resolution: "xtend@npm:4.0.2" checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a @@ -21205,27 +22405,26 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^1.10.0": - version: 1.10.2 - resolution: "yaml@npm:1.10.2" - checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: eba51182400b9f35b017daa7f419f434424410691bbc5de4f4240cc830fdef906b504424992700dc047f16b4d99100a6f8b8b11175c193f38008e9c96322b6a5 languageName: node linkType: hard -"yargs-parser@npm:20.x": - version: 20.2.9 - resolution: "yargs-parser@npm:20.2.9" - checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 +"yaml@npm:^1.10.0, yaml@npm:^1.10.2, yaml@npm:^1.7.2": + version: 1.10.2 + resolution: "yaml@npm:1.10.2" + checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f languageName: node linkType: hard -"yargs-parser@npm:^13.1.2": - version: 13.1.2 - resolution: "yargs-parser@npm:13.1.2" - dependencies: - camelcase: ^5.0.0 - decamelize: ^1.2.0 - checksum: c8bb6f44d39a4acd94462e96d4e85469df865de6f4326e0ab1ac23ae4a835e5dd2ddfe588317ebf80c3a7e37e741bd5cb0dc8d92bcc5812baefb7df7c885e86b +"yaml@npm:^2.3.4": + version: 2.8.1 + resolution: "yaml@npm:2.8.1" + bin: + yaml: bin.mjs + checksum: 35b46150d48bc1da2fd5b1521a48a4fa36d68deaabe496f3c3fa9646d5796b6b974f3930a02c4b5aee6c85c860d7d7f79009416724465e835f40b87898c36de4 languageName: node linkType: hard @@ -21239,6 +22438,13 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^20.2.2": + version: 20.2.9 + resolution: "yargs-parser@npm:20.2.9" + checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 + languageName: node + linkType: hard + "yargs-parser@npm:^21.1.1": version: 21.1.1 resolution: "yargs-parser@npm:21.1.1" @@ -21246,25 +22452,22 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^13.3.0, yargs@npm:^13.3.2": - version: 13.3.2 - resolution: "yargs@npm:13.3.2" +"yargs@npm:17.7.2, yargs@npm:^17.3.1, yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" dependencies: - cliui: ^5.0.0 - find-up: ^3.0.0 - get-caller-file: ^2.0.1 + cliui: ^8.0.1 + escalade: ^3.1.1 + get-caller-file: ^2.0.5 require-directory: ^2.1.1 - require-main-filename: ^2.0.0 - set-blocking: ^2.0.0 - string-width: ^3.0.0 - which-module: ^2.0.0 - y18n: ^4.0.0 - yargs-parser: ^13.1.2 - checksum: 75c13e837eb2bb25717957ba58d277e864efc0cca7f945c98bdf6477e6ec2f9be6afa9ed8a876b251a21423500c148d7b91e88dee7adea6029bdec97af1ef3e8 + string-width: ^4.2.3 + y18n: ^5.0.5 + yargs-parser: ^21.1.1 + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a languageName: node linkType: hard -"yargs@npm:^15.4.1": +"yargs@npm:^15.3.1": version: 15.4.1 resolution: "yargs@npm:15.4.1" dependencies: @@ -21283,18 +22486,18 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.3.1": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" +"yargs@npm:^16.2.0": + version: 16.2.0 + resolution: "yargs@npm:16.2.0" dependencies: - cliui: ^8.0.1 + cliui: ^7.0.2 escalade: ^3.1.1 get-caller-file: ^2.0.5 require-directory: ^2.1.1 - string-width: ^4.2.3 + string-width: ^4.2.0 y18n: ^5.0.5 - yargs-parser: ^21.1.1 - checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + yargs-parser: ^20.2.2 + checksum: b14afbb51e3251a204d81937c86a7e9d4bdbf9a2bcee38226c900d00f522969ab675703bee2a6f99f8e20103f608382936034e64d921b74df82b63c07c5e8f59 languageName: node linkType: hard @@ -21312,24 +22515,28 @@ __metadata: languageName: node linkType: hard -"yocto-queue@npm:^1.0.0": - version: 1.0.0 - resolution: "yocto-queue@npm:1.0.0" - checksum: 2cac84540f65c64ccc1683c267edce396b26b1e931aa429660aefac8fbe0188167b7aee815a3c22fa59a28a58d898d1a2b1825048f834d8d629f4c2a5d443801 +"yoctocolors-cjs@npm:^2.1.2": + version: 2.1.3 + resolution: "yoctocolors-cjs@npm:2.1.3" + checksum: 207df586996c3b604fa85903f81cc54676f1f372613a0c7247f0d24b1ca781905685075d06955211c4d5d4f629d7d5628464f8af0a42d286b7a8ff88e9dadcb8 languageName: node linkType: hard -"yup@npm:^0.32.11": - version: 0.32.11 - resolution: "yup@npm:0.32.11" +"yup@npm:^1.6.1": + version: 1.7.0 + resolution: "yup@npm:1.7.0" dependencies: - "@babel/runtime": ^7.15.4 - "@types/lodash": ^4.14.175 - lodash: ^4.17.21 - lodash-es: ^4.17.21 - nanoclone: ^0.2.1 - property-expr: ^2.0.4 + property-expr: ^2.0.5 + tiny-case: ^1.0.3 toposort: ^2.0.2 - checksum: 43a16786b47cc910fed4891cebdd89df6d6e31702e9462e8f969c73eac88551ce750732608012201ea6b93802c8847cb0aa27b5d57370640f4ecf30f9f97d4b0 + type-fest: ^2.19.0 + checksum: 845f4bb66df547208c1906a15d03a0cd838789dc22fa9ae948247752f360b273834f7d607176285d8c11779bb143640c65ae5f8f4045351505b17413a183aea9 + languageName: node + linkType: hard + +"zwitch@npm:^2.0.0": + version: 2.0.4 + resolution: "zwitch@npm:2.0.4" + checksum: f22ec5fc2d5f02c423c93d35cdfa83573a3a3bd98c66b927c368ea4d0e7252a500df2a90a6b45522be536a96a73404393c958e945fdba95e6832c200791702b6 languageName: node linkType: hard From b435a04cddeb7bf0adadd0a7e2fb97fb6eceac2f Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Tue, 16 Sep 2025 11:01:43 -0400 Subject: [PATCH 042/477] no lock --- src/backend/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/backend/index.ts b/src/backend/index.ts index 10b4e921ff..ffe251ec65 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -25,7 +25,6 @@ import statisticsRouter from './src/routes/statistics.routes'; import retrospectiveRouter from './src/routes/retrospective.routes'; import partsRouter from './src/routes/parts.routes'; import financeRouter from './src/routes/finance.routes'; -import shopRouter from './src/routes/shop.routes'; const app = express(); @@ -88,7 +87,6 @@ app.use('/statistics', statisticsRouter); app.use('/retrospective', retrospectiveRouter); app.use('/parts', partsRouter); app.use('/finance', financeRouter); -app.use('/shops', shopRouter); app.use('/', (_req, res) => { res.status(200).json('Welcome to FinishLine'); }); From de1814c0127019109a66b3b9ed4457ff63896a24 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 16 Sep 2025 13:12:15 -0400 Subject: [PATCH 043/477] #3555 done --- .../src/controllers/calendar.controllers.ts | 1 + .../event-type.query-args.ts | 11 +++ .../20250904214316_calendar/migration.sql | 1 + src/backend/src/prisma/schema.prisma | 1 + src/backend/src/prisma/seed.ts | 85 +++++++++++++++++++ src/backend/src/routes/calendar.routes.ts | 3 +- src/backend/src/services/calendar.services.ts | 7 +- .../src/transformers/calendar.transformer.ts | 22 ++++- src/backend/tests/test-utils.ts | 2 + src/backend/tests/unit/calendar.test.ts | 73 ++++++++++++++++ src/shared/src/types/calendar-types.ts | 30 +++++++ 11 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 src/backend/src/prisma-query-args/event-type.query-args.ts create mode 100644 src/backend/tests/unit/calendar.test.ts diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 2c81d4c365..1ffca82527 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -17,6 +17,7 @@ export default class CalendarController { shop, machinery, workPackage, + questionDocument, documents, description } = req.body; diff --git a/src/backend/src/prisma-query-args/event-type.query-args.ts b/src/backend/src/prisma-query-args/event-type.query-args.ts new file mode 100644 index 0000000000..f8ee59fac5 --- /dev/null +++ b/src/backend/src/prisma-query-args/event-type.query-args.ts @@ -0,0 +1,11 @@ +import { Prisma } from '@prisma/client'; +import { getUserQueryArgs } from './user.query-args'; + +export type EventTypeQueryArgs = ReturnType; + +export const getEventTypeQueryArgs = (organizationId: string) => + Prisma.validator()({ + include: { + userCreated: getUserQueryArgs(organizationId) + } + }); diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index 9c6c8f6c37..74043a0da0 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -104,6 +104,7 @@ CREATE TABLE "public"."EventType" ( "shop" BOOLEAN, "machinery" BOOLEAN, "workPackage" BOOLEAN, + "questionDocument" BOOLEAN, "documents" BOOLEAN, "description" BOOLEAN, diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 8f3cb5c732..7a443a7eca 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1001,6 +1001,7 @@ model EventType { shop Boolean? machinery Boolean? workPackage Boolean? + questionDocument Boolean? documents Boolean? description Boolean? events Event[] diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index a002745e4a..15ca712b1b 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -50,6 +50,8 @@ import AnnouncementService from '../services/announcement.services'; import OnboardingServices from '../services/onboarding.services'; import { dbSeedAllParts, dbSeedAllPartTags } from './seed-data/parts.seed'; import FinanceServices from '../services/finance.services'; +import CalendarService from '../services/calendar.services'; +import { truncateByDomain } from 'recharts/types/util/ChartUtils'; const prisma = new PrismaClient(); @@ -3059,6 +3061,89 @@ const performSeed: () => Promise = async () => { new Date(7, 5, 25), thomasEmrax.userId ); + + // meeting event type + await CalendarService.createEventType( + thomasEmrax, + 'Meeting', + [], + ner, + true, + true, + true, + true, + true, + true, + false, + false, + false, + true, + true, + true + ); + + // design review event type + await CalendarService.createEventType( + thomasEmrax, + 'Design Review', + [], + ner, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + true, + true, + true + ); + + // manufacturing event type + await CalendarService.createEventType( + thomasEmrax, + 'Manufacturing', + [], + ner, + true, + false, + false, + true, + false, + false, + false, + true, + true, + true, + false, + false, + true + ); + + // bay time event type + await CalendarService.createEventType( + thomasEmrax, + 'Bay Time', + [], + ner, + true, + true, + true, + true, + false, + false, + false, + true, + false, + true, + false, + false, + true + ); }; performSeed() diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index cc17586b96..49250463f3 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,6 +1,6 @@ import express from 'express'; import { body } from 'express-validator'; -import { nonEmptyString, validateInputs } from '../utils/validation.utils'; +import { nonEmptyString } from '../utils/validation.utils'; const calendarRouter = express.Router(); @@ -18,6 +18,7 @@ calendarRouter.post( body('shop').isBoolean().optional, body('machinery').isBoolean().optional, body('workPackage').isBoolean().optional, + body('questionDocument').isBoolean().optional, body('documents').isBoolean().optional, body('description').isBoolean().optional ); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 92d6cec106..f75c116755 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -4,6 +4,7 @@ import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; +import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; export default class CalendarService { /** @@ -23,6 +24,7 @@ export default class CalendarService { * @param shop Determines if a shop is associated with this event type. * @param machinery Determines if machinery is associated with this event type. * @param workPackage Determines if a work package is associated with this event type. + * @param questionDocument Determines if a question document is associated with this event type. * @param documents Determines if documents are associates with this event type. * @param description Determines if a description is associated with this event type. * @@ -45,6 +47,7 @@ export default class CalendarService { shop?: boolean, machinery?: boolean, workPackage?: boolean, + questionDocument?: boolean, documents?: boolean, description?: boolean ): Promise { @@ -69,9 +72,11 @@ export default class CalendarService { shop, machinery, workPackage, + questionDocument, documents, description - } + }, + ...getEventTypeQueryArgs(organization.organizationId) }); return eventTypeTransformer(newEventType); diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index bd2c57cc97..a5801e4353 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -1,8 +1,26 @@ import { Prisma } from '@prisma/client'; import { EventType } from 'shared'; +import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; +import { userTransformer } from './user.transformer'; -export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload): EventType => { +export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload): EventType => { return { - name: eventType.name + eventTypeId: eventType.eventTypeId, + name: eventType.name, + userCreated: userTransformer(eventType.userCreated), + dateCreated: eventType.dateCreated, + initialDateScheduled: eventType.initialDateScheduled ?? undefined, + allDay: eventType.allDay ?? undefined, + recurring: eventType.recurring ?? undefined, + members: eventType.members ?? undefined, + location: eventType.location ?? undefined, + zoomLink: eventType.zoomLink ?? undefined, + availability: eventType.availabilities ?? undefined, + shop: eventType.shop ?? undefined, + machinery: eventType.machinery ?? undefined, + workPackage: eventType.workPackage ?? undefined, + questionDocument: eventType.questionDocument ?? undefined, + documents: eventType.documents ?? undefined, + description: eventType.description ?? undefined }; }; diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index 68e35ff3db..ad07ef502e 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -166,6 +166,8 @@ export const resetUsers = async () => { await prisma.account_Code.deleteMany(); await prisma.refund_Source.deleteMany(); await prisma.index_Code.deleteMany(); + await prisma.eventType.deleteMany(); + await prisma.calendar.deleteMany(); await prisma.organization.deleteMany(); await prisma.user.deleteMany(); }; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts new file mode 100644 index 0000000000..c84dcf23aa --- /dev/null +++ b/src/backend/tests/unit/calendar.test.ts @@ -0,0 +1,73 @@ +import { Organization } from '@prisma/client'; +import CalendarService from '../../src/services/calendar.services'; +import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; +import { batmanAppAdmin, wonderwomanGuest } from '../test-data/users.test-data'; +import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; + +describe('Calendar Tests', () => { + let orgId: string; + let organization: Organization; + + beforeEach(async () => { + organization = await createTestOrganization(); + orgId = organization.organizationId; + }); + + afterEach(async () => { + await resetUsers(); + }); + + describe('Create EventType', () => { + it('Fails if user is not an admin', async () => { + await expect( + async () => + await CalendarService.createEventType( + await createTestUser(wonderwomanGuest, orgId), + 'Team Meeting', + [], + organization, + true, + false, + true + ) + ).rejects.toThrow(new AccessDeniedAdminOnlyException('create event type')); + }); + + it('Succeeds and creates an event type', async () => { + const result = await CalendarService.createEventType( + await createTestUser(batmanAppAdmin, orgId), + 'Team Meeting', + [], + organization, + true, + false, + true, + true, + true, + false, + true, + false, + false, + false, + false, + false, + true + ); + + expect(result.name).toEqual('Team Meeting'); + expect(result.initialDateScheduled).toBe(true); + expect(result.recurring).toBe(false); + expect(result.allDay).toBe(true); + expect(result.members).toBe(true); + expect(result.location).toBe(true); + expect(result.zoomLink).toBe(false); + expect(result.availability).toBe(true); + expect(result.shop).toBe(false); + expect(result.machinery).toBe(false); + expect(result.workPackage).toBe(false); + expect(result.questionDocument).toBe(false); + expect(result.documents).toBe(false); + expect(result.description).toBe(true); + }); + }); +}); diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 4ca68ccfc9..fb14fabd78 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -2,9 +2,12 @@ import { WorkPackage } from './project-types'; import { Availability, User } from './user-types'; export interface Calendar { + calendarId: string; name: string; description: string; color: string; + userCreated: User; + dateCreated: Date; eventTypes: EventType[]; } @@ -19,6 +22,7 @@ export enum DayOfWeek { } export interface ScheduleSlot { + scheduleSlotId: string; days: DayOfWeek[]; startTime?: Date; endTime?: Date; @@ -28,28 +32,54 @@ export interface ScheduleSlot { } export interface EventType { + eventTypeId: string; name: string; + userCreated: User; + dateCreated: Date; + initialDateScheduled?: boolean; + allDay?: boolean; + recurring?: boolean; + members?: boolean; + location?: boolean; + zoomLink?: boolean; + availability?: boolean; + shop?: boolean; + machinery?: boolean; + workPackage?: boolean; + questionDocument?: boolean; + documents?: boolean; + description?: boolean; } export interface Shop { + shopId: string; name: string; description: string; + userCreated: User; + dateCreated: Date; } export interface ShopMachinery { + shopMachineryId: string; shop: Shop; quantity: number; description?: string; } export interface Machinery { + machineryId: string; name: string; + userCreated: User; + dateCreated: Date; shops: ShopMachinery[]; } export interface Event { + eventId: string; name: string; approved: boolean; + userCreated: User; + dateCreated: Date; eventTypeId: string; approvedBy?: User; scheduledTimes?: ScheduleSlot[]; From 2ab713e57295225d896c9e3a5192d53ad16e8b6d Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 16 Sep 2025 13:15:01 -0400 Subject: [PATCH 044/477] #3555 linting --- src/backend/src/controllers/calendar.controllers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 1ffca82527..0ea389bdc1 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -37,6 +37,7 @@ export default class CalendarController { shop, machinery, workPackage, + questionDocument, documents, description ); From d151ee7ef229916b978534f865374159849b152f Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 16 Sep 2025 18:29:14 -0400 Subject: [PATCH 045/477] #3555 final touches --- .../src/controllers/calendar.controllers.ts | 4 +-- src/backend/src/prisma/seed.ts | 10 ++++++ src/backend/src/routes/calendar.routes.ts | 33 ++++++++++--------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 0ea389bdc1..4bc7f495c8 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -6,7 +6,7 @@ export default class CalendarController { try { const { name, - calendarId, + calendarIds, initialDateScheduled, recurring, allDay, @@ -25,7 +25,7 @@ export default class CalendarController { const eventType = await CalendarService.createEventType( req.currentUser, name, - calendarId, + calendarIds, req.organization, initialDateScheduled, recurring, diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 15ca712b1b..f8e877d18a 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3062,6 +3062,16 @@ const performSeed: () => Promise = async () => { thomasEmrax.userId ); + const calendar = await prisma.calendar.create({ + data: { + name: 'Engineering Team Calendar', + description: 'Tracks all engineering team events, meetings, and deadlines.', + colorHexCode: '#3498db', + userCreated: { connect: { userId: thomasEmrax.userId } }, + dateCreated: new Date() + } + }); + // meeting event type await CalendarService.createEventType( thomasEmrax, diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 49250463f3..91f40bdccb 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,26 +1,29 @@ import express from 'express'; import { body } from 'express-validator'; -import { nonEmptyString } from '../utils/validation.utils'; +import { nonEmptyString, validateInputs } from '../utils/validation.utils'; +import CalendarController from '../controllers/calendar.controllers'; const calendarRouter = express.Router(); calendarRouter.post( '/event-type/create', nonEmptyString(body('name')), - body('calendarIds').isArray, - body('initialDateScheduled').isBoolean().optional, - body('allDay').isBoolean().optional, - body('recurring').isBoolean().optional, - body('members').isBoolean().optional, - body('location').isBoolean().optional, - body('zoomLink').isBoolean().optional, - body('availabilities').isBoolean().optional, - body('shop').isBoolean().optional, - body('machinery').isBoolean().optional, - body('workPackage').isBoolean().optional, - body('questionDocument').isBoolean().optional, - body('documents').isBoolean().optional, - body('description').isBoolean().optional + body('calendarIds').isArray(), + body('initialDateScheduled').isBoolean().optional(), + body('allDay').isBoolean().optional(), + body('recurring').isBoolean().optional(), + body('members').isBoolean().optional(), + body('location').isBoolean().optional(), + body('zoomLink').isBoolean().optional(), + body('availabilities').isBoolean().optional(), + body('shop').isBoolean().optional(), + body('machinery').isBoolean().optional(), + body('workPackage').isBoolean().optional(), + body('questionDocument').isBoolean().optional(), + body('documents').isBoolean().optional(), + body('description').isBoolean().optional(), + validateInputs, + CalendarController.createEventType ); export default calendarRouter; From 2abc7b54ae0be7cee9fe2fa6f3159e53aef2f884 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Wed, 17 Sep 2025 12:04:00 -0400 Subject: [PATCH 046/477] #3555 update services --- src/backend/src/services/calendar.services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index f75c116755..31c5ed36f5 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -61,7 +61,7 @@ export default class CalendarService { calendars: { connect: calendarIds.map((calendarId) => ({ calendarId })) }, - userCreated: { connect: { userId: submitter.userId } }, + userCreatedId: submitter.userId, initialDateScheduled, recurring, allDay, From 98137cf38fb693e6bd3acf2e40e4c919a222cde6 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 17 Sep 2025 13:35:10 -0400 Subject: [PATCH 047/477] Fixing the yarn.lock --- src/backend/index.ts | 2 + yarn.lock | 2453 ++++++++++++------------------------------ 2 files changed, 706 insertions(+), 1749 deletions(-) diff --git a/src/backend/index.ts b/src/backend/index.ts index ffe251ec65..10b4e921ff 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -25,6 +25,7 @@ import statisticsRouter from './src/routes/statistics.routes'; import retrospectiveRouter from './src/routes/retrospective.routes'; import partsRouter from './src/routes/parts.routes'; import financeRouter from './src/routes/finance.routes'; +import shopRouter from './src/routes/shop.routes'; const app = express(); @@ -87,6 +88,7 @@ app.use('/statistics', statisticsRouter); app.use('/retrospective', retrospectiveRouter); app.use('/parts', partsRouter); app.use('/finance', financeRouter); +app.use('/shops', shopRouter); app.use('/', (_req, res) => { res.status(200).json('Welcome to FinishLine'); }); diff --git a/yarn.lock b/yarn.lock index 8e4ee5ee83..c82e2a9721 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6,9 +6,9 @@ __metadata: cacheKey: 8 "@adobe/css-tools@npm:^4.4.0": - version: 4.4.4 - resolution: "@adobe/css-tools@npm:4.4.4" - checksum: 452b82cd9f42aacc57eeaf0b11e36c6864eb482e8a347054cb986503d221d1f7c1418710d2007858d8919afdbd31357149c2c16bd080ded15506f13608d16cf2 + version: 4.4.3 + resolution: "@adobe/css-tools@npm:4.4.3" + checksum: 8c773f624d7327cdc58e92ab9077500f4578b24eee9f504e7925a775df6885cd534399c40c1a2919e38cbd57c0023d5bf9e32f8b89ed783733f706366b0f61e6 languageName: node linkType: hard @@ -19,6 +19,16 @@ __metadata: languageName: node linkType: hard +"@ampproject/remapping@npm:^2.2.0": + version: 2.3.0 + resolution: "@ampproject/remapping@npm:2.3.0" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: d3ad7b89d973df059c4e8e6d7c972cbeb1bb2f18f002a3bd04ae0707da214cb06cc06929b65aa2313b9347463df2914772298bae8b1d7973f246bb3f2ab3e8f0 + languageName: node + linkType: hard + "@apideck/better-ajv-errors@npm:^0.3.1": version: 0.3.6 resolution: "@apideck/better-ajv-errors@npm:0.3.6" @@ -32,490 +42,6 @@ __metadata: languageName: node linkType: hard -"@aws-crypto/sha256-browser@npm:5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/sha256-browser@npm:5.2.0" - dependencies: - "@aws-crypto/sha256-js": ^5.2.0 - "@aws-crypto/supports-web-crypto": ^5.2.0 - "@aws-crypto/util": ^5.2.0 - "@aws-sdk/types": ^3.222.0 - "@aws-sdk/util-locate-window": ^3.0.0 - "@smithy/util-utf8": ^2.0.0 - tslib: ^2.6.2 - checksum: 773f12f2026d82a6bb4a23a8f491894a6d32525bd9b8bfbc12896526cf11882a7607a671c478c45f9cd7d6ba1caaed48a62b67c6f725244bd83a1275108f46c7 - languageName: node - linkType: hard - -"@aws-crypto/sha256-js@npm:5.2.0, @aws-crypto/sha256-js@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/sha256-js@npm:5.2.0" - dependencies: - "@aws-crypto/util": ^5.2.0 - "@aws-sdk/types": ^3.222.0 - tslib: ^2.6.2 - checksum: 007fbe0436d714d0d0d282e2b61c90e45adcb9ad75eac9ac7ba03d32b56624afd09b2a9ceb4d659661cf17c51d74d1900ab6b00eacafc002da1101664955ca53 - languageName: node - linkType: hard - -"@aws-crypto/supports-web-crypto@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/supports-web-crypto@npm:5.2.0" - dependencies: - tslib: ^2.6.2 - checksum: 6ffc21de48b2b2c3e918193101d7e8fe949d47b37688892e1c39eaedaa938be80c0f404fe1c874c30cce16781026777a53bf47d5d90143ca91d0feb7c4a6f830 - languageName: node - linkType: hard - -"@aws-crypto/util@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/util@npm:5.2.0" - dependencies: - "@aws-sdk/types": ^3.222.0 - "@smithy/util-utf8": ^2.0.0 - tslib: ^2.6.2 - checksum: f0f81d9d2771c59946cfec48b86cb23d39f78a966c4a1f89d4753abdc3cb38de06f907d1e6450059b121d48ac65d612ab88bdb70014553a077fc3dabddfbf8d6 - languageName: node - linkType: hard - -"@aws-sdk/client-ses@npm:^3.731.1": - version: 3.888.0 - resolution: "@aws-sdk/client-ses@npm:3.888.0" - dependencies: - "@aws-crypto/sha256-browser": 5.2.0 - "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.888.0 - "@aws-sdk/credential-provider-node": 3.888.0 - "@aws-sdk/middleware-host-header": 3.887.0 - "@aws-sdk/middleware-logger": 3.887.0 - "@aws-sdk/middleware-recursion-detection": 3.887.0 - "@aws-sdk/middleware-user-agent": 3.888.0 - "@aws-sdk/region-config-resolver": 3.887.0 - "@aws-sdk/types": 3.887.0 - "@aws-sdk/util-endpoints": 3.887.0 - "@aws-sdk/util-user-agent-browser": 3.887.0 - "@aws-sdk/util-user-agent-node": 3.888.0 - "@smithy/config-resolver": ^4.2.1 - "@smithy/core": ^3.11.0 - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/hash-node": ^4.1.1 - "@smithy/invalid-dependency": ^4.1.1 - "@smithy/middleware-content-length": ^4.1.1 - "@smithy/middleware-endpoint": ^4.2.1 - "@smithy/middleware-retry": ^4.2.1 - "@smithy/middleware-serde": ^4.1.1 - "@smithy/middleware-stack": ^4.1.1 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-body-length-node": ^4.1.0 - "@smithy/util-defaults-mode-browser": ^4.1.1 - "@smithy/util-defaults-mode-node": ^4.1.1 - "@smithy/util-endpoints": ^3.1.1 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-retry": ^4.1.1 - "@smithy/util-utf8": ^4.1.0 - "@smithy/util-waiter": ^4.1.1 - tslib: ^2.6.2 - checksum: 818bd91245081edb2e16d3e8c05f0c9a74868dd46b9f3fa1b4d57496636961a3a09ce7837471abaebe0e2697c7732366d5af3b8d9b9ece65c4d3c0a7e1419619 - languageName: node - linkType: hard - -"@aws-sdk/client-sso@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/client-sso@npm:3.888.0" - dependencies: - "@aws-crypto/sha256-browser": 5.2.0 - "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.888.0 - "@aws-sdk/middleware-host-header": 3.887.0 - "@aws-sdk/middleware-logger": 3.887.0 - "@aws-sdk/middleware-recursion-detection": 3.887.0 - "@aws-sdk/middleware-user-agent": 3.888.0 - "@aws-sdk/region-config-resolver": 3.887.0 - "@aws-sdk/types": 3.887.0 - "@aws-sdk/util-endpoints": 3.887.0 - "@aws-sdk/util-user-agent-browser": 3.887.0 - "@aws-sdk/util-user-agent-node": 3.888.0 - "@smithy/config-resolver": ^4.2.1 - "@smithy/core": ^3.11.0 - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/hash-node": ^4.1.1 - "@smithy/invalid-dependency": ^4.1.1 - "@smithy/middleware-content-length": ^4.1.1 - "@smithy/middleware-endpoint": ^4.2.1 - "@smithy/middleware-retry": ^4.2.1 - "@smithy/middleware-serde": ^4.1.1 - "@smithy/middleware-stack": ^4.1.1 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-body-length-node": ^4.1.0 - "@smithy/util-defaults-mode-browser": ^4.1.1 - "@smithy/util-defaults-mode-node": ^4.1.1 - "@smithy/util-endpoints": ^3.1.1 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-retry": ^4.1.1 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: 0aa68ee0144cf56c31034c520c39fd8c53b73083bd6ce1ad0ac32ecbefd497e280b5638a00b8078c26e4687b4a083161468b94f4d79d0e51132c98044d2628ab - languageName: node - linkType: hard - -"@aws-sdk/core@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/core@npm:3.888.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@aws-sdk/xml-builder": 3.887.0 - "@smithy/core": ^3.11.0 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/property-provider": ^4.0.5 - "@smithy/protocol-http": ^5.2.1 - "@smithy/signature-v4": ^5.1.3 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-utf8": ^4.1.0 - fast-xml-parser: 5.2.5 - tslib: ^2.6.2 - checksum: baf26845beaf66f796130337365e2992751e37fd632ea75ad0bfc8f955aea704c69112fc107a0c13a5af7e932707c3a40fc490c9634cdda4acf6050f5ca63deb - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-env@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 4c5012bcb95966db2a72ad7700fc3b5bbb4f7e4dea43f215b972b2d868ed40c8b7c7d1cec4fe53b0bda9b5f6c142480716561707609022f0fd91f033c2450a9c - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-http@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/property-provider": ^4.0.5 - "@smithy/protocol-http": ^5.2.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/util-stream": ^4.3.1 - tslib: ^2.6.2 - checksum: cd83cae0e01c65bc91ff922670d5c1933463726bbb44a68c6ee726f6b0799dc8d596ca7ef15e1abfb7fb9c88322f337e2bd303f65d66dfd5859055be35061d86 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-ini@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/credential-provider-env": 3.888.0 - "@aws-sdk/credential-provider-http": 3.888.0 - "@aws-sdk/credential-provider-process": 3.888.0 - "@aws-sdk/credential-provider-sso": 3.888.0 - "@aws-sdk/credential-provider-web-identity": 3.888.0 - "@aws-sdk/nested-clients": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/credential-provider-imds": ^4.0.7 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: aa551d529f378ef9558a16ea01e043f742646f38347469e2b1cbe3e2e094ca30cd272911750c62dd56908c9ff704c459014f6fbf3a25fd61e8f0e7e61f3a41bb - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-node@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.888.0" - dependencies: - "@aws-sdk/credential-provider-env": 3.888.0 - "@aws-sdk/credential-provider-http": 3.888.0 - "@aws-sdk/credential-provider-ini": 3.888.0 - "@aws-sdk/credential-provider-process": 3.888.0 - "@aws-sdk/credential-provider-sso": 3.888.0 - "@aws-sdk/credential-provider-web-identity": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/credential-provider-imds": ^4.0.7 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: cac63c05516ebf645068f8f68f1932db4691b1368ceced7260cd6ad6b10e4bf6be30962c150e3db69aab86e31609576610b85e62293fc4b4c71b4c96991e9ada - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-process@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 51290738eb782230758767994c677bec5a7da72756b7a780e5eaff04ed2812d7612e74df90892eac89c1f06ad164f2c657da0d999a786158e7e4af972a9dc7e0 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-sso@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.888.0" - dependencies: - "@aws-sdk/client-sso": 3.888.0 - "@aws-sdk/core": 3.888.0 - "@aws-sdk/token-providers": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 69e040bd12cea21134669ce8635741a754c940e5c9b053bf208d498b7878ca35ed047405eddf8264c8e44f09258166c8701b75776aa9002f8fc28e6b9a498580 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-web-identity@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/nested-clients": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: f4a6855190f47b00c5150d8e89c588e2beb65232829a4e2cef398aab2fddd775124541cead84c4ae5b59f1cabd4e566127ae23cb909841ce8e34a2d8f4fbc623 - languageName: node - linkType: hard - -"@aws-sdk/middleware-host-header@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: f07a901c5165d8eaf831bc0968f12c77c2b74cde53c7a6f61caadc87578172be162e4e0df6fdf7df0a182d282716603f01b4d818b2f2ba2856ad0ecb82de7816 - languageName: node - linkType: hard - -"@aws-sdk/middleware-logger@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/middleware-logger@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 6f4a95ed164378d6104207ec6b0da8d61452a74a67c95156e42be33d00f29daa53badc7a0461f269223eaeb0d5eff520d8fc4e25cc615657c0d5a897dbd7546f - languageName: node - linkType: hard - -"@aws-sdk/middleware-recursion-detection@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@aws/lambda-invoke-store": ^0.0.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: c8cdef1bcbe1228b918c6fa8fd7f149fb46c0004ee661b04138d95f167eeae9abfac68ca5597b70fa501efc292024ce7369161459cdcb2f6615587c428c6baac - languageName: node - linkType: hard - -"@aws-sdk/middleware-user-agent@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@aws-sdk/util-endpoints": 3.887.0 - "@smithy/core": ^3.11.0 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 17eeaa35c7a9b4e0505e7d5feb705c41dbdcdf4809ef39562fa8bd6e964ef5b9d3669eb6f307e535ce3f7a00c466b4080948a822ee9d7e14fa2c4257dc0c5eb3 - languageName: node - linkType: hard - -"@aws-sdk/nested-clients@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/nested-clients@npm:3.888.0" - dependencies: - "@aws-crypto/sha256-browser": 5.2.0 - "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.888.0 - "@aws-sdk/middleware-host-header": 3.887.0 - "@aws-sdk/middleware-logger": 3.887.0 - "@aws-sdk/middleware-recursion-detection": 3.887.0 - "@aws-sdk/middleware-user-agent": 3.888.0 - "@aws-sdk/region-config-resolver": 3.887.0 - "@aws-sdk/types": 3.887.0 - "@aws-sdk/util-endpoints": 3.887.0 - "@aws-sdk/util-user-agent-browser": 3.887.0 - "@aws-sdk/util-user-agent-node": 3.888.0 - "@smithy/config-resolver": ^4.2.1 - "@smithy/core": ^3.11.0 - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/hash-node": ^4.1.1 - "@smithy/invalid-dependency": ^4.1.1 - "@smithy/middleware-content-length": ^4.1.1 - "@smithy/middleware-endpoint": ^4.2.1 - "@smithy/middleware-retry": ^4.2.1 - "@smithy/middleware-serde": ^4.1.1 - "@smithy/middleware-stack": ^4.1.1 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/smithy-client": ^4.6.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-body-length-node": ^4.1.0 - "@smithy/util-defaults-mode-browser": ^4.1.1 - "@smithy/util-defaults-mode-node": ^4.1.1 - "@smithy/util-endpoints": ^3.1.1 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-retry": ^4.1.1 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: 699aaea06f8d0fe720470003ec70ede15e8781d50dbf28ed827ed7dd85318b3684995996859c1c5e0350ba9829f39f6721f1229b2c0e06f2a0e4cf77fee89f4b - languageName: node - linkType: hard - -"@aws-sdk/region-config-resolver@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-config-provider": ^4.0.0 - "@smithy/util-middleware": ^4.1.1 - tslib: ^2.6.2 - checksum: aced1bf4e3dce92fa76337a774551cf88e72a25e44f7582a9897ce52e73d309791fab22ba4900f364715afc73190c9e5a1d8934077aa04a63d8ef9cd9bf3f4ad - languageName: node - linkType: hard - -"@aws-sdk/token-providers@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/token-providers@npm:3.888.0" - dependencies: - "@aws-sdk/core": 3.888.0 - "@aws-sdk/nested-clients": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/property-provider": ^4.0.5 - "@smithy/shared-ini-file-loader": ^4.0.5 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 8e2e6ac2fc480f6d1b38a3563f274d2096bc7aad1ea46e875ce08955c7bb37b8c3f2ce7c457f414af94b5d7053499589909f15ceb5de8c28bd9a596c24b6fa6c - languageName: node - linkType: hard - -"@aws-sdk/types@npm:3.887.0, @aws-sdk/types@npm:^3.222.0": - version: 3.887.0 - resolution: "@aws-sdk/types@npm:3.887.0" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 141d3fcd3bf5b95e13df81b8cf1554f2cc2f4783922265ea344ab60105ea4453a9b4fae7df5da8652f9ede9e83fba8b06bc1c95566329d0541810d711ff1dad9 - languageName: node - linkType: hard - -"@aws-sdk/util-endpoints@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/util-endpoints@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-endpoints": ^3.1.1 - tslib: ^2.6.2 - checksum: aced26165e63871ac44e0cd9393729cb437d8b2f277c34cc45d51c9964e43c5bea4762c948ee04e9a93c5d98b037923de23d0b69973f256480f533285d0db45d - languageName: node - linkType: hard - -"@aws-sdk/util-locate-window@npm:^3.0.0": - version: 3.873.0 - resolution: "@aws-sdk/util-locate-window@npm:3.873.0" - dependencies: - tslib: ^2.6.2 - checksum: ff98e8fa00504ae62bf25605e708ac77693b11b628e0234b0a5bd03e6021e0ca12677ea494b1463c2ef70b483b5b30b2a08dfe5806788a570b3d7becae15591e - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-browser@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.887.0" - dependencies: - "@aws-sdk/types": 3.887.0 - "@smithy/types": ^4.5.0 - bowser: ^2.11.0 - tslib: ^2.6.2 - checksum: 18c5f77fd5e60129c7944c7f2d8b5b6c61783c12d59492193b25dcb6631d1c48896d5ffdec4ffd579ed75ae781c8fb91747e25cf4e7927b6f37b41b059e3035c - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-node@npm:3.888.0": - version: 3.888.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.888.0" - dependencies: - "@aws-sdk/middleware-user-agent": 3.888.0 - "@aws-sdk/types": 3.887.0 - "@smithy/node-config-provider": ^4.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - peerDependencies: - aws-crt: ">=1.0.0" - peerDependenciesMeta: - aws-crt: - optional: true - checksum: f2e273f44e078aeeaad678a592a69c315e0307a557f48759cba5d78f2ae501faed18c2497ea27e35796a11642ea6f9eeff2629947db07621b3a553e7fc81884c - languageName: node - linkType: hard - -"@aws-sdk/xml-builder@npm:3.887.0": - version: 3.887.0 - resolution: "@aws-sdk/xml-builder@npm:3.887.0" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: c2937d705a6ba6e3635279532eb984548117086520e9569df97ce400c6d7b9d1a74b47e720089857e2e5bd2a68f2b8273e746a79938ece0b875cca5b7ddbd844 - languageName: node - linkType: hard - -"@aws/lambda-invoke-store@npm:^0.0.1": - version: 0.0.1 - resolution: "@aws/lambda-invoke-store@npm:0.0.1" - checksum: af732ba2cd343daa49d4933827b4bdc80449641fbdf465ad4a97a818adf6f355454942a2b59a6a297c261c1b3fff11ea69c93b9564ed5e33fcdcf30f993c722d - languageName: node - linkType: hard - "@babel/code-frame@npm:7.12.11": version: 7.12.11 resolution: "@babel/code-frame@npm:7.12.11" @@ -537,38 +63,38 @@ __metadata: linkType: hard "@babel/compat-data@npm:^7.27.2, @babel/compat-data@npm:^7.27.7, @babel/compat-data@npm:^7.28.0": - version: 7.28.4 - resolution: "@babel/compat-data@npm:7.28.4" - checksum: 9f6f5289bbe5a29e3f9c737577a797205a91f19371b50af8942257d9cb590d44eb950154e4f2a3d5de4105f97a49d6fbc8daebe0db1e6eee04f5a4bf73536bfc + version: 7.28.0 + resolution: "@babel/compat-data@npm:7.28.0" + checksum: 37a40d4ea10a32783bc24c4ad374200f5db864c8dfa42f82e76f02b8e84e4c65e6a017fc014d165b08833f89333dff4cb635fce30f03c333ea3525ea7e20f0a2 languageName: node linkType: hard "@babel/core@npm:^7.1.0, @babel/core@npm:^7.11.1, @babel/core@npm:^7.12.3, @babel/core@npm:^7.16.0, @babel/core@npm:^7.20.5, @babel/core@npm:^7.28.0, @babel/core@npm:^7.7.2, @babel/core@npm:^7.8.0": - version: 7.28.4 - resolution: "@babel/core@npm:7.28.4" + version: 7.28.0 + resolution: "@babel/core@npm:7.28.0" dependencies: + "@ampproject/remapping": ^2.2.0 "@babel/code-frame": ^7.27.1 - "@babel/generator": ^7.28.3 + "@babel/generator": ^7.28.0 "@babel/helper-compilation-targets": ^7.27.2 - "@babel/helper-module-transforms": ^7.28.3 - "@babel/helpers": ^7.28.4 - "@babel/parser": ^7.28.4 + "@babel/helper-module-transforms": ^7.27.3 + "@babel/helpers": ^7.27.6 + "@babel/parser": ^7.28.0 "@babel/template": ^7.27.2 - "@babel/traverse": ^7.28.4 - "@babel/types": ^7.28.4 - "@jridgewell/remapping": ^2.3.5 + "@babel/traverse": ^7.28.0 + "@babel/types": ^7.28.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 - checksum: f55b90b2c61a6461f5c0ccab74d32af9c67448c43c629529ba7ec3c61d87fa8c408cc9305bfb1f5b09e671d25436d44eaf75c48dee5dc0a5c5e21c01290f5134 + checksum: 86da9e26c96e22d96deca0509969d273476f61c30464f262dec5e5a163422e07d5ab690ed54619d10fcab784abd10567022ce3d90f175b40279874f5288215e3 languageName: node linkType: hard "@babel/eslint-parser@npm:^7.16.3": - version: 7.28.4 - resolution: "@babel/eslint-parser@npm:7.28.4" + version: 7.28.0 + resolution: "@babel/eslint-parser@npm:7.28.0" dependencies: "@nicolo-ribaudo/eslint-scope-5-internals": 5.1.1-v1 eslint-visitor-keys: ^2.1.0 @@ -576,20 +102,20 @@ __metadata: peerDependencies: "@babel/core": ^7.11.0 eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - checksum: 32fb41c8648e169bc8570e25b4657475e165e1a49b8c6610f9bf86f311bbcc8dfa73f004977015688763aa6af17f48c690720bbc7b7b99695557adb267a9a7ff + checksum: ccfc4b9b9fdca2b8df95da3827b70231e9588a71447ff7b2de76c4f36710e4e0a7dc5e2e98623f398a737c2429c46500cb11d4ccdfeb98271e067d0bf0eec9b5 languageName: node linkType: hard -"@babel/generator@npm:^7.28.3, @babel/generator@npm:^7.7.2": - version: 7.28.3 - resolution: "@babel/generator@npm:7.28.3" +"@babel/generator@npm:^7.28.0, @babel/generator@npm:^7.7.2": + version: 7.28.0 + resolution: "@babel/generator@npm:7.28.0" dependencies: - "@babel/parser": ^7.28.3 - "@babel/types": ^7.28.2 + "@babel/parser": ^7.28.0 + "@babel/types": ^7.28.0 "@jridgewell/gen-mapping": ^0.3.12 "@jridgewell/trace-mapping": ^0.3.28 jsesc: ^3.0.2 - checksum: e2202bf2b9c8a94f7e7a0a049fda0ee037d055c46922e85afa3bbc53309113f859b8193894f991045d7865226028b8f4f06152ed315ab414451932016dba5e42 + checksum: 3fc9ecca7e7a617cf7b7357e11975ddfaba4261f374ab915f5d9f3b1ddc8fd58da9f39492396416eb08cf61972d1aa13c92d4cca206533c553d8651c2740f07f languageName: node linkType: hard @@ -615,20 +141,20 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.27.1, @babel/helper-create-class-features-plugin@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/helper-create-class-features-plugin@npm:7.28.3" +"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-create-class-features-plugin@npm:7.27.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.27.3 + "@babel/helper-annotate-as-pure": ^7.27.1 "@babel/helper-member-expression-to-functions": ^7.27.1 "@babel/helper-optimise-call-expression": ^7.27.1 "@babel/helper-replace-supers": ^7.27.1 "@babel/helper-skip-transparent-expression-wrappers": ^7.27.1 - "@babel/traverse": ^7.28.3 + "@babel/traverse": ^7.27.1 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 6d918e5e9c88ad1a262ab7b1a3caede1bbf95f8276c96846d8b0c1af251c85a0c868a9f1bbbaebdeb199e44dfd0e10fbe22935e56bedd1aa41ba4a7162bfa86c + checksum: 406954b455e5b20924e7d1b41cf932e6e98e95c3a5224c7a70c3ad96a84e8fbde915ceff7ddbf9c7d121397c4e9274f061241648475122cf6fe54e0a95caae15 languageName: node linkType: hard @@ -687,16 +213,16 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/helper-module-transforms@npm:7.28.3" +"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/helper-module-transforms@npm:7.27.3" dependencies: "@babel/helper-module-imports": ^7.27.1 "@babel/helper-validator-identifier": ^7.27.1 - "@babel/traverse": ^7.28.3 + "@babel/traverse": ^7.27.3 peerDependencies: "@babel/core": ^7.0.0 - checksum: 7cf7b79da0fa626d6c84bfc7b35c079a2559caecaa2ff645b0f1db0d741507aa4df6b5b98a3283e8ac4e89094af271d805bf5701e5c4f916e622797b7c8cbb18 + checksum: c611d42d3cb7ba23b1a864fcf8d6cde0dc99e876ca1c9a67e4d7919a70706ded4aaa45420de2bf7f7ea171e078e59f0edcfa15a56d74b9485e151b95b93b946e languageName: node linkType: hard @@ -774,23 +300,23 @@ __metadata: linkType: hard "@babel/helper-wrap-function@npm:^7.27.1": - version: 7.28.3 - resolution: "@babel/helper-wrap-function@npm:7.28.3" + version: 7.27.1 + resolution: "@babel/helper-wrap-function@npm:7.27.1" dependencies: - "@babel/template": ^7.27.2 - "@babel/traverse": ^7.28.3 - "@babel/types": ^7.28.2 - checksum: 0ebdfdc918fdd0c1cf6ff15ba4c664974d0cdf21a017af560d58b00c379df3bf2e55f13a44fe3225668bca169da174f6cb97a96c4e987fb728fdb8f9a39db302 + "@babel/template": ^7.27.1 + "@babel/traverse": ^7.27.1 + "@babel/types": ^7.27.1 + checksum: b0427765766494cb5455a188d4cdef5e6167f2835a8ed76f3c25fa3bbe2ec2a716588fa326c52fab0d184a9537200d76e48656e516580a914129d74528322821 languageName: node linkType: hard -"@babel/helpers@npm:^7.28.4": - version: 7.28.4 - resolution: "@babel/helpers@npm:7.28.4" +"@babel/helpers@npm:^7.27.6": + version: 7.28.2 + resolution: "@babel/helpers@npm:7.28.2" dependencies: "@babel/template": ^7.27.2 - "@babel/types": ^7.28.4 - checksum: a8706219e0bd60c18bbb8e010aa122e9b14e7e7e67c21cc101e6f1b5e79dcb9a18d674f655997f85daaf421aa138cf284710bb04371a2255a0a3137f097430b4 + "@babel/types": ^7.28.2 + checksum: 7ead856041f73496eeeb4f7f88a741067c8022fc764cbca7fc3e96ae73ce71969f75fd79b40b2c6a60ca4923f9d56f7798fb86ac2538f13b6d4acb54ebb563a7 languageName: node linkType: hard @@ -806,14 +332,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": - version: 7.28.4 - resolution: "@babel/parser@npm:7.28.4" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/parser@npm:7.28.0" dependencies: - "@babel/types": ^7.28.4 + "@babel/types": ^7.28.0 bin: parser: ./bin/babel-parser.js - checksum: d95e283fe1153039b396926ef567ca1ab114afb5c732a23bbcbbd0465ac59971aeb6a63f37593ce7671a52d34ec52b23008c999d68241b42d26928c540464063 + checksum: 718e4ce9b0914701d6f74af610d3e7d52b355ef1dcf34a7dedc5930e96579e387f04f96187e308e601828b900b8e4e66d2fe85023beba2ac46587023c45b01cf languageName: node linkType: hard @@ -864,15 +390,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.28.3" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.27.1" dependencies: "@babel/helper-plugin-utils": ^7.27.1 - "@babel/traverse": ^7.28.3 + "@babel/traverse": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: c810e5d36030df6861ced35f0adbda7b4b41ac3e984422b32bee906564fd49374435f0a7a1a42eb0a9e6a5170c255f0ab31c163d5fc51fa5a816aa0420311029 + checksum: 4d6792ccade2d6b9d5577b0a879ab22d05ac8a1206b1a636b6ffdb53a0c0bacaf0f7947e46de254f228ffd75456f4b95ccd82fdeaefc0b92d88af3c5991863ad languageName: node linkType: hard @@ -1254,13 +780,13 @@ __metadata: linkType: hard "@babel/plugin-transform-block-scoping@npm:^7.28.0": - version: 7.28.4 - resolution: "@babel/plugin-transform-block-scoping@npm:7.28.4" + version: 7.28.0 + resolution: "@babel/plugin-transform-block-scoping@npm:7.28.0" dependencies: "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7f62eae907c0b4f85b9cc024da949697e57d17f2107ca4a240011174762d4c546b856ccbd5ba83ecb4bc9eb50150ea46558d551a5b05d3f25aace88a65fa4e04 + checksum: 6d740f9a386e5fbdffd9e7c5a8400bff8d54068241a78b8e71aba6f1f46eff0c4297902f5f1543bee1ed076ec88d0dc4ceed19e98a466802c14d3c20f178f712 languageName: node linkType: hard @@ -1276,31 +802,31 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/plugin-transform-class-static-block@npm:7.28.3" +"@babel/plugin-transform-class-static-block@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-class-static-block@npm:7.27.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.28.3 + "@babel/helper-create-class-features-plugin": ^7.27.1 "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.12.0 - checksum: 9b2feaacbf29637ab35a3aae1df35a1129adec5400a1767443739557fb0d3bf8278bf0ec90aacf43dec9a7dd91428d01375020b70528713e1bc36a72776a104c + checksum: 69688fe1641ae0ea025b916b8c2336e8b5643a5ec292e8f546ecd35d9d9d4bb301d738910822a79d867098cf687d550d92cd906ae4cda03c0f69b1ece2149a58 languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.28.3": - version: 7.28.4 - resolution: "@babel/plugin-transform-classes@npm:7.28.4" +"@babel/plugin-transform-classes@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/plugin-transform-classes@npm:7.28.0" dependencies: "@babel/helper-annotate-as-pure": ^7.27.3 "@babel/helper-compilation-targets": ^7.27.2 "@babel/helper-globals": ^7.28.0 "@babel/helper-plugin-utils": ^7.27.1 "@babel/helper-replace-supers": ^7.27.1 - "@babel/traverse": ^7.28.4 + "@babel/traverse": ^7.28.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f412e00c86584a9094cc0a2f3dd181b8108a4dced477d609c5406beddd5bf79d05a7ea74db508dc4dcb37172f042d5ef98d3d6311ade61c7ea6fbbbb70f5ec29 + checksum: 0b47188046a4f1579123354ee30d08874b4b585d45128a3d492fa1cba7e26c8039d8c44d38d85f4eaa9b5a53064c66f032cfc35526c73c74a865a11edf3a0c28 languageName: node linkType: hard @@ -1596,17 +1122,17 @@ __metadata: linkType: hard "@babel/plugin-transform-object-rest-spread@npm:^7.28.0": - version: 7.28.4 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.4" + version: 7.28.0 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.0" dependencies: "@babel/helper-compilation-targets": ^7.27.2 "@babel/helper-plugin-utils": ^7.27.1 "@babel/plugin-transform-destructuring": ^7.28.0 "@babel/plugin-transform-parameters": ^7.27.7 - "@babel/traverse": ^7.28.4 + "@babel/traverse": ^7.28.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2063672ba4ac457a64b5c0c982439c7b08b4c70f0e743792b98240db5a05f1c063918d8366c92d4d6b2572e2e3452b300a23980b6668e4f54ff349f60d47ec48 + checksum: 7c32c988b4b040d0091d0210b6b946249571858b2f33f3a5105f41c28ee0b8440a9dfb2aa46f3ae0d3014f86ddf16aee9a0cbf4229daf8e013235352b8f31fc9 languageName: node linkType: hard @@ -1774,14 +1300,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.28.3": - version: 7.28.4 - resolution: "@babel/plugin-transform-regenerator@npm:7.28.4" +"@babel/plugin-transform-regenerator@npm:^7.28.0": + version: 7.28.1 + resolution: "@babel/plugin-transform-regenerator@npm:7.28.1" dependencies: "@babel/helper-plugin-utils": ^7.27.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2aa99b3a7b254a109e913fabbe1fb320ff40723988fde0e225212b7ef20f523a399a6e45077258b176c29715493b2a853cf7c130811692215adf33e5af99782b + checksum: c0bc0123ce2227c5074c7c17d6b72b558f0b38360aa180751c897086912f5e17e18855d361ac29f542343ad30ee128b937398282dc9a12c795fa8227954e48ea languageName: node linkType: hard @@ -1809,8 +1335,8 @@ __metadata: linkType: hard "@babel/plugin-transform-runtime@npm:^7.16.4": - version: 7.28.3 - resolution: "@babel/plugin-transform-runtime@npm:7.28.3" + version: 7.28.0 + resolution: "@babel/plugin-transform-runtime@npm:7.28.0" dependencies: "@babel/helper-module-imports": ^7.27.1 "@babel/helper-plugin-utils": ^7.27.1 @@ -1820,7 +1346,7 @@ __metadata: semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 63d2fc05d5bfcb96f31be54b095d72a89f0a03c8de10f5d742b18b174e2731bcdc27292e8deec66c2e88cebf8298393123d5e767526f6fffbc75cb8144ef66c6 + checksum: 8d324eb312636efe706917a5d44f867538654453c9bf4efd34b0dbd712c6d80e604092b98acbfcb318f42bec707b590c28ae95c659ff359a64a4ccb7621dc400 languageName: node linkType: hard @@ -1943,8 +1469,8 @@ __metadata: linkType: hard "@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.16.4": - version: 7.28.3 - resolution: "@babel/preset-env@npm:7.28.3" + version: 7.28.0 + resolution: "@babel/preset-env@npm:7.28.0" dependencies: "@babel/compat-data": ^7.28.0 "@babel/helper-compilation-targets": ^7.27.2 @@ -1954,7 +1480,7 @@ __metadata: "@babel/plugin-bugfix-safari-class-field-initializer-scope": ^7.27.1 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.27.1 "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.27.1 - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.28.3 + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.27.1 "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 "@babel/plugin-syntax-import-assertions": ^7.27.1 "@babel/plugin-syntax-import-attributes": ^7.27.1 @@ -1965,8 +1491,8 @@ __metadata: "@babel/plugin-transform-block-scoped-functions": ^7.27.1 "@babel/plugin-transform-block-scoping": ^7.28.0 "@babel/plugin-transform-class-properties": ^7.27.1 - "@babel/plugin-transform-class-static-block": ^7.28.3 - "@babel/plugin-transform-classes": ^7.28.3 + "@babel/plugin-transform-class-static-block": ^7.27.1 + "@babel/plugin-transform-classes": ^7.28.0 "@babel/plugin-transform-computed-properties": ^7.27.1 "@babel/plugin-transform-destructuring": ^7.28.0 "@babel/plugin-transform-dotall-regex": ^7.27.1 @@ -1998,7 +1524,7 @@ __metadata: "@babel/plugin-transform-private-methods": ^7.27.1 "@babel/plugin-transform-private-property-in-object": ^7.27.1 "@babel/plugin-transform-property-literals": ^7.27.1 - "@babel/plugin-transform-regenerator": ^7.28.3 + "@babel/plugin-transform-regenerator": ^7.28.0 "@babel/plugin-transform-regexp-modifiers": ^7.27.1 "@babel/plugin-transform-reserved-words": ^7.27.1 "@babel/plugin-transform-shorthand-properties": ^7.27.1 @@ -2018,7 +1544,7 @@ __metadata: semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c4e70f69b727d21eedd4de201ac082e951482f2d28a388e401e7937fd6f15bc1a49a63c12f59e87a18d237ac037a5b29d983f3bb82f1196d6444ae5b605ac6e2 + checksum: 90399ed6350ac413fb507dc5c9e29e98d10684c4b7c7c6ae7b204bb91a7a9cd3bf8f944167a931a73112c8c820d0d1f42d4c15d7c4a7cf19196bf11c19663513 languageName: node linkType: hard @@ -2066,10 +1592,10 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.28.3, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.7": - version: 7.28.4 - resolution: "@babel/runtime@npm:7.28.4" - checksum: 934b0a0460f7d06637d93fcd1a44ac49adc33518d17253b5a0b55ff4cb90a45d8fe78bf034b448911dbec7aff2a90b918697559f78d21c99ff8dbadae9565b55 +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.25.6, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.28.2, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.7": + version: 7.28.2 + resolution: "@babel/runtime@npm:7.28.2" + checksum: 8673eb2311752929f5b0167f42cff4cc1d5fadddd0394baca27d06c1618680ffcf95e9f01061f5c4dc3f6a32b6bbf500e7762c02dc22bcd273c2947b9774ddad languageName: node linkType: hard @@ -2084,28 +1610,28 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.7.2": - version: 7.28.4 - resolution: "@babel/traverse@npm:7.28.4" +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.7.2": + version: 7.28.0 + resolution: "@babel/traverse@npm:7.28.0" dependencies: "@babel/code-frame": ^7.27.1 - "@babel/generator": ^7.28.3 + "@babel/generator": ^7.28.0 "@babel/helper-globals": ^7.28.0 - "@babel/parser": ^7.28.4 + "@babel/parser": ^7.28.0 "@babel/template": ^7.27.2 - "@babel/types": ^7.28.4 + "@babel/types": ^7.28.0 debug: ^4.3.1 - checksum: d603b8ce4e55ba4fc7b28d3362cc2b1b20bc887e471c8a59fe87b2578c26803c9ef8fcd118081dd8283ea78e0e9a6df9d88c8520033c6aaf81eec30d2a669151 + checksum: f1b6ed2a37f593ee02db82521f8d54c8540a7ec2735c6c127ba687de306d62ac5a7c6471819783128e0b825c4f7e374206ebbd1daf00d07f05a4528f5b1b4c07 languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": - version: 7.28.4 - resolution: "@babel/types@npm:7.28.4" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.0, @babel/types@npm:^7.28.2, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": + version: 7.28.2 + resolution: "@babel/types@npm:7.28.2" dependencies: "@babel/helper-string-parser": ^7.27.1 "@babel/helper-validator-identifier": ^7.27.1 - checksum: a369b4fb73415a2ed902a15576b49696ae9777ddee394a7a904c62e6fbb31f43906b0147ae0b8f03ac17f20c248eac093df349e33c65c94617b12e524b759694 + checksum: 2218f0996d5fbadc4e3428c4c38f4ed403f0e2634e3089beba2c89783268c0c1d796a23e65f9f1ff8547b9061ae1a67691c76dc27d0b457e5fa9f2dd4e022e49 languageName: node linkType: hard @@ -2134,6 +1660,16 @@ __metadata: languageName: node linkType: hard +"@bundled-es-modules/tough-cookie@npm:^0.1.6": + version: 0.1.6 + resolution: "@bundled-es-modules/tough-cookie@npm:0.1.6" + dependencies: + "@types/tough-cookie": ^4.0.5 + tough-cookie: ^4.1.4 + checksum: e31c1262cbc044373e757117b1b152acc86ba5d088124153b3d1ae83e0de0a2b4d2362758cec3e1a49cf15c39a4447587cc2672e4f5a961754c91ef9ca3221e1 + languageName: node + linkType: hard + "@cspotcode/source-map-support@npm:^0.8.0": version: 0.8.1 resolution: "@cspotcode/source-map-support@npm:0.8.1" @@ -2356,11 +1892,11 @@ __metadata: linkType: hard "@emotion/is-prop-valid@npm:^1.3.0": - version: 1.4.0 - resolution: "@emotion/is-prop-valid@npm:1.4.0" + version: 1.3.1 + resolution: "@emotion/is-prop-valid@npm:1.3.1" dependencies: "@emotion/memoize": ^0.9.0 - checksum: 6b003cdc62106c2d5d12207c2d1352d674339252a2d7ac8d96974781d7c639833f35d22e7e331411795daaafa62f126c2824a4983584292b431e08b42877d51e + checksum: fe6549d54f389e1a17cb02d832af7ee85fb6ea126fc18d02ca47216e8ff19332c1983f4a0ba68602cfcd3b325ffd4ebf0b2d0c6270f1e7e6fe3fca4ba7741e1a languageName: node linkType: hard @@ -2476,9 +2012,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/aix-ppc64@npm:0.25.9" +"@esbuild/aix-ppc64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/aix-ppc64@npm:0.25.8" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -2504,9 +2040,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/android-arm64@npm:0.25.9" +"@esbuild/android-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/android-arm64@npm:0.25.8" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -2532,9 +2068,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/android-arm@npm:0.25.9" +"@esbuild/android-arm@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/android-arm@npm:0.25.8" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -2560,9 +2096,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/android-x64@npm:0.25.9" +"@esbuild/android-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/android-x64@npm:0.25.8" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -2588,9 +2124,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/darwin-arm64@npm:0.25.9" +"@esbuild/darwin-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/darwin-arm64@npm:0.25.8" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -2616,9 +2152,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/darwin-x64@npm:0.25.9" +"@esbuild/darwin-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/darwin-x64@npm:0.25.8" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -2644,9 +2180,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/freebsd-arm64@npm:0.25.9" +"@esbuild/freebsd-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/freebsd-arm64@npm:0.25.8" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -2672,9 +2208,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/freebsd-x64@npm:0.25.9" +"@esbuild/freebsd-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/freebsd-x64@npm:0.25.8" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -2700,9 +2236,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-arm64@npm:0.25.9" +"@esbuild/linux-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-arm64@npm:0.25.8" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -2728,9 +2264,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-arm@npm:0.25.9" +"@esbuild/linux-arm@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-arm@npm:0.25.8" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -2756,9 +2292,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-ia32@npm:0.25.9" +"@esbuild/linux-ia32@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-ia32@npm:0.25.8" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -2784,9 +2320,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-loong64@npm:0.25.9" +"@esbuild/linux-loong64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-loong64@npm:0.25.8" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -2812,9 +2348,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-mips64el@npm:0.25.9" +"@esbuild/linux-mips64el@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-mips64el@npm:0.25.8" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -2840,9 +2376,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-ppc64@npm:0.25.9" +"@esbuild/linux-ppc64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-ppc64@npm:0.25.8" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -2868,9 +2404,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-riscv64@npm:0.25.9" +"@esbuild/linux-riscv64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-riscv64@npm:0.25.8" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -2896,9 +2432,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-s390x@npm:0.25.9" +"@esbuild/linux-s390x@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-s390x@npm:0.25.8" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -2924,9 +2460,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/linux-x64@npm:0.25.9" +"@esbuild/linux-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-x64@npm:0.25.8" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -2938,9 +2474,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/netbsd-arm64@npm:0.25.9" +"@esbuild/netbsd-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/netbsd-arm64@npm:0.25.8" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard @@ -2966,9 +2502,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/netbsd-x64@npm:0.25.9" +"@esbuild/netbsd-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/netbsd-x64@npm:0.25.8" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -2980,9 +2516,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/openbsd-arm64@npm:0.25.9" +"@esbuild/openbsd-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/openbsd-arm64@npm:0.25.8" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -3008,16 +2544,16 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/openbsd-x64@npm:0.25.9" +"@esbuild/openbsd-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/openbsd-x64@npm:0.25.8" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openharmony-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/openharmony-arm64@npm:0.25.9" +"@esbuild/openharmony-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/openharmony-arm64@npm:0.25.8" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard @@ -3043,9 +2579,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/sunos-x64@npm:0.25.9" +"@esbuild/sunos-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/sunos-x64@npm:0.25.8" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -3071,9 +2607,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/win32-arm64@npm:0.25.9" +"@esbuild/win32-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/win32-arm64@npm:0.25.8" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -3099,9 +2635,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/win32-ia32@npm:0.25.9" +"@esbuild/win32-ia32@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/win32-ia32@npm:0.25.8" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -3127,21 +2663,21 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.25.9": - version: 0.25.9 - resolution: "@esbuild/win32-x64@npm:0.25.9" +"@esbuild/win32-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/win32-x64@npm:0.25.8" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.9.0 - resolution: "@eslint-community/eslint-utils@npm:4.9.0" + version: 4.7.0 + resolution: "@eslint-community/eslint-utils@npm:4.7.0" dependencies: eslint-visitor-keys: ^3.4.3 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: ae9b98eea006d1354368804b0116b8b45017a4e47b486d1b9cfa048a8ed3dc69b9b074eb2b2acb14034e6897c24048fd42b6a6816d9dc8bb9daad79db7d478d2 + checksum: b177e3b75c0b8d0e5d71f1c532edb7e40b31313db61f0c879f9bf19c3abb2783c6c372b5deb2396dab4432f2946b9972122ac682e77010376c029dfd0149c681 languageName: node linkType: hard @@ -3202,25 +2738,25 @@ __metadata: languageName: node linkType: hard -"@floating-ui/dom@npm:^1.7.4": - version: 1.7.4 - resolution: "@floating-ui/dom@npm:1.7.4" +"@floating-ui/dom@npm:^1.7.3": + version: 1.7.3 + resolution: "@floating-ui/dom@npm:1.7.3" dependencies: "@floating-ui/core": ^1.7.3 "@floating-ui/utils": ^0.2.10 - checksum: 806923e6f5b09e024c366070f2115a4db6e8ad28462bac29cd075170a6f7d900497da3ee542439bd0770b8e2fff12b636cc30873d1c82e9ec4a487870b080643 + checksum: 37a02ed991f0c580ba65bb67040656bbe45b0331fc8ebe35fdf7bacb13555641e1260d18599d5c1eb81ca0479873b18f15f2288e928d52cf8908efc154de989b languageName: node linkType: hard "@floating-ui/react-dom@npm:^2.1.1": - version: 2.1.6 - resolution: "@floating-ui/react-dom@npm:2.1.6" + version: 2.1.5 + resolution: "@floating-ui/react-dom@npm:2.1.5" dependencies: - "@floating-ui/dom": ^1.7.4 + "@floating-ui/dom": ^1.7.3 peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 24ff266806cd4cba6ad066f0eda7b99583f68af877f41df0b2a8d10a392692e3a1c1d666ebb75571a060818ede940bae59d833aa517ed538f7dba9dddd9991ae + checksum: 95bc27fcae10ebcaa7e9ee88dfa99b21e544e84f2b2e779655969e0fab224018c61a90d0ce9b7c82a5e4d55bbda08a3e8e475bca8022326a135bd80b256dfdb1 languageName: node linkType: hard @@ -3301,35 +2837,28 @@ __metadata: languageName: node linkType: hard -"@inquirer/ansi@npm:^1.0.0": - version: 1.0.0 - resolution: "@inquirer/ansi@npm:1.0.0" - checksum: 153b619c1178ece3e28a66ab41b7827b9ee64c84180f779bcc1c38c8c3e87979130bba109dd7e648ccdd3786da75c4a3a0945e816dc6afec9219f54ac7fbbb69 - languageName: node - linkType: hard - "@inquirer/confirm@npm:^5.0.0": - version: 5.1.18 - resolution: "@inquirer/confirm@npm:5.1.18" + version: 5.1.14 + resolution: "@inquirer/confirm@npm:5.1.14" dependencies: - "@inquirer/core": ^10.2.2 + "@inquirer/core": ^10.1.15 "@inquirer/type": ^3.0.8 peerDependencies: "@types/node": ">=18" peerDependenciesMeta: "@types/node": optional: true - checksum: 59a27eedf9b8e5ff1ca5eb738121caf56c94d9ec80f0ff02021300a7894c608e9c32e06b79ba21714f6977a277c84025e62b141c50c580be2a30697f52ef4941 + checksum: 18e56ca1a46bd7b03064cc01b467f9c699d0c27abdccafb14174192875d7a39a1802eb968386f33668303a28b0b1859dac07ac0323422c35a62f5a80a0987a7a languageName: node linkType: hard -"@inquirer/core@npm:^10.2.2": - version: 10.2.2 - resolution: "@inquirer/core@npm:10.2.2" +"@inquirer/core@npm:^10.1.15": + version: 10.1.15 + resolution: "@inquirer/core@npm:10.1.15" dependencies: - "@inquirer/ansi": ^1.0.0 "@inquirer/figures": ^1.0.13 "@inquirer/type": ^3.0.8 + ansi-escapes: ^4.3.2 cli-width: ^4.1.0 mute-stream: ^2.0.0 signal-exit: ^4.1.0 @@ -3340,7 +2869,7 @@ __metadata: peerDependenciesMeta: "@types/node": optional: true - checksum: 79d528ecb5f485a0f63bd5e48273a2ffba9457240e2a1971da8ea97a97c8398b932260691b8d5e5134f306ba8b08ce7a4800dfa7bd8cc9143a86760714215927 + checksum: 84b262dcdb7c4c800e65d79aa87b1c6449b2ccade5797a53e6e2d07d1f54db8bc4e3a529c87dfb20b5bb69f0dd46077582b2394aed1a44f3b79a67b402c990d3 languageName: node linkType: hard @@ -3705,22 +3234,12 @@ __metadata: linkType: hard "@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.13 - resolution: "@jridgewell/gen-mapping@npm:0.3.13" + version: 0.3.12 + resolution: "@jridgewell/gen-mapping@npm:0.3.12" dependencies: "@jridgewell/sourcemap-codec": ^1.5.0 "@jridgewell/trace-mapping": ^0.3.24 - checksum: f2105acefc433337145caa3c84bba286de954f61c0bc46279bbd85a9e6a02871089717fa060413cfb6a9d44189fe8313b2d1cabf3a2eb3284d208fd5f75c54ff - languageName: node - linkType: hard - -"@jridgewell/remapping@npm:^2.3.5": - version: 2.3.5 - resolution: "@jridgewell/remapping@npm:2.3.5" - dependencies: - "@jridgewell/gen-mapping": ^0.3.5 - "@jridgewell/trace-mapping": ^0.3.24 - checksum: 4a66a7397c3dc9c6b5c14a0024b1f98c5e1d90a0dbc1e5955b5038f2db339904df2a0ee8a66559fafb4fc23ff33700a2639fd40bbdd2e9e82b58b3bdf83738e3 + checksum: 56ee1631945084897f274e65348afbaca7970ce92e3c23b3a23b2fe5d0d2f0c67614f0df0f2bb070e585e944bbaaf0c11cee3a36318ab8a36af46f2fd566bc40 languageName: node linkType: hard @@ -3732,19 +3251,19 @@ __metadata: linkType: hard "@jridgewell/source-map@npm:^0.3.3": - version: 0.3.11 - resolution: "@jridgewell/source-map@npm:0.3.11" + version: 0.3.10 + resolution: "@jridgewell/source-map@npm:0.3.10" dependencies: "@jridgewell/gen-mapping": ^0.3.5 "@jridgewell/trace-mapping": ^0.3.25 - checksum: c8a0011cc67e701f270fa042e32b312f382c413bcc70ca9c03684687cbf5b64d5eed87d4afa36dddaabe60ab3da6db4935f878febd9cfc7f82724ea1a114d344 + checksum: 035d6e6df0e60744506b14033f1569fd5ddc269abeb68bf50c2911118e2a4fa50dab474d49a59a993e4ee6795c4ae5940381e0d09fc204972c5387788d22d010 languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": - version: 1.5.5 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" - checksum: c2e36e67971f719a8a3a85ef5a5f580622437cc723c35d03ebd0c9c0b06418700ef006f58af742791f71f6a4fc68fcfaf1f6a74ec2f9a3332860e9373459dae7 +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.4 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.4" + checksum: 959093724bfbc7c1c9aadc08066154f5c1f2acc647b45bd59beec46922cbfc6a9eda4a2114656de5bc00bb3600e420ea9a4cb05e68dcf388619f573b77bd9f0c languageName: node linkType: hard @@ -3759,12 +3278,12 @@ __metadata: linkType: hard "@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": - version: 0.3.31 - resolution: "@jridgewell/trace-mapping@npm:0.3.31" + version: 0.3.29 + resolution: "@jridgewell/trace-mapping@npm:0.3.29" dependencies: "@jridgewell/resolve-uri": ^3.1.0 "@jridgewell/sourcemap-codec": ^1.4.14 - checksum: af8fda2431348ad507fbddf8e25f5d08c79ecc94594061ce402cf41bc5aba1a7b3e59bf0fd70a619b35f33983a3f488ceeba8faf56bff784f98bb5394a8b7d47 + checksum: 5e92eeafa5131a4f6b7122063833d657f885cb581c812da54f705d7a599ff36a75a4a093a83b0f6c7e95642f5772dd94753f696915e8afea082237abf7423ca3 languageName: node linkType: hard @@ -3783,8 +3302,8 @@ __metadata: linkType: hard "@mswjs/interceptors@npm:^0.39.1": - version: 0.39.6 - resolution: "@mswjs/interceptors@npm:0.39.6" + version: 0.39.5 + resolution: "@mswjs/interceptors@npm:0.39.5" dependencies: "@open-draft/deferred-promise": ^2.2.0 "@open-draft/logger": ^0.3.0 @@ -3792,7 +3311,7 @@ __metadata: is-node-process: ^1.2.0 outvariant: ^1.4.3 strict-event-emitter: ^0.5.1 - checksum: 4960ad247aeabdb6465754ab4646b6441032bdc26cef8c38696240cd3968e99533363f7e71f5d3f8f170b49456c2f1294920c28031327ea7d721320e3863b546 + checksum: ba555a9023a6e156feb195b4d47194aa8ae77b2e73affc7b378f97e9b9c77a8a29396c184e066b9d554fafbc0a092d6e70811916dfe8448f15c32857c9565241 languageName: node linkType: hard @@ -3977,17 +3496,17 @@ __metadata: languageName: node linkType: hard -"@mui/types@npm:^7.2.15, @mui/types@npm:^7.2.17, @mui/types@npm:^7.4.6": - version: 7.4.6 - resolution: "@mui/types@npm:7.4.6" +"@mui/types@npm:^7.2.15, @mui/types@npm:^7.2.17, @mui/types@npm:^7.4.5": + version: 7.4.5 + resolution: "@mui/types@npm:7.4.5" dependencies: - "@babel/runtime": ^7.28.3 + "@babel/runtime": ^7.28.2 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 7e4b4ae06066468e8a8211376d0a08250325f4b92f6d2ea24576df37dfcd0f683602567debdf15889e0e4510eb48d677aa0d71a2ed9423c16dbd4b4ecfbccbb9 + checksum: 2468000bc1d003c1d1eb71e0537b8ed63b9dff96e077a7de31f7dd5db28f8b07f415e835240b5fd1b2d07ba5823283c90af7419a7d582496599717248103fcd5 languageName: node linkType: hard @@ -4044,11 +3563,11 @@ __metadata: linkType: hard "@mui/utils@npm:^5.16.6 || ^6.0.0 || ^7.0.0": - version: 7.3.2 - resolution: "@mui/utils@npm:7.3.2" + version: 7.3.1 + resolution: "@mui/utils@npm:7.3.1" dependencies: - "@babel/runtime": ^7.28.3 - "@mui/types": ^7.4.6 + "@babel/runtime": ^7.28.2 + "@mui/types": ^7.4.5 "@types/prop-types": ^15.7.15 clsx: ^2.1.1 prop-types: ^15.8.1 @@ -4059,7 +3578,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 201fb1f49434c3ee12de3a177660af04cb6411a68f8c13dc62ea828c522758b53040046daf2341b38da3b0a8a455ef4454a49cca4fa4e7b4d345d05e3ca61ecc + checksum: 2f4777b7bba142a78ce881682b0d012e341a38ec19f8c33ce82eadcab626ae032fb587e9ea9c75e5acf8cfd5eb53d2e70b424ab315d3421dab7c621835164ef9 languageName: node linkType: hard @@ -4612,749 +4131,249 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.50.2" +"@rollup/rollup-android-arm-eabi@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.46.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-android-arm64@npm:4.50.2" +"@rollup/rollup-android-arm64@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-android-arm64@npm:4.46.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-darwin-arm64@npm:4.50.2" +"@rollup/rollup-darwin-arm64@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.46.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-darwin-x64@npm:4.50.2" +"@rollup/rollup-darwin-x64@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.46.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.50.2" +"@rollup/rollup-freebsd-arm64@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.46.2" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-freebsd-x64@npm:4.50.2" +"@rollup/rollup-freebsd-x64@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-freebsd-x64@npm:4.46.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.2" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.46.2" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.50.2" +"@rollup/rollup-linux-arm-musleabihf@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.46.2" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.50.2" +"@rollup/rollup-linux-arm64-gnu@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.46.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.50.2" +"@rollup/rollup-linux-arm64-musl@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.46.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loong64-gnu@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.50.2" +"@rollup/rollup-linux-loongarch64-gnu@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.46.2" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-ppc64-gnu@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.50.2" +"@rollup/rollup-linux-ppc64-gnu@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.46.2" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.50.2" +"@rollup/rollup-linux-riscv64-gnu@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.46.2" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.50.2" +"@rollup/rollup-linux-riscv64-musl@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.46.2" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard - -"@rollup/rollup-linux-s390x-gnu@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.50.2" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-x64-gnu@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.50.2" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@rollup/rollup-linux-x64-musl@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.50.2" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@rollup/rollup-openharmony-arm64@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-openharmony-arm64@npm:4.50.2" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@rollup/rollup-win32-arm64-msvc@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.50.2" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@rollup/rollup-win32-ia32-msvc@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.50.2" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@rollup/rollup-win32-x64-msvc@npm:4.50.2": - version: 4.50.2 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.50.2" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@rtsao/scc@npm:^1.1.0": - version: 1.1.0 - resolution: "@rtsao/scc@npm:1.1.0" - checksum: 17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 - languageName: node - linkType: hard - -"@rushstack/eslint-patch@npm:^1.1.0": - version: 1.12.0 - resolution: "@rushstack/eslint-patch@npm:1.12.0" - checksum: 186788a93e2f141f622696091a593727fe7964d4925236a308e29754e29dcb182377f8d292ae954d227fb0574433863af055c0156593a40fd525e88b76e891ec - languageName: node - linkType: hard - -"@sinclair/typebox@npm:^0.24.1": - version: 0.24.51 - resolution: "@sinclair/typebox@npm:0.24.51" - checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0 - languageName: node - linkType: hard - -"@sinclair/typebox@npm:^0.27.8": - version: 0.27.8 - resolution: "@sinclair/typebox@npm:0.27.8" - checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 - languageName: node - linkType: hard - -"@sinonjs/commons@npm:^1.7.0": - version: 1.8.6 - resolution: "@sinonjs/commons@npm:1.8.6" - dependencies: - type-detect: 4.0.8 - checksum: 7d3f8c1e85f30cd4e83594fc19b7a657f14d49eb8d95a30095631ce15e906c869e0eff96c5b93dffea7490c00418b07f54582ba49c6560feb2a8c34c0b16832d - languageName: node - linkType: hard - -"@sinonjs/fake-timers@npm:^8.0.1": - version: 8.1.0 - resolution: "@sinonjs/fake-timers@npm:8.1.0" - dependencies: - "@sinonjs/commons": ^1.7.0 - checksum: 09b5a158ce013a6c37613258bad79ca4efeb99b1f59c41c73cca36cac00b258aefcf46eeea970fccf06b989414d86fe9f54c1102272c0c3bdd51a313cea80949 - languageName: node - linkType: hard - -"@slack/events-api@npm:^3.0.1": - version: 3.0.1 - resolution: "@slack/events-api@npm:3.0.1" - dependencies: - "@types/debug": ^4.1.4 - "@types/express": ^4.17.0 - "@types/lodash.isstring": ^4.0.6 - "@types/node": ">=12.13.0 < 13" - "@types/yargs": ^15.0.4 - debug: ^2.6.1 - express: ^4.0.0 - lodash.isstring: ^4.0.1 - raw-body: ^2.3.3 - tsscmp: ^1.0.6 - yargs: ^15.3.1 - dependenciesMeta: - express: - optional: true - bin: - slack-verify: dist/verify.js - checksum: ce62dc2ee9dd93b88820e18f88f543228740243dc390caf49b3a7e1ad351b298e3961898bd78f5eb43e9f6acac067458257cd34c9661089f684bb5cf4af468c3 - languageName: node - linkType: hard - -"@slack/logger@npm:^4.0.0": - version: 4.0.0 - resolution: "@slack/logger@npm:4.0.0" - dependencies: - "@types/node": ">=18.0.0" - checksum: dc79e9d2032c4bf9ce01d96cc72882f003dd376d036f172d4169662cfc2c9b384a80d5546b06021578dd473e7059f064303f0ba851eeb153387f2081a1e3062e - languageName: node - linkType: hard - -"@slack/types@npm:^2.9.0": - version: 2.16.0 - resolution: "@slack/types@npm:2.16.0" - checksum: f1db2b8c18af245f78d5c178d98ed57fa5c8c18a1ea2e922bc0d330178a483ee7a29834b42a6710ece005789d91266d62195c93e8e2411ca707f8e438442c7f1 - languageName: node - linkType: hard - -"@slack/web-api@npm:^7.8.0": - version: 7.10.0 - resolution: "@slack/web-api@npm:7.10.0" - dependencies: - "@slack/logger": ^4.0.0 - "@slack/types": ^2.9.0 - "@types/node": ">=18.0.0" - "@types/retry": 0.12.0 - axios: ^1.11.0 - eventemitter3: ^5.0.1 - form-data: ^4.0.4 - is-electron: 2.2.2 - is-stream: ^2 - p-queue: ^6 - p-retry: ^4 - retry: ^0.13.1 - checksum: 6aa3f19892713c1efd5ec4dbca493f28725d185de478226b179cc9e8456c5fb7e38dc6092a5a93a6e4ce49e45a6cf2c287d18969b9563b52941db1e1679ecb96 - languageName: node - linkType: hard - -"@smithy/abort-controller@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/abort-controller@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: c05ba27366becd5ad6eddaf648e440efd51ac21c3721f3da8d03d977826a139cbe48f2c5f52be2ef3178c8692e899c568e7c1dba3724a92fbf248a65e3eeb15b - languageName: node - linkType: hard - -"@smithy/config-resolver@npm:^4.2.1, @smithy/config-resolver@npm:^4.2.2": - version: 4.2.2 - resolution: "@smithy/config-resolver@npm:4.2.2" - dependencies: - "@smithy/node-config-provider": ^4.2.2 - "@smithy/types": ^4.5.0 - "@smithy/util-config-provider": ^4.1.0 - "@smithy/util-middleware": ^4.1.1 - tslib: ^2.6.2 - checksum: 9a725596bdb892f07e3797230d26aaa5794ad0a116624ae355249bb8bd88a909d45ece3c788cc50a99d7e7482e8482b0ca1ac304c3d03dfb836c7b3dcf6f7806 - languageName: node - linkType: hard - -"@smithy/core@npm:^3.11.0": - version: 3.11.0 - resolution: "@smithy/core@npm:3.11.0" - dependencies: - "@smithy/middleware-serde": ^4.1.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-body-length-browser": ^4.1.0 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-stream": ^4.3.1 - "@smithy/util-utf8": ^4.1.0 - "@types/uuid": ^9.0.1 - tslib: ^2.6.2 - uuid: ^9.0.1 - checksum: 1e6274090961398776fbc5e00b93bc84d5fe2aff6bf0909c84d0a03a3e384db03d52bd9a7c147cc5834b9c9511db80121d09a3c81497405718d8cff20892ab02 - languageName: node - linkType: hard - -"@smithy/credential-provider-imds@npm:^4.0.7, @smithy/credential-provider-imds@npm:^4.1.2": - version: 4.1.2 - resolution: "@smithy/credential-provider-imds@npm:4.1.2" - dependencies: - "@smithy/node-config-provider": ^4.2.2 - "@smithy/property-provider": ^4.1.1 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - tslib: ^2.6.2 - checksum: b62d2b9362296e3c5dda34144a416e1524283a5c9fc7619fc090ebf41579ca6579e067db50bcd2af55f629680a8019ba2d87348ac870ae02b05cb153c625c6b8 - languageName: node - linkType: hard - -"@smithy/fetch-http-handler@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/fetch-http-handler@npm:5.2.1" - dependencies: - "@smithy/protocol-http": ^5.2.1 - "@smithy/querystring-builder": ^4.1.1 - "@smithy/types": ^4.5.0 - "@smithy/util-base64": ^4.1.0 - tslib: ^2.6.2 - checksum: 68733a2d4a47002c9059af23078712ebc451dacca9542a3f6a70ba2288a017bb474a15ff6c10816c04296011c833d9ad8f957d22eedb33ea3a0edc12ad62160e - languageName: node - linkType: hard - -"@smithy/hash-node@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/hash-node@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - "@smithy/util-buffer-from": ^4.1.0 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: ee0d5ed0355d5551cc8805e55dcca582d75b062c15b5f1cde15a0376b3e0254ef4803a80f16f1c4125a985545e4fa99b4a7021199cc5ffa5457f829056962146 - languageName: node - linkType: hard - -"@smithy/invalid-dependency@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/invalid-dependency@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 039893fddde6786eb0c50c1a7c33768e9b052c5bc36c5ff1bec517290dab06f9e8ddf07323a3ef594f80b30fc4eaeb35bed1e0ef9b7aa9588aa99f169dd02ada - languageName: node - linkType: hard - -"@smithy/is-array-buffer@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/is-array-buffer@npm:2.2.0" - dependencies: - tslib: ^2.6.2 - checksum: cd12c2e27884fec89ca8966d33c9dc34d3234efe89b33a9b309c61ebcde463e6f15f6a02d31d4fddbfd6e5904743524ca5b95021b517b98fe10957c2da0cd5fc - languageName: node - linkType: hard - -"@smithy/is-array-buffer@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/is-array-buffer@npm:4.1.0" - dependencies: - tslib: ^2.6.2 - checksum: 8ab4c920f9f9dc10dadcbc32fef439e9809da8065898ef05007c46c9d4a6494b512240cd25652b8be533f17aee0ce441c412fa0de535128ea7f8e610fda3acbd - languageName: node - linkType: hard - -"@smithy/middleware-content-length@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-content-length@npm:4.1.1" - dependencies: - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: e136bd0f2a95b6baba0d226289bfa430f2cad9180f952d4b8abda49362adbbe02cfed85726dd54d4be3f7e07196e6dffd1af56616ab922b1485571891dae3633 - languageName: node - linkType: hard - -"@smithy/middleware-endpoint@npm:^4.2.1, @smithy/middleware-endpoint@npm:^4.2.2": - version: 4.2.2 - resolution: "@smithy/middleware-endpoint@npm:4.2.2" - dependencies: - "@smithy/core": ^3.11.0 - "@smithy/middleware-serde": ^4.1.1 - "@smithy/node-config-provider": ^4.2.2 - "@smithy/shared-ini-file-loader": ^4.2.0 - "@smithy/types": ^4.5.0 - "@smithy/url-parser": ^4.1.1 - "@smithy/util-middleware": ^4.1.1 - tslib: ^2.6.2 - checksum: e058f390f9f3fd5c14c34d1a95afb31a0185611a68dd4888ea9d70c3291a9e4a627788ba33f7563acdc4d054668ce13c8093830a4bb4badb5c3e0bf4d31d412b - languageName: node - linkType: hard - -"@smithy/middleware-retry@npm:^4.2.1": - version: 4.2.2 - resolution: "@smithy/middleware-retry@npm:4.2.2" - dependencies: - "@smithy/node-config-provider": ^4.2.2 - "@smithy/protocol-http": ^5.2.1 - "@smithy/service-error-classification": ^4.1.1 - "@smithy/smithy-client": ^4.6.2 - "@smithy/types": ^4.5.0 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-retry": ^4.1.1 - "@types/uuid": ^9.0.1 - tslib: ^2.6.2 - uuid: ^9.0.1 - checksum: 57b44854d595a556fe7b5adcea9089edd85cda1c32e4cc59ac03fb71879bcdb1274e4723dcae1604d83fe2780a9ce63b106d6992d3c0daf37bfb675ee17a5af6 - languageName: node - linkType: hard - -"@smithy/middleware-serde@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-serde@npm:4.1.1" - dependencies: - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: e0f6d3895ec83b2e70a8282d058c1862d73ed4d6a2ca878cda6c97b439e52bf3df3f3b4c44e7749262cdf87e5e7c30d10f1fb081ade79689cf0ac17061cf447b - languageName: node - linkType: hard - -"@smithy/middleware-stack@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/middleware-stack@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 9046afc321356a8d26d1db41a700a5ac0d9d370d561725c0bb9239db7aaa2ad02b3747998da6497238a3c4bd7169cbbf8bd4936c123f0fc219c4b17611a663ea - languageName: node - linkType: hard - -"@smithy/node-config-provider@npm:^4.2.1, @smithy/node-config-provider@npm:^4.2.2": - version: 4.2.2 - resolution: "@smithy/node-config-provider@npm:4.2.2" - dependencies: - "@smithy/property-provider": ^4.1.1 - "@smithy/shared-ini-file-loader": ^4.2.0 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 671845a3d00b53ee0fa2c97e4345cfd2ade99945aec6d47c0545e5366d5332aed774b4d84774924dec26a0ed92de1df139619426f9d0e34ac0afdd40cea2fba7 - languageName: node - linkType: hard - -"@smithy/node-http-handler@npm:^4.2.1": - version: 4.2.1 - resolution: "@smithy/node-http-handler@npm:4.2.1" - dependencies: - "@smithy/abort-controller": ^4.1.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/querystring-builder": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 93d006a5908b41cf8bb9b4564c4f2274825db44755dd6949490405e859419cba73afd6c34de93a4e2ee4ef7cc2524a91853fbcca16261ab302b1bd08e73694c9 - languageName: node - linkType: hard - -"@smithy/property-provider@npm:^4.0.5, @smithy/property-provider@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/property-provider@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 0173716227d82d50845121202dc157dd23e75786d3ab994ea91666e2441a66c972c27e71d67992688a10b7ca4e988a7b809668d20c0c35a66a39c824842fd6ee - languageName: node - linkType: hard - -"@smithy/protocol-http@npm:^5.2.1": - version: 5.2.1 - resolution: "@smithy/protocol-http@npm:5.2.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 6a8509a7fd38a039e6db10d372f0698ea841fe73c49cb7f03a7718ff2b5e60776f4f3a9d7658020f9ad981917ce46e40d7d38fbd8675330031d6483ef3aafc42 - languageName: node - linkType: hard - -"@smithy/querystring-builder@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/querystring-builder@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - "@smithy/util-uri-escape": ^4.1.0 - tslib: ^2.6.2 - checksum: 01d7ff1a21547a8a7e687ebcb7f2b9c94c8cd62403e1c5e88fab340c7e5bc11162e66b08d1b75876c7221e352272e33dd2066a19e270171f8eb63bbf6a1d92a6 - languageName: node - linkType: hard - -"@smithy/querystring-parser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/querystring-parser@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: b70f09e2a778a6037d9ff3e9c67707d4744dba4d0f760b9e79a0d4469ff6f68d493d1c3d4104441de040cf8ab6e15acc06ae5dbba7a30a418306af3771117cba - languageName: node - linkType: hard - -"@smithy/service-error-classification@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/service-error-classification@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - checksum: 7d8bc8fa9faf4047b8386e45e74f033feedd8824483ab8ab9a37046405a6a5c15cf66d1f7e32a179336b415974d1b55b750727c823d55b288618793dfefb0633 - languageName: node - linkType: hard - -"@smithy/shared-ini-file-loader@npm:^4.0.5, @smithy/shared-ini-file-loader@npm:^4.2.0": - version: 4.2.0 - resolution: "@smithy/shared-ini-file-loader@npm:4.2.0" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: d89d2b620575f9b8d255c39a28f6b76accba57e79b164e490aab801c61744819e2164c7d26f6c986dc38366e08659896dbba58ea7c179a95fc18398d934cc821 - languageName: node - linkType: hard - -"@smithy/signature-v4@npm:^5.1.3": - version: 5.2.1 - resolution: "@smithy/signature-v4@npm:5.2.1" - dependencies: - "@smithy/is-array-buffer": ^4.1.0 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-hex-encoding": ^4.1.0 - "@smithy/util-middleware": ^4.1.1 - "@smithy/util-uri-escape": ^4.1.0 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: d609451fead77465d04b3d2fb614cfd51c5c66020429ecf97c871952e70d0cacb9d4ff8b15271cc7b38fcfa852b3d141e1811804ecab0eb522cadb9d43f3c10c - languageName: node - linkType: hard - -"@smithy/smithy-client@npm:^4.6.1, @smithy/smithy-client@npm:^4.6.2": - version: 4.6.2 - resolution: "@smithy/smithy-client@npm:4.6.2" - dependencies: - "@smithy/core": ^3.11.0 - "@smithy/middleware-endpoint": ^4.2.2 - "@smithy/middleware-stack": ^4.1.1 - "@smithy/protocol-http": ^5.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-stream": ^4.3.1 - tslib: ^2.6.2 - checksum: a1a6510dcc075c7055852d8ba8c3f69bd3fa93aad45d3659bb63a0d20d043a2628ed6a8ca75034ae69f23ed3a32d6252dd45ef5b396d285245c57ed143138e70 - languageName: node - linkType: hard - -"@smithy/types@npm:^4.5.0": - version: 4.5.0 - resolution: "@smithy/types@npm:4.5.0" - dependencies: - tslib: ^2.6.2 - checksum: 5fb38dcf554e8ecf3654cbcc295fffcf35517f7e792ed158f4119223982f57d4e3ec79ad56e8e9a590c8843990bef217da8a88e02e197ee7f6d4737abcc9c075 - languageName: node - linkType: hard - -"@smithy/url-parser@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/url-parser@npm:4.1.1" - dependencies: - "@smithy/querystring-parser": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 189d60c99b3610bb4be2f32474551e4431273891093232f38553a27541ba1379df70a625b83390f259aafbddb3307e531b8210148c854eb39763e2d0e5ec3769 - languageName: node - linkType: hard - -"@smithy/util-base64@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-base64@npm:4.1.0" - dependencies: - "@smithy/util-buffer-from": ^4.1.0 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: 8855de07897631f835fc47b9c17938a5e927291ce6ef08cfd1424431333fc4c4797c18e2094790c5331388f39bd5ed0a76a913e9b7f3c7f61c0e228bf18a3cf9 - languageName: node - linkType: hard - -"@smithy/util-body-length-browser@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-body-length-browser@npm:4.1.0" - dependencies: - tslib: ^2.6.2 - checksum: 7aa162eb084ffeb7b0b6d504494e248e7da72447f08cda02120d5594ddb146544dcee19b92d6e57dc3115372e2ce018147692e44c7cb1498f634a3fa17d22aa9 + +"@rollup/rollup-linux-s390x-gnu@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.46.2" + conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-body-length-node@npm:4.1.0" - dependencies: - tslib: ^2.6.2 - checksum: dfaf22fd6fc086544f582dd5c64a4416c01bad8b92f5891add84b9086a9b0a8815659269c91b8adee7ef3b36f21701c6aaab2313bfbe21a2c189eb15943a0c25 +"@rollup/rollup-linux-x64-gnu@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.46.2" + conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@smithy/util-buffer-from@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-buffer-from@npm:2.2.0" - dependencies: - "@smithy/is-array-buffer": ^2.2.0 - tslib: ^2.6.2 - checksum: 424c5b7368ae5880a8f2732e298d17879a19ca925f24ca45e1c6c005f717bb15b76eb28174d308d81631ad457ea0088aab0fd3255dd42f45a535c81944ad64d3 +"@rollup/rollup-linux-x64-musl@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.46.2" + conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@smithy/util-buffer-from@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-buffer-from@npm:4.1.0" - dependencies: - "@smithy/is-array-buffer": ^4.1.0 - tslib: ^2.6.2 - checksum: a8523e142cfa8a5526ada1bb2f4264c7dc6027875a16752995324c294ea6b2bd502303db16ac74eb49fe602f20d847cdb09054d611e3aa9916c09b7a41e379c0 +"@rollup/rollup-win32-arm64-msvc@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.46.2" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@smithy/util-config-provider@npm:^4.0.0, @smithy/util-config-provider@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-config-provider@npm:4.1.0" - dependencies: - tslib: ^2.6.2 - checksum: 8d13ec9246b05bc3b8af9312ba53d266cb9fff6400957630e3288ed1807c6fb433a7383df385282b84f699f112653069008b9c972e520393a4fed88d19a2e8e3 +"@rollup/rollup-win32-ia32-msvc@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.46.2" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^4.1.1": - version: 4.1.2 - resolution: "@smithy/util-defaults-mode-browser@npm:4.1.2" - dependencies: - "@smithy/property-provider": ^4.1.1 - "@smithy/smithy-client": ^4.6.2 - "@smithy/types": ^4.5.0 - bowser: ^2.11.0 - tslib: ^2.6.2 - checksum: 78a4e34c47e8df6ad0363be3eddc2fe47465cfb9c2cc373a17f724f914f402c33811a69ff7d00b8aefb53e91911eb1b404f02c3f0a571fed945bb91f65e907f3 +"@rollup/rollup-win32-x64-msvc@npm:4.46.2": + version: 4.46.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.46.2" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^4.1.1": - version: 4.1.2 - resolution: "@smithy/util-defaults-mode-node@npm:4.1.2" - dependencies: - "@smithy/config-resolver": ^4.2.2 - "@smithy/credential-provider-imds": ^4.1.2 - "@smithy/node-config-provider": ^4.2.2 - "@smithy/property-provider": ^4.1.1 - "@smithy/smithy-client": ^4.6.2 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 41499f7b5161e38b60888274504cdde86baede02f8000f0ebc63d42013fd945719ffd254bed87205f41ff54f6c489123ea3caee3457efcdeec0bfb734553cd26 +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 languageName: node linkType: hard -"@smithy/util-endpoints@npm:^3.1.1": - version: 3.1.2 - resolution: "@smithy/util-endpoints@npm:3.1.2" - dependencies: - "@smithy/node-config-provider": ^4.2.2 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: fc024b99eee4d1157bd6edc5ae45f7ced9dba2e1ee978ed963bad0bef379f15e664e864989e3177c362d55a26b0dee52b32803023e04954206a3e8c22cdb8a2a +"@rushstack/eslint-patch@npm:^1.1.0": + version: 1.12.0 + resolution: "@rushstack/eslint-patch@npm:1.12.0" + checksum: 186788a93e2f141f622696091a593727fe7964d4925236a308e29754e29dcb182377f8d292ae954d227fb0574433863af055c0156593a40fd525e88b76e891ec languageName: node linkType: hard -"@smithy/util-hex-encoding@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-hex-encoding@npm:4.1.0" - dependencies: - tslib: ^2.6.2 - checksum: 0005c0569a18edc9a6fe991acca95c35e1bfecaf7bb4a9ed2a54eed249e7ccc3662c7d5e3c995db5c47dece9841690f56c4cb93b5adc8681c9436dd7cb8ebff5 +"@sinclair/typebox@npm:^0.24.1": + version: 0.24.51 + resolution: "@sinclair/typebox@npm:0.24.51" + checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0 languageName: node linkType: hard -"@smithy/util-middleware@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-middleware@npm:4.1.1" - dependencies: - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 9f8dc9f29730f70c0575920f9f88073af0c8359e1e0a4114a60834cf1053f6ee8df687814f8f4f9b87a02a591a2a3592ffa2b0d7b93234309fe1cdc52cd51e3a +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 languageName: node linkType: hard -"@smithy/util-retry@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-retry@npm:4.1.1" +"@sinonjs/commons@npm:^1.7.0": + version: 1.8.6 + resolution: "@sinonjs/commons@npm:1.8.6" dependencies: - "@smithy/service-error-classification": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: 7ed26ae7b9cd810752f692c749bb8ad083c8fd5000cfd00c9c917806156486b84afb7b8fcf968395b84b3552a6bf46562ec479b97ab4f0cb9d4b121958f1cd5f + type-detect: 4.0.8 + checksum: 7d3f8c1e85f30cd4e83594fc19b7a657f14d49eb8d95a30095631ce15e906c869e0eff96c5b93dffea7490c00418b07f54582ba49c6560feb2a8c34c0b16832d languageName: node linkType: hard -"@smithy/util-stream@npm:^4.3.1": - version: 4.3.1 - resolution: "@smithy/util-stream@npm:4.3.1" +"@sinonjs/fake-timers@npm:^8.0.1": + version: 8.1.0 + resolution: "@sinonjs/fake-timers@npm:8.1.0" dependencies: - "@smithy/fetch-http-handler": ^5.2.1 - "@smithy/node-http-handler": ^4.2.1 - "@smithy/types": ^4.5.0 - "@smithy/util-base64": ^4.1.0 - "@smithy/util-buffer-from": ^4.1.0 - "@smithy/util-hex-encoding": ^4.1.0 - "@smithy/util-utf8": ^4.1.0 - tslib: ^2.6.2 - checksum: a1b73d9f39811065729bd7304a6deaceea99ddb2f736fb5b95c20d3db53f84e4e53f956c358d95fa747967488b2193b581e96ed75d841164cdb5176fef928eb8 + "@sinonjs/commons": ^1.7.0 + checksum: 09b5a158ce013a6c37613258bad79ca4efeb99b1f59c41c73cca36cac00b258aefcf46eeea970fccf06b989414d86fe9f54c1102272c0c3bdd51a313cea80949 languageName: node linkType: hard -"@smithy/util-uri-escape@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-uri-escape@npm:4.1.0" +"@slack/events-api@npm:^3.0.1": + version: 3.0.1 + resolution: "@slack/events-api@npm:3.0.1" dependencies: - tslib: ^2.6.2 - checksum: 0c55f4981af8be1a67fdd154497d41b3ea130da2a409b06a5e899d5f86b498fe4e5b9c065ee018379b976d74ae9aaf45180548e0d96bf7e474fb039da667aac6 + "@types/debug": ^4.1.4 + "@types/express": ^4.17.0 + "@types/lodash.isstring": ^4.0.6 + "@types/node": ">=12.13.0 < 13" + "@types/yargs": ^15.0.4 + debug: ^2.6.1 + express: ^4.0.0 + lodash.isstring: ^4.0.1 + raw-body: ^2.3.3 + tsscmp: ^1.0.6 + yargs: ^15.3.1 + dependenciesMeta: + express: + optional: true + bin: + slack-verify: dist/verify.js + checksum: ce62dc2ee9dd93b88820e18f88f543228740243dc390caf49b3a7e1ad351b298e3961898bd78f5eb43e9f6acac067458257cd34c9661089f684bb5cf4af468c3 languageName: node linkType: hard -"@smithy/util-utf8@npm:^2.0.0": - version: 2.3.0 - resolution: "@smithy/util-utf8@npm:2.3.0" +"@slack/logger@npm:^4.0.0": + version: 4.0.0 + resolution: "@slack/logger@npm:4.0.0" dependencies: - "@smithy/util-buffer-from": ^2.2.0 - tslib: ^2.6.2 - checksum: 00e55d4b4e37d48be0eef3599082402b933c52a1407fed7e8e8ad76d94d81a0b30b8bfaf2047c59d9c3af31e5f20e7a8c959cb7ae270f894255e05a2229964f0 + "@types/node": ">=18.0.0" + checksum: dc79e9d2032c4bf9ce01d96cc72882f003dd376d036f172d4169662cfc2c9b384a80d5546b06021578dd473e7059f064303f0ba851eeb153387f2081a1e3062e languageName: node linkType: hard -"@smithy/util-utf8@npm:^4.1.0": - version: 4.1.0 - resolution: "@smithy/util-utf8@npm:4.1.0" - dependencies: - "@smithy/util-buffer-from": ^4.1.0 - tslib: ^2.6.2 - checksum: 3a5a1420a5f06bfcc1c15935344f245ea5d297c0d021c52589cb7125fe5a3546e69cedf37940fd84962405116d59c81f56d1adb463105715f4b534f0fe3bf9db +"@slack/types@npm:^2.9.0": + version: 2.15.0 + resolution: "@slack/types@npm:2.15.0" + checksum: 9c7e719d91fb206d936ab7802277141cbfeb55501ecc9f64d4b396b014ffc4fd9d1608ec957c24cf83212e5985542e1c87ec5ad5ae0abeddc00190a7a1d9b9b6 languageName: node linkType: hard -"@smithy/util-waiter@npm:^4.1.1": - version: 4.1.1 - resolution: "@smithy/util-waiter@npm:4.1.1" +"@slack/web-api@npm:^7.8.0": + version: 7.9.3 + resolution: "@slack/web-api@npm:7.9.3" dependencies: - "@smithy/abort-controller": ^4.1.1 - "@smithy/types": ^4.5.0 - tslib: ^2.6.2 - checksum: f4d16ee1cbcc34a2519e835f70b4e3430fe1bbff611e30951ea83ed997ee6a6c01a3189e4e8c8c2bae441520622f03c6324bd4decac77b02f7001637f26cf83a + "@slack/logger": ^4.0.0 + "@slack/types": ^2.9.0 + "@types/node": ">=18.0.0" + "@types/retry": 0.12.0 + axios: ^1.8.3 + eventemitter3: ^5.0.1 + form-data: ^4.0.0 + is-electron: 2.2.2 + is-stream: ^2 + p-queue: ^6 + p-retry: ^4 + retry: ^0.13.1 + checksum: a683d92496f0f654cc5e6e8daf6618d27b2a844ea9195ae49d689ae1602b1077920e960e19bb6f85dcd71106db0101d82037dd6b3202f41eddc9a605d90d5e75 languageName: node linkType: hard @@ -5518,16 +4537,17 @@ __metadata: linkType: hard "@testing-library/jest-dom@npm:^6.6.3": - version: 6.8.0 - resolution: "@testing-library/jest-dom@npm:6.8.0" + version: 6.6.4 + resolution: "@testing-library/jest-dom@npm:6.6.4" dependencies: "@adobe/css-tools": ^4.4.0 aria-query: ^5.0.0 css.escape: ^1.5.1 dom-accessibility-api: ^0.6.3 + lodash: ^4.17.21 picocolors: ^1.1.1 redent: ^3.0.0 - checksum: a3cfb162b6ec6e98277187d9488234ba3e3ee25f24a86facdae092dbe54a015c845bcb81daa6de7afadcac5a5fe25becd7c7e9b67bb01ee4ccf7d67ee907adc9 + checksum: 45c8be7b4a577d926210ff10a444dcc5a40132ff6865512406b76c2768d0530c0b3c4d6babccf97c63108bd8b59d1fab58fab08b02452d286be76320323d91be languageName: node linkType: hard @@ -5761,9 +4781,9 @@ __metadata: linkType: hard "@types/d3-array@npm:^3.0.3": - version: 3.2.2 - resolution: "@types/d3-array@npm:3.2.2" - checksum: 72e8e2abe0911cb431d6f3fe0a1f71b915356b679d4d9c826f52941bb30210c0fe8299dde066b08d9986754c620f031b13b13ab6dfc60d404eceab66a075dd5d + version: 3.2.1 + resolution: "@types/d3-array@npm:3.2.1" + checksum: 8a41cee0969e53bab3f56cc15c4e6c9d76868d6daecb2b7d8c9ce71e0ececccc5a8239697cc52dadf5c665f287426de5c8ef31a49e7ad0f36e8846889a383df4 languageName: node linkType: hard @@ -6133,20 +5153,20 @@ __metadata: linkType: hard "@types/node-forge@npm:^1.3.0": - version: 1.3.14 - resolution: "@types/node-forge@npm:1.3.14" + version: 1.3.13 + resolution: "@types/node-forge@npm:1.3.13" dependencies: "@types/node": "*" - checksum: ff621803390e723e56b289a89fca3a06f9f8b438add1b843203a0f64bcbc7ac03d457136b3c15010b5bc89d81f57b35f62964e6e980f6290597bb21b4463c009 + checksum: dee446d958e7098c8ad74076843d27cb46908632cf289f732ccc5c0a2c1e62927df44d22725bd37a84579ea3336e52b4c064385c53e22b741e277d07c9da20cb languageName: node linkType: hard "@types/node@npm:*, @types/node@npm:>=18.0.0": - version: 24.5.0 - resolution: "@types/node@npm:24.5.0" + version: 24.2.1 + resolution: "@types/node@npm:24.2.1" dependencies: - undici-types: ~7.12.0 - checksum: ae97c80b1edce278b3e0b5d8ad432b545b850b4b21a43b1202fae66b5d35f0a38c5e1b8eb2006225929c600f458daec6c1654f72a02bab6fe6414e3b35140d99 + undici-types: ~7.10.0 + checksum: d7a12a35bcb6ade13787bd9b40d8f59b96170f228dfbd19326170b4df2a66ae86cf21eec6867e92f979405235431e580a9668b167aa3ce8e89531c00792551d3 languageName: node linkType: hard @@ -6172,21 +5192,20 @@ __metadata: linkType: hard "@types/node@npm:^20.0.0": - version: 20.19.15 - resolution: "@types/node@npm:20.19.15" + version: 20.19.10 + resolution: "@types/node@npm:20.19.10" dependencies: undici-types: ~6.21.0 - checksum: 02d7327b6bd3778247e5882c4a236364103b30f883b7f03243e83c882ff257e14d15c2b4dab8b4862548d45541b4f708e3aa565520a042dd242ab7d0d2b63968 + checksum: e294ec0d37ce5a1ae9e4c255ef837b584d793a4d2f89472d580024a4c008de0d5df595c919e96e95fcdf56bf55d567213f90c0c5874b369a30526bedfaa3f418 languageName: node linkType: hard "@types/nodemailer@npm:^6.4.0": - version: 6.4.19 - resolution: "@types/nodemailer@npm:6.4.19" + version: 6.4.17 + resolution: "@types/nodemailer@npm:6.4.17" dependencies: - "@aws-sdk/client-ses": ^3.731.1 "@types/node": "*" - checksum: 7f449db31d8c0b150da554158e04d9fd631832ff2c01cc7c906ec9619a5295d7f525db959bfd3fc0eb451f386dd052ddbcbe1a337e3f776a3d9d554701a9df53 + checksum: 498b702575111494a42cf9cdd3d399f0308c3b3b0244e7f53008924327955a16b39ba0bf99a5ccf17af9fd2bc50a61a76ae7e8a75498a426ea2f828a05202eab languageName: node linkType: hard @@ -6316,9 +5335,9 @@ __metadata: linkType: hard "@types/semver@npm:^7.3.12": - version: 7.7.1 - resolution: "@types/semver@npm:7.7.1" - checksum: 76d218e414482a398148d5c28f2bfa017108869f3fc18cda379c9d8d062348f8b9653ae2fa8642d3b5b52e211928fe8be34f22da4e1f08245c84e0e51e040673 + version: 7.7.0 + resolution: "@types/semver@npm:7.7.0" + checksum: d488eaeddb23879a0a8a759bed667e1a76cb0dd4d23e3255538e24c189db387357953ca9e7a3bda2bb7f95e84cac8fe0db4fbe6b3456e893043337732d1d23cc languageName: node linkType: hard @@ -6396,6 +5415,13 @@ __metadata: languageName: node linkType: hard +"@types/tough-cookie@npm:^4.0.5": + version: 4.0.5 + resolution: "@types/tough-cookie@npm:4.0.5" + checksum: f19409d0190b179331586365912920d192733112a195e870c7f18d20ac8adb7ad0b0ff69dad430dba8bc2be09593453a719cfea92dc3bda19748fd158fe1498d + languageName: node + linkType: hard + "@types/trusted-types@npm:^2.0.2": version: 2.0.7 resolution: "@types/trusted-types@npm:2.0.7" @@ -6431,13 +5457,6 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:^9.0.1": - version: 9.0.8 - resolution: "@types/uuid@npm:9.0.8" - checksum: b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 - languageName: node - linkType: hard - "@types/ws@npm:^8.5.5": version: 8.18.1 resolution: "@types/ws@npm:8.18.1" @@ -7164,7 +6183,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.9.0": +"acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.9.0": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -7271,7 +6290,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.1": +"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.1, ansi-escapes@npm:^4.3.2": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -7306,9 +6325,9 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.2.2 - resolution: "ansi-regex@npm:6.2.2" - checksum: 9b17ce2c6daecc75bcd5966b9ad672c23b184dc3ed9bf3c98a0702f0d2f736c15c10d461913568f2cf527a5e64291c7473358885dd493305c84a1cfed66ba94f + version: 6.1.0 + resolution: "ansi-regex@npm:6.1.0" + checksum: 495834a53b0856c02acd40446f7130cb0f8284f4a39afdab20d5dc42b2e198b1196119fe887beed8f9055c4ff2055e3b2f6d4641d0be018cdfb64fedf6fc1aac languageName: node linkType: hard @@ -7338,9 +6357,9 @@ __metadata: linkType: hard "ansi-styles@npm:^6.1.0": - version: 6.2.3 - resolution: "ansi-styles@npm:6.2.3" - checksum: f1b0829cf048cce870a305819f65ce2adcebc097b6d6479e12e955fd6225df9b9eb8b497083b764df796d94383ff20016cc4dbbae5b40f36138fb65a9d33c2e2 + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 languageName: node linkType: hard @@ -7648,14 +6667,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.11.0, axios@npm:^1.7.9": - version: 1.12.2 - resolution: "axios@npm:1.12.2" +"axios@npm:^1.7.9, axios@npm:^1.8.3": + version: 1.11.0 + resolution: "axios@npm:1.11.0" dependencies: follow-redirects: ^1.15.6 form-data: ^4.0.4 proxy-from-env: ^1.1.0 - checksum: f0331594fe053a4bbff04104edb073973a3aabfad2e56b0aa18de82428aa63f6f0839ca3d837258ec739cb4528014121793b1649a21e5115ffb2bf8237eadca3 + checksum: 0a33dc600b588bfd3111b198d5985527ed89f722817455d7cdb66c1d055e5f8859cc2bebb7320888957fc8458ebe77d5f83af02af9cd260217c91c4e92b6dfb6 languageName: node linkType: hard @@ -7911,15 +6930,6 @@ __metadata: languageName: node linkType: hard -"baseline-browser-mapping@npm:^2.8.3": - version: 2.8.4 - resolution: "baseline-browser-mapping@npm:2.8.4" - bin: - baseline-browser-mapping: dist/cli.js - checksum: c9580e27141fdaff3ad219a14906774c80a040f45527213d867ce8a2db02a60cf1db545041bfb69a9482c3101c5a0cd3cef1155cde3f1ba8e98bf817667756c5 - languageName: node - linkType: hard - "batch@npm:0.6.1": version: 0.6.1 resolution: "batch@npm:0.6.1" @@ -8041,18 +7051,11 @@ __metadata: linkType: hard "bootstrap@npm:^5.3.0": - version: 5.3.8 - resolution: "bootstrap@npm:5.3.8" + version: 5.3.7 + resolution: "bootstrap@npm:5.3.7" peerDependencies: "@popperjs/core": ^2.11.8 - checksum: 6813254a1140646ca53f33f2d0c5fbf7cf544dabba06cddc061243acf4ec71fadff348860ed4623e1b486c05c151d7807da017dc473e748add0926d2cf9f1a04 - languageName: node - linkType: hard - -"bowser@npm:^2.11.0": - version: 2.12.1 - resolution: "bowser@npm:2.12.1" - checksum: 994a3da9e9b628892e0fbc4fd5afeec672003a9a72300ec8ac832f6707ba6ce68d137d50316f08e6197f9e0cca5c486aa4b9ce9db50013061225cab4e432f8a0 + checksum: ac3ebcbdd37caed60cf515953a007af31265548271471ab1aff070cd4ad2aa3ec215b25144b3172882953ad107fe04548fe0bb6c71fcde95153b8605c564173c languageName: node linkType: hard @@ -8107,18 +7110,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.25.3": - version: 4.26.2 - resolution: "browserslist@npm:4.26.2" +"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4, browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.25.1": + version: 4.25.2 + resolution: "browserslist@npm:4.25.2" dependencies: - baseline-browser-mapping: ^2.8.3 - caniuse-lite: ^1.0.30001741 - electron-to-chromium: ^1.5.218 - node-releases: ^2.0.21 + caniuse-lite: ^1.0.30001733 + electron-to-chromium: ^1.5.199 + node-releases: ^2.0.19 update-browserslist-db: ^1.1.3 bin: browserslist: cli.js - checksum: ebd96e8895cdfc72be074281eb377332b69ceb944ec0c063739d8eeb8e513b168ac1e27d26ce5cc260e69a340a44c6bb5e9408565449d7a16739e5844453d4c7 + checksum: 104f151563a797f95cda7ae862938939c41b89975960cba4615a389238cdd98dcf2ec4ea804c97374c39457f1f476bc58cfd2826fdccff5dba91e2ca45f5b1b3 languageName: node linkType: hard @@ -8298,21 +7300,21 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001741": - version: 1.0.30001743 - resolution: "caniuse-lite@npm:1.0.30001743" - checksum: 9e203fe09158b011bd4a6707f6e5f9ad040e5b4093b12e2e047636a71d6e2e3bf5209aae42f213251cc812d9091188d7f1da7bd4785bc0b879beb98f9aa04ebc +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001733": + version: 1.0.30001733 + resolution: "caniuse-lite@npm:1.0.30001733" + checksum: cf9d0701ef5617231072be7db74a077ac7a453c8672fe0f17df14aee73f8f253b42cd0d95e1f150ff73453edb115b7131e98b416070b798c8f41b25606f15292 languageName: node linkType: hard "canvas@npm:^3.0.0-rc2": - version: 3.2.0 - resolution: "canvas@npm:3.2.0" + version: 3.1.2 + resolution: "canvas@npm:3.1.2" dependencies: node-addon-api: ^7.0.0 node-gyp: latest prebuild-install: ^7.1.3 - checksum: 68c7fe3c0c79efb3358d4ab4b04586068fefe06c7137e6636111ae91e68122ac069f05d883fdf11eb7fd08eba841096cb700324d02efca7abbf92d3476c567e4 + checksum: 12de08247fb90f9e442ea4c04b47dffac0b66a58587619bc354495195168063d8d1a870c52bd35b17a95697bb0e99c4cb562d9fc9752bf11b7ba2e5b81eb5ba9 languageName: node linkType: hard @@ -8342,15 +7344,15 @@ __metadata: linkType: hard "chai@npm:^5.1.2, chai@npm:^5.2.0": - version: 5.3.3 - resolution: "chai@npm:5.3.3" + version: 5.2.1 + resolution: "chai@npm:5.2.1" dependencies: assertion-error: ^2.0.1 check-error: ^2.1.1 deep-eql: ^5.0.1 loupe: ^3.1.0 pathval: ^2.0.0 - checksum: bc4091f1cccfee63f6a3d02ce477fe847f5c57e747916a11bd72675c9459125084e2e55dc2363ee2b82b088a878039ee7ee27c75d6d90f7de9202bf1b12ce573 + checksum: 15e2923de73bc4a361fa016b3322c8258c1ec7a33794f6dfa8000b4cd7fb64521363e59fcf08b90b9dd2d787b25ac9e2420535ce31c530501296d4bc03b48576 languageName: node linkType: hard @@ -8794,19 +7796,20 @@ __metadata: linkType: hard "concurrently@npm:^9.1.0": - version: 9.2.1 - resolution: "concurrently@npm:9.2.1" + version: 9.2.0 + resolution: "concurrently@npm:9.2.0" dependencies: - chalk: 4.1.2 - rxjs: 7.8.2 - shell-quote: 1.8.3 - supports-color: 8.1.1 - tree-kill: 1.2.2 - yargs: 17.7.2 + chalk: ^4.1.2 + lodash: ^4.17.21 + rxjs: ^7.8.1 + shell-quote: ^1.8.1 + supports-color: ^8.1.1 + tree-kill: ^1.2.2 + yargs: ^17.7.2 bin: conc: dist/bin/concurrently.js concurrently: dist/bin/concurrently.js - checksum: 95c6cdde21b6304d53005d872318805f69e153d4cedfd4d720cc5776f56fbd073b38297cfe56bacfc8fbdba9b6c38ac1233739abd25b023761fd03b896a4cea5 + checksum: a138458968c791e0c5719771d3181c5add8b865beebf19fae43365ab4d49ac79de634de29ef150697e3aaf1145f27dcf634910bdc2bcb779c5dd92621607b854 languageName: node linkType: hard @@ -8920,25 +7923,25 @@ __metadata: linkType: hard "core-js-compat@npm:^3.43.0": - version: 3.45.1 - resolution: "core-js-compat@npm:3.45.1" + version: 3.45.0 + resolution: "core-js-compat@npm:3.45.0" dependencies: - browserslist: ^4.25.3 - checksum: 817286f6b7deb90278fd1f46131664fda36b74983e2fc4859a36ae85ef9361868b307964eea0e364251763e415eab7589e9abe2a4ec4d1672c2870f03c52b1ac + browserslist: ^4.25.1 + checksum: 98808620626b761eb4772cb8719d959289e9a9127d4fd4d2e3e78aa8341c4935bdc395883134c9419f718776222c0d3eda1ae2337e67e171388e4547d3097b51 languageName: node linkType: hard "core-js-pure@npm:^3.23.3": - version: 3.45.1 - resolution: "core-js-pure@npm:3.45.1" - checksum: 7427bc4c8991acabc537bc30da5da9e7afb12754c7cf59d5271b01d1750d4b216c44e2ea298b4354efa83873eeeff62e71d858e5c9cd0a3a69fea933971a6a8d + version: 3.45.0 + resolution: "core-js-pure@npm:3.45.0" + checksum: 2a53eff76a3ba609ba57a82cca08f8832cc4e68fbca08b449361c4fcf319534d1e83ca534305212d113c311d38c37c30a6ac473f295df43836db405a0404cfd8 languageName: node linkType: hard "core-js@npm:^3.19.2": - version: 3.45.1 - resolution: "core-js@npm:3.45.1" - checksum: 674c79e9c58ed923280cd4afbc3bc4c921b8b11bce70d269f1bd98db484e27f0ff436d1de34e198f27065a10386761b39f110309c471f329fe7376ab0fb32bf6 + version: 3.45.0 + resolution: "core-js@npm:3.45.0" + checksum: 05706def467637c0392cb3d37d9e29714070d53feceea2715b4c805f9d55a62caac5d9f40c679a5f56e7fed4198a0e923392c704140fd617c111b239968d5bf1 languageName: node linkType: hard @@ -9464,9 +8467,9 @@ __metadata: linkType: hard "dayjs@npm:^1.11.10": - version: 1.11.18 - resolution: "dayjs@npm:1.11.18" - checksum: cc90054bad30ab011417a7a474b2ffa70e7a28ca6f834d7e86fe53a408a40a14c174f26155072628670e9eda4c48c4ed0d847d2edf83d47c0bfb78be15bbf2dd + version: 1.11.13 + resolution: "dayjs@npm:1.11.13" + checksum: f388db88a6aa93956c1f6121644e783391c7b738b73dbc54485578736565c8931bdfba4bb94e9b1535c6e509c97d5deb918bbe1ae6b34358d994de735055cca9 languageName: node linkType: hard @@ -9480,14 +8483,14 @@ __metadata: linkType: hard "debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1": - version: 4.4.3 - resolution: "debug@npm:4.4.3" + version: 4.4.1 + resolution: "debug@npm:4.4.1" dependencies: ms: ^2.1.3 peerDependenciesMeta: supports-color: optional: true - checksum: 4805abd570e601acdca85b6aa3757186084a45cff9b2fa6eee1f3b173caa776b45f478b2a71a572d616d2010cea9211d0ac4a02a610e4c18ac4324bde3760834 + checksum: a43826a01cda685ee4cec00fb2d3322eaa90ccadbef60d9287debc2a886be3e835d9199c80070ede75a409ee57828c4c6cd80e4b154f2843f0dc95a570dc0729 languageName: node linkType: hard @@ -9657,9 +8660,9 @@ __metadata: linkType: hard "detect-libc@npm:^2.0.0": - version: 2.1.0 - resolution: "detect-libc@npm:2.1.0" - checksum: a6430901d590bacc622e4304b9510fa99f5f8e71be7b5272d5dd03e07f361b9b5452da3416a8215125575946ec3c97c82bd6c51937a3923ab33405481a70e9ae + version: 2.0.4 + resolution: "detect-libc@npm:2.0.4" + checksum: 3d186b7d4e16965e10e21db596c78a4e131f9eee69c0081d13b85e6a61d7448d3ba23fe7997648022bdfa3b0eb4cc3c289a44c8188df949445a20852689abef6 languageName: node linkType: hard @@ -9970,10 +8973,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.218": - version: 1.5.218 - resolution: "electron-to-chromium@npm:1.5.218" - checksum: 869953636f9d7ff865c827a65e3a8e5f2b4162f1ba58389d93e19f2c945001a2e5925d2c29b49af57c2ddbbf75c6205d01d472bf0d54085c42d606b97fd76eab +"electron-to-chromium@npm:^1.5.199": + version: 1.5.199 + resolution: "electron-to-chromium@npm:1.5.199" + checksum: e34ec35366a083b54dd489a23d2e7d7bf21f2971cf52a9f47bc63a64fdbc53adda1c4e15bd7bb33648f045e9f251fc9585e47651f760fdc11b4e9fb793b419ce languageName: node linkType: hard @@ -10044,7 +9047,7 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.17.3": +"enhanced-resolve@npm:^5.17.2": version: 5.18.3 resolution: "enhanced-resolve@npm:5.18.3" dependencies: @@ -10086,11 +9089,11 @@ __metadata: linkType: hard "error-ex@npm:^1.3.1": - version: 1.3.4 - resolution: "error-ex@npm:1.3.4" + version: 1.3.2 + resolution: "error-ex@npm:1.3.2" dependencies: is-arrayish: ^0.2.1 - checksum: 25136c0984569c8d68417036a9a1624804314296f24675199a391e5d20b2e26fe6d9304d40901293fa86900603a229983c9a8921ea7f1d16f814c2db946ff4ef + checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001 languageName: node linkType: hard @@ -10502,35 +9505,35 @@ __metadata: linkType: hard "esbuild@npm:^0.25.0": - version: 0.25.9 - resolution: "esbuild@npm:0.25.9" - dependencies: - "@esbuild/aix-ppc64": 0.25.9 - "@esbuild/android-arm": 0.25.9 - "@esbuild/android-arm64": 0.25.9 - "@esbuild/android-x64": 0.25.9 - "@esbuild/darwin-arm64": 0.25.9 - "@esbuild/darwin-x64": 0.25.9 - "@esbuild/freebsd-arm64": 0.25.9 - "@esbuild/freebsd-x64": 0.25.9 - "@esbuild/linux-arm": 0.25.9 - "@esbuild/linux-arm64": 0.25.9 - "@esbuild/linux-ia32": 0.25.9 - "@esbuild/linux-loong64": 0.25.9 - "@esbuild/linux-mips64el": 0.25.9 - "@esbuild/linux-ppc64": 0.25.9 - "@esbuild/linux-riscv64": 0.25.9 - "@esbuild/linux-s390x": 0.25.9 - "@esbuild/linux-x64": 0.25.9 - "@esbuild/netbsd-arm64": 0.25.9 - "@esbuild/netbsd-x64": 0.25.9 - "@esbuild/openbsd-arm64": 0.25.9 - "@esbuild/openbsd-x64": 0.25.9 - "@esbuild/openharmony-arm64": 0.25.9 - "@esbuild/sunos-x64": 0.25.9 - "@esbuild/win32-arm64": 0.25.9 - "@esbuild/win32-ia32": 0.25.9 - "@esbuild/win32-x64": 0.25.9 + version: 0.25.8 + resolution: "esbuild@npm:0.25.8" + dependencies: + "@esbuild/aix-ppc64": 0.25.8 + "@esbuild/android-arm": 0.25.8 + "@esbuild/android-arm64": 0.25.8 + "@esbuild/android-x64": 0.25.8 + "@esbuild/darwin-arm64": 0.25.8 + "@esbuild/darwin-x64": 0.25.8 + "@esbuild/freebsd-arm64": 0.25.8 + "@esbuild/freebsd-x64": 0.25.8 + "@esbuild/linux-arm": 0.25.8 + "@esbuild/linux-arm64": 0.25.8 + "@esbuild/linux-ia32": 0.25.8 + "@esbuild/linux-loong64": 0.25.8 + "@esbuild/linux-mips64el": 0.25.8 + "@esbuild/linux-ppc64": 0.25.8 + "@esbuild/linux-riscv64": 0.25.8 + "@esbuild/linux-s390x": 0.25.8 + "@esbuild/linux-x64": 0.25.8 + "@esbuild/netbsd-arm64": 0.25.8 + "@esbuild/netbsd-x64": 0.25.8 + "@esbuild/openbsd-arm64": 0.25.8 + "@esbuild/openbsd-x64": 0.25.8 + "@esbuild/openharmony-arm64": 0.25.8 + "@esbuild/sunos-x64": 0.25.8 + "@esbuild/win32-arm64": 0.25.8 + "@esbuild/win32-ia32": 0.25.8 + "@esbuild/win32-x64": 0.25.8 dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -10586,7 +9589,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 718bc15016266da5b4675c2226923cadfe014b119e5c7a9240a6fe826c01ec2e7d5492af052e1c8a03b511778187f234cef2e994e6195287945ce0a824b79974 + checksum: 018e7b151c86df559f30e9b4da95cd5f6c76715818ee1c584ea3a4d19400be75f705f6d57486af2884ad7c1654b791e28419d34c0755186b194d3411745d074c languageName: node linkType: hard @@ -11429,20 +10432,9 @@ __metadata: linkType: hard "fast-uri@npm:^3.0.1": - version: 3.1.0 - resolution: "fast-uri@npm:3.1.0" - checksum: daab0efd3548cc53d0db38ecc764d125773f8bd70c34552ff21abdc6530f26fa4cb1771f944222ca5e61a0a1a85d01a104848ff88c61736de445d97bd616ea7e - languageName: node - linkType: hard - -"fast-xml-parser@npm:5.2.5": - version: 5.2.5 - resolution: "fast-xml-parser@npm:5.2.5" - dependencies: - strnum: ^2.1.0 - bin: - fxparser: src/cli/cli.js - checksum: b12daa933bc226bd7df1e1ecbd305e561c83fd6e4a234b5e2728901deca25a9b9522b9d3ebafde41b1f4d87ab814e3efe18c636638580795fdbe4670a556be88 + version: 3.0.6 + resolution: "fast-uri@npm:3.0.6" + checksum: 7161ba2a7944778d679ba8e5f00d6a2bb479a2142df0982f541d67be6c979b17808f7edbb0ce78161c85035974bde3fa52b5137df31da46c0828cb629ba67c4e languageName: node linkType: hard @@ -11473,15 +10465,15 @@ __metadata: languageName: node linkType: hard -"fdir@npm:^6.5.0": - version: 6.5.0 - resolution: "fdir@npm:6.5.0" +"fdir@npm:^6.4.4, fdir@npm:^6.4.6": + version: 6.4.6 + resolution: "fdir@npm:6.4.6" peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: picomatch: optional: true - checksum: bd537daa9d3cd53887eed35efa0eab2dbb1ca408790e10e024120e7a36c6e9ae2b33710cb8381e35def01bc9c1d7eaba746f886338413e68ff6ebaee07b9a6e8 + checksum: fe9f3014901d023cf631831dcb9eae5447f4d7f69218001dd01ecf007eccc40f6c129a04411b5cc273a5f93c14e02e971e17270afc9022041c80be924091eb6f languageName: node linkType: hard @@ -12587,8 +11579,8 @@ __metadata: linkType: hard "html-webpack-plugin@npm:^5.5.0": - version: 5.6.4 - resolution: "html-webpack-plugin@npm:5.6.4" + version: 5.6.3 + resolution: "html-webpack-plugin@npm:5.6.3" dependencies: "@types/html-minifier-terser": ^6.0.0 html-minifier-terser: ^6.0.2 @@ -12603,7 +11595,7 @@ __metadata: optional: true webpack: optional: true - checksum: b486d99ce820d563dda215f8b6bbeb78127a738b88b419c95d577165e10dd29125e151010b5745ce933e8055f2445c2f9ad1c93024ad3b752db9ac613e84cfac + checksum: 59e7d971b0cfd9ba34c7acaa3c161e43c62596474dd8cd35d7b690498ff5891f21296de0aa1d2e7810348caa657e938461267155dda47913b5eeca7124406270 languageName: node linkType: hard @@ -12751,16 +11743,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.7.0": - version: 0.7.0 - resolution: "iconv-lite@npm:0.7.0" - dependencies: - safer-buffer: ">= 2.1.2 < 3.0.0" - checksum: f362a8befb95e37f29be1d1290c17e0c9d0d4ad4fa62fcfd813cc9c937ab89401abed9a011f83e10651a267abb2aa231ec7da91d843570bec873bd98489b5bf8 - languageName: node - linkType: hard - -"iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -12928,10 +11911,13 @@ __metadata: languageName: node linkType: hard -"ip-address@npm:^10.0.1": - version: 10.0.1 - resolution: "ip-address@npm:10.0.1" - checksum: 525d5391cfd31a91f80f5857e98487aeaa8474e860a6725a0b6461ac8e436c7f8c869774dece391c8f8e7486306a34a4d1c094778c4c583a3f1f2cd905e5ed50 +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: 1.1.0 + sprintf-js: ^1.1.3 + checksum: aa15f12cfd0ef5e38349744e3654bae649a34c3b10c77a674a167e99925d1549486c5b14730eebce9fea26f6db9d5e42097b00aa4f9f612e68c79121c71652dc languageName: node linkType: hard @@ -13429,12 +12415,12 @@ __metadata: linkType: hard "istanbul-reports@npm:^3.1.3": - version: 3.2.0 - resolution: "istanbul-reports@npm:3.2.0" + version: 3.1.7 + resolution: "istanbul-reports@npm:3.1.7" dependencies: html-escaper: ^2.0.0 istanbul-lib-report: ^3.0.0 - checksum: 72b4c8525276147908d28b0917bc675b1019836b638e50875521ca3b8ec63672681aa98dbab88a6f49ef798c08fe041d428abdcf84f4f3fcff5844eee54af65a + checksum: 2072db6e07bfbb4d0eb30e2700250636182398c1af811aea5032acb219d2080f7586923c09fa194029efd6b92361afb3dcbe1ebcc3ee6651d13340f7c6c4ed95 languageName: node linkType: hard @@ -14198,6 +13184,13 @@ __metadata: languageName: node linkType: hard +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 944f924f2bd67ad533b3850eee47603eed0f6ae425fd1ee8c760f477e8c34a05f144c1bd4f5a5dd1963141dc79a2c55f89ccc5ab77d039e7077f3ad196b64965 + languageName: node + linkType: hard + "jsdom@npm:^16.6.0": version: 16.7.0 resolution: "jsdom@npm:16.7.0" @@ -14328,15 +13321,15 @@ __metadata: linkType: hard "jsonfile@npm:^6.0.1": - version: 6.2.0 - resolution: "jsonfile@npm:6.2.0" + version: 6.1.0 + resolution: "jsonfile@npm:6.1.0" dependencies: graceful-fs: ^4.1.6 universalify: ^2.0.0 dependenciesMeta: graceful-fs: optional: true - checksum: c3028ec5c770bb41290c9bb9ca04bdd0a1b698ddbdf6517c9453d3f90fc9e000c9675959fb46891d317690a93c62de03ff1735d8dbe02be83e51168ce85815d3 + checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354 languageName: node linkType: hard @@ -14743,9 +13736,9 @@ __metadata: linkType: hard "loupe@npm:^3.1.0, loupe@npm:^3.1.2, loupe@npm:^3.1.4": - version: 3.2.1 - resolution: "loupe@npm:3.2.1" - checksum: 3ce9ecc5b2c56ffc073bf065ad3a4644cccce3eac81e61a8732e9c8ebfe05513ed478592d25f9dba24cfe82766913be045ab384c04711c7c6447deaf800ad94c + version: 3.2.0 + resolution: "loupe@npm:3.2.0" + checksum: 4bfb4d9cf9e482b7f8c2f1d245cf0a14dd690b08d85356b0f0f6da94787c005ead7d2e4812a77ccddae42b86212b168beb1f65da711dc1709e9bf972beb51213 languageName: node linkType: hard @@ -14766,9 +13759,9 @@ __metadata: linkType: hard "lru-cache@npm:^11.0.0": - version: 11.2.1 - resolution: "lru-cache@npm:11.2.1" - checksum: d54584b6f03e6de64c9e9f01e48abce5a9bc04318874d5204cee9e4275719544624d51eea6a167672576794af8bba3a7cfc23455d28b270a278cc387d1965131 + version: 11.1.0 + resolution: "lru-cache@npm:11.1.0" + checksum: 6274e90b5fdff87570fe26fe971467a5ae1f25f132bebe187e71c5627c7cd2abb94b47addd0ecdad034107667726ebde1abcef083d80f2126e83476b2c4e7c82 languageName: node linkType: hard @@ -14809,11 +13802,11 @@ __metadata: linkType: hard "magic-string@npm:^0.30.12, magic-string@npm:^0.30.17": - version: 0.30.19 - resolution: "magic-string@npm:0.30.19" + version: 0.30.17 + resolution: "magic-string@npm:0.30.17" dependencies: - "@jridgewell/sourcemap-codec": ^1.5.5 - checksum: f360b87febeceddb35238e55963b70ef68381688c1aada6d842833a7be440a08cb0a8776e23b5e4e34785edc6b42b92dc08c829f43ecdb58547122f3fd79fdc7 + "@jridgewell/sourcemap-codec": ^1.5.0 + checksum: f4b4ed17c5ada64f77fc98491847302ebad64894a905c417c943840c0384662118c9b37f9f68bb86add159fa4749ff6f118c4627d69a470121b46731f8debc6d languageName: node linkType: hard @@ -15438,14 +14431,14 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.4.5": - version: 2.9.4 - resolution: "mini-css-extract-plugin@npm:2.9.4" + version: 2.9.3 + resolution: "mini-css-extract-plugin@npm:2.9.3" dependencies: schema-utils: ^4.0.0 tapable: ^2.2.1 peerDependencies: webpack: ^5.0.0 - checksum: 4ec46ebdcb5dae4b1c012debca90fea27b1e8e7790d408154232d77d25f56f839e7b1ec5401a962d6356e7b9301c760d2ef62e1cb0d4d7b6ec8209f812733dda + checksum: a404565949c3601bf9e8363a2489ce41c6fd9b03a8d8e5f6b5ee49ba209357b07db05475f89ff1c4670f0fdde64d53637dc357d72519deabb2428ef53ccf8400 languageName: node linkType: hard @@ -15624,11 +14617,12 @@ __metadata: linkType: hard "msw@npm:^2.7.0": - version: 2.11.2 - resolution: "msw@npm:2.11.2" + version: 2.10.4 + resolution: "msw@npm:2.10.4" dependencies: "@bundled-es-modules/cookie": ^2.0.1 "@bundled-es-modules/statuses": ^1.0.1 + "@bundled-es-modules/tough-cookie": ^0.1.6 "@inquirer/confirm": ^5.0.0 "@mswjs/interceptors": ^0.39.1 "@open-draft/deferred-promise": ^2.2.0 @@ -15641,9 +14635,7 @@ __metadata: outvariant: ^1.4.3 path-to-regexp: ^6.3.0 picocolors: ^1.1.1 - rettime: ^0.7.0 strict-event-emitter: ^0.5.1 - tough-cookie: ^6.0.0 type-fest: ^4.26.1 yargs: ^17.7.2 peerDependencies: @@ -15653,7 +14645,7 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: 599aa3ed6e5043479bef473fa427a7aaf343d32aedba301ec62cac1a30c50b2a2898c4b9fe11b939ab03768807860eff64ce2fbdd28f78d0c6be4f4318d8b276 + checksum: 7a0b30ffd982a4f99493c24efae48a333a007f53ddd53657ac8d850c86bd08cefd5fdff4af859ad3e9624a686fb57ff9061075ffb5abee7145b521401d515155 languageName: node linkType: hard @@ -15780,11 +14772,11 @@ __metadata: linkType: hard "node-abi@npm:^3.3.0": - version: 3.77.0 - resolution: "node-abi@npm:3.77.0" + version: 3.75.0 + resolution: "node-abi@npm:3.75.0" dependencies: semver: ^7.3.5 - checksum: 62ab12fe90e2c2081c1e0dfc3819d60dc181aff36c5dd2ca99cece3f1f19efb284be90353bd0cb911c44f77a23ce111635937e8c6b48dd8cfaa24e34221d4a9f + checksum: b86021c748b316b31efda4f1f4a74db9fd411b0ae63fa50be5b0247546285ae7e31c737e92013478877eaf39a3fd0a06072d48b1cace21ad629862373410416f languageName: node linkType: hard @@ -15819,8 +14811,8 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 11.4.2 - resolution: "node-gyp@npm:11.4.2" + version: 11.3.0 + resolution: "node-gyp@npm:11.3.0" dependencies: env-paths: ^2.2.0 exponential-backoff: ^3.1.1 @@ -15834,7 +14826,7 @@ __metadata: which: ^5.0.0 bin: node-gyp: bin/node-gyp.js - checksum: d8041cee7ec60c86fb2961d77c12a2d083a481fb28b08e6d9583153186c0e7766044dc30bdb1f3ac01ddc5763b83caeed3d1ea35787ec4ffd8cc4aeedfc34f2b + checksum: 64255952af18222e930a0bb8239e8fc86ec25eddfbf61523ab30b45f19670c1e66384ceda0472f5d59e63a7779b2134eab8ec5322b9f092f60202b0e312a66c8 languageName: node linkType: hard @@ -15845,10 +14837,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.21": - version: 2.0.21 - resolution: "node-releases@npm:2.0.21" - checksum: 191f8245e18272971650eb45151c5891313bca27507a8f634085bd8c98a9cb9492686ef6182176866ceebff049646ef6cd5fb5ca46d5b5ca00ce2c69185d84c4 +"node-releases@npm:^2.0.19": + version: 2.0.19 + resolution: "node-releases@npm:2.0.19" + checksum: 917dbced519f48c6289a44830a0ca6dc944c3ee9243c468ebd8515a41c97c8b2c256edb7f3f750416bc37952cc9608684e6483c7b6c6f39f6bd8d86c52cfe658 languageName: node linkType: hard @@ -15939,9 +14931,9 @@ __metadata: linkType: hard "nwsapi@npm:^2.2.0": - version: 2.2.22 - resolution: "nwsapi@npm:2.2.22" - checksum: 9491f0396d8aaf7fd1f9ebbbbff5d9bb9090e5d200263cf31b117bbaad7eb79da86b4c9b9bcd64c4b35f6d7e1630d14ee21c0959c01131e89c1c5e22d72530bf + version: 2.2.21 + resolution: "nwsapi@npm:2.2.21" + checksum: 1378b2556b01063c95d88932aefc0516e853b1a5b9c94457e03aabfd4e6a133c32c636c3ccaaebdc3a4e316390e61cdb380f39aa4009c20d2e8c0fec869e6a66 languageName: node linkType: hard @@ -16422,9 +15414,9 @@ __metadata: linkType: hard "path-to-regexp@npm:^8.0.0": - version: 8.3.0 - resolution: "path-to-regexp@npm:8.3.0" - checksum: 73e0d3db449f9899692b10be8480bbcfa294fd575be2d09bce3e63f2f708d1fccd3aaa8591709f8b82062c528df116e118ff9df8f5c52ccc4c2443a90be73e10 + version: 8.2.0 + resolution: "path-to-regexp@npm:8.2.0" + checksum: 56e13e45962e776e9e7cd72e87a441cfe41f33fd539d097237ceb16adc922281136ca12f5a742962e33d8dda9569f630ba594de56d8b7b6e49adf31803c5e771 languageName: node linkType: hard @@ -17762,14 +16754,14 @@ __metadata: linkType: hard "raw-body@npm:^3.0.0": - version: 3.0.1 - resolution: "raw-body@npm:3.0.1" + version: 3.0.0 + resolution: "raw-body@npm:3.0.0" dependencies: bytes: 3.1.2 http-errors: 2.0.0 - iconv-lite: 0.7.0 + iconv-lite: 0.6.3 unpipe: 1.0.0 - checksum: e75e1db74337e01b78cc07f7e65692ed46aef2e0c4fb39cb25bb365a7ab04cbdb8b3541aabebe50b07a5bffec5def5674b587fd9e8fbde84c8838cbab1ad9836 + checksum: 25b7cf7964183db322e819050d758a5abd0f22c51e9f37884ea44a9ed6855a1fb61f8caa8ec5b61d07e69f54db43dbbc08ad98ef84556696d6aa806be247af0e languageName: node linkType: hard @@ -18380,12 +17372,12 @@ __metadata: languageName: node linkType: hard -"regenerate-unicode-properties@npm:^10.2.2": - version: 10.2.2 - resolution: "regenerate-unicode-properties@npm:10.2.2" +"regenerate-unicode-properties@npm:^10.2.0": + version: 10.2.0 + resolution: "regenerate-unicode-properties@npm:10.2.0" dependencies: regenerate: ^1.4.2 - checksum: 7ae4c1c32460c4360e3118c45eec0621424908f430fdd6f162c9172067786bf2b1682fbc885a33b26bc85e76e06f4d3f398b52425e801b0bb0cbae147dafb0b2 + checksum: d5c5fc13f8b8d7e16e791637a4bfef741f8d70e267d51845ee7d5404a32fa14c75b181c4efba33e4bff8b0000a2f13e9773593713dfe5b66597df4259275ce63 languageName: node linkType: hard @@ -18432,16 +17424,16 @@ __metadata: linkType: hard "regexpu-core@npm:^6.2.0": - version: 6.3.1 - resolution: "regexpu-core@npm:6.3.1" + version: 6.2.0 + resolution: "regexpu-core@npm:6.2.0" dependencies: regenerate: ^1.4.2 - regenerate-unicode-properties: ^10.2.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.2.1 - checksum: 601a8298bca4d074c239e3b989b3b5f7532e4c8bde4e6d45690d4ba01d4f331869df3899a260a0fd88ecdb8902082725845447b0e2a3e1b0a1364131970489cb + unicode-match-property-value-ecmascript: ^2.1.0 + checksum: 67d3c4a3f6c99bc80b5d690074a27e6f675be1c1739f8a9acf028fbc36f1a468472574ea65e331e217995198ba4404d7878f3cb3739a73552dd3c70d3fb7f8e6 languageName: node linkType: hard @@ -18688,13 +17680,6 @@ __metadata: languageName: node linkType: hard -"rettime@npm:^0.7.0": - version: 0.7.0 - resolution: "rettime@npm:0.7.0" - checksum: 1ad3984a4f8000adf56c623882170115d7453b3bbaed56429a40077b067fad98c1c5db9a58e63793add15a97006fa7c817516d985c3347df40b5d274dc087803 - languageName: node - linkType: hard - "reusify@npm:^1.0.4": version: 1.1.0 resolution: "reusify@npm:1.1.0" @@ -18754,30 +17739,29 @@ __metadata: linkType: hard "rollup@npm:^4.20.0, rollup@npm:^4.23.0, rollup@npm:^4.43.0": - version: 4.50.2 - resolution: "rollup@npm:4.50.2" - dependencies: - "@rollup/rollup-android-arm-eabi": 4.50.2 - "@rollup/rollup-android-arm64": 4.50.2 - "@rollup/rollup-darwin-arm64": 4.50.2 - "@rollup/rollup-darwin-x64": 4.50.2 - "@rollup/rollup-freebsd-arm64": 4.50.2 - "@rollup/rollup-freebsd-x64": 4.50.2 - "@rollup/rollup-linux-arm-gnueabihf": 4.50.2 - "@rollup/rollup-linux-arm-musleabihf": 4.50.2 - "@rollup/rollup-linux-arm64-gnu": 4.50.2 - "@rollup/rollup-linux-arm64-musl": 4.50.2 - "@rollup/rollup-linux-loong64-gnu": 4.50.2 - "@rollup/rollup-linux-ppc64-gnu": 4.50.2 - "@rollup/rollup-linux-riscv64-gnu": 4.50.2 - "@rollup/rollup-linux-riscv64-musl": 4.50.2 - "@rollup/rollup-linux-s390x-gnu": 4.50.2 - "@rollup/rollup-linux-x64-gnu": 4.50.2 - "@rollup/rollup-linux-x64-musl": 4.50.2 - "@rollup/rollup-openharmony-arm64": 4.50.2 - "@rollup/rollup-win32-arm64-msvc": 4.50.2 - "@rollup/rollup-win32-ia32-msvc": 4.50.2 - "@rollup/rollup-win32-x64-msvc": 4.50.2 + version: 4.46.2 + resolution: "rollup@npm:4.46.2" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.46.2 + "@rollup/rollup-android-arm64": 4.46.2 + "@rollup/rollup-darwin-arm64": 4.46.2 + "@rollup/rollup-darwin-x64": 4.46.2 + "@rollup/rollup-freebsd-arm64": 4.46.2 + "@rollup/rollup-freebsd-x64": 4.46.2 + "@rollup/rollup-linux-arm-gnueabihf": 4.46.2 + "@rollup/rollup-linux-arm-musleabihf": 4.46.2 + "@rollup/rollup-linux-arm64-gnu": 4.46.2 + "@rollup/rollup-linux-arm64-musl": 4.46.2 + "@rollup/rollup-linux-loongarch64-gnu": 4.46.2 + "@rollup/rollup-linux-ppc64-gnu": 4.46.2 + "@rollup/rollup-linux-riscv64-gnu": 4.46.2 + "@rollup/rollup-linux-riscv64-musl": 4.46.2 + "@rollup/rollup-linux-s390x-gnu": 4.46.2 + "@rollup/rollup-linux-x64-gnu": 4.46.2 + "@rollup/rollup-linux-x64-musl": 4.46.2 + "@rollup/rollup-win32-arm64-msvc": 4.46.2 + "@rollup/rollup-win32-ia32-msvc": 4.46.2 + "@rollup/rollup-win32-x64-msvc": 4.46.2 "@types/estree": 1.0.8 fsevents: ~2.3.2 dependenciesMeta: @@ -18801,7 +17785,7 @@ __metadata: optional: true "@rollup/rollup-linux-arm64-musl": optional: true - "@rollup/rollup-linux-loong64-gnu": + "@rollup/rollup-linux-loongarch64-gnu": optional: true "@rollup/rollup-linux-ppc64-gnu": optional: true @@ -18815,8 +17799,6 @@ __metadata: optional: true "@rollup/rollup-linux-x64-musl": optional: true - "@rollup/rollup-openharmony-arm64": - optional: true "@rollup/rollup-win32-arm64-msvc": optional: true "@rollup/rollup-win32-ia32-msvc": @@ -18827,7 +17809,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: fbdd9b470585fe1add3ec35edb760de289fe4413c9eb4ba5321fcf38638669d7f0d44ee54f9c55cd81404c69caa2c4b0598d2b4715e0b138cdace65bbe9a207a + checksum: cba997c09d51a92bdf0475c522dafe6264891329d4d53689b7fab8a44bbf0b8ab2feb4bb27d9809a5d76831e703fddb44d5f8a95c1d3e7f2f9c9766541f65475 languageName: node linkType: hard @@ -18853,7 +17835,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:7.8.2": +"rxjs@npm:^7.8.1": version: 7.8.2 resolution: "rxjs@npm:7.8.2" dependencies: @@ -18950,8 +17932,8 @@ __metadata: linkType: hard "sass@npm:^1.54.0": - version: 1.92.1 - resolution: "sass@npm:1.92.1" + version: 1.90.0 + resolution: "sass@npm:1.90.0" dependencies: "@parcel/watcher": ^2.4.1 chokidar: ^4.0.0 @@ -18962,7 +17944,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: ec0d4da639874f0f849b766f51f3db1fdff703840e7066ca3dd097999179630707b357744d83dde54289c02bba2f1ef8b34bba460cf4f703874b7922a86e32df + checksum: 1f2ad353eb9a4a294ba7e8f9038363c8fbf69afbf2938d53a3beff9bd9180061c3da71f139b7dedc4707f7421c4a1226164bd0276988dbc3b43b1276c0752055 languageName: node linkType: hard @@ -19279,7 +18261,7 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:1.8.3, shell-quote@npm:^1.7.3, shell-quote@npm:^1.8.3": +"shell-quote@npm:^1.7.3, shell-quote@npm:^1.8.1, shell-quote@npm:^1.8.3": version: 1.8.3 resolution: "shell-quote@npm:1.8.3" checksum: 550dd84e677f8915eb013d43689c80bb114860649ec5298eb978f40b8f3d4bc4ccb072b82c094eb3548dc587144bb3965a8676f0d685c1cf4c40b5dc27166242 @@ -19454,12 +18436,12 @@ __metadata: linkType: hard "socks@npm:^2.8.3": - version: 2.8.7 - resolution: "socks@npm:2.8.7" + version: 2.8.6 + resolution: "socks@npm:2.8.6" dependencies: - ip-address: ^10.0.1 + ip-address: ^9.0.5 smart-buffer: ^4.2.0 - checksum: 4bbe2c88cf0eeaf49f94b7f11564a99b2571bde6fd1e714ff95b38f89e1f97858c19e0ab0e6d39eb7f6a984fa67366825895383ed563fe59962a1d57a1d55318 + checksum: 3d2a696d42d94b05b2a7e797b9291483d6768b23300b015353f34f8046cce35f23fe59300a38a77a9f0dee4274dd6c333afbdef628cf48f3df171bfb86c2d21c languageName: node linkType: hard @@ -19571,6 +18553,13 @@ __metadata: languageName: node linkType: hard +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -19863,11 +18852,11 @@ __metadata: linkType: hard "strip-ansi@npm:^7.0.1": - version: 7.1.2 - resolution: "strip-ansi@npm:7.1.2" + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" dependencies: ansi-regex: ^6.0.1 - checksum: db0e3f9654e519c8a33c50fc9304d07df5649388e7da06d3aabf66d29e5ad65d5e6315d8519d409c15b32fa82c1df7e11ed6f8cd50b0e4404463f0c9d77c8d0b + checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d languageName: node linkType: hard @@ -19931,13 +18920,6 @@ __metadata: languageName: node linkType: hard -"strnum@npm:^2.1.0": - version: 2.1.1 - resolution: "strnum@npm:2.1.1" - checksum: 566139b218ef13bdde2a69c744852ac41ea167588f624d46c3b3bebb5d1d1775c55bca4702a0ad2a6a66eb4b3b7de4cbbc83e8d40c5835feabebf6f9cc468993 - languageName: node - linkType: hard - "style-loader@npm:^3.3.1": version: 3.3.4 resolution: "style-loader@npm:3.3.4" @@ -20030,15 +19012,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:8.1.1, supports-color@npm:^8.0.0": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: ^4.0.0 - checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 - languageName: node - linkType: hard - "supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -20057,6 +19030,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^8.0.0, supports-color@npm:^8.1.1": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: ^4.0.0 + checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 + languageName: node + linkType: hard + "supports-hyperlinks@npm:^2.0.0": version: 2.3.0 resolution: "supports-hyperlinks@npm:2.3.0" @@ -20191,9 +19173,9 @@ __metadata: linkType: hard "tapable@npm:^2.0.0, tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": - version: 2.2.3 - resolution: "tapable@npm:2.2.3" - checksum: 0bef252c4f12d3371353c4b16b38ea4fc7153598ab7f7770a4235277ed4d631925a27f42bf03caa754817e9ab017e3179fd2323a0a28409846d225e23f3bf722 + version: 2.2.2 + resolution: "tapable@npm:2.2.2" + checksum: 781b3666f4454eb506fd2bcd985c1994f2b93884ea88a7a2a5be956cad8337b31128a7591e771f7aab8e247993b2a0887d360a2d4f54382902ed89994c102740 languageName: node linkType: hard @@ -20288,16 +19270,16 @@ __metadata: linkType: hard "terser@npm:^5.0.0, terser@npm:^5.10.0, terser@npm:^5.31.1": - version: 5.44.0 - resolution: "terser@npm:5.44.0" + version: 5.43.1 + resolution: "terser@npm:5.43.1" dependencies: "@jridgewell/source-map": ^0.3.3 - acorn: ^8.15.0 + acorn: ^8.14.0 commander: ^2.20.0 source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: 4e1868d9662ea280dad7b49cfe61b7693187be2b529b31b1f86782db00833c03ba05f2b82fc513d928e937260f2a5fbf42a93724e86eaf55f069288f934ccdb3 + checksum: 1d51747f4540a0842139c2f2617e88d68a26da42d7571cda8955e1bd8febac6e60bc514c258781334e1724aeeccfbd511473eb9d8d831435e4e5fad1ce7f6e8b languageName: node linkType: hard @@ -20386,13 +19368,13 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": - version: 0.2.15 - resolution: "tinyglobby@npm:0.2.15" +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14": + version: 0.2.14 + resolution: "tinyglobby@npm:0.2.14" dependencies: - fdir: ^6.5.0 - picomatch: ^4.0.3 - checksum: 0e33b8babff966c6ab86e9b825a350a6a98a63700fa0bb7ae6cf36a7770a508892383adc272f7f9d17aaf46a9d622b455e775b9949a3f951eaaf5dfb26331d44 + fdir: ^6.4.4 + picomatch: ^4.0.2 + checksum: 261e986e3f2062dec3a582303bad2ce31b4634b9348648b46828c000d464b012cf474e38f503312367d4117c3f2f18611992738fca684040758bba44c24de522 languageName: node linkType: hard @@ -20431,24 +19413,6 @@ __metadata: languageName: node linkType: hard -"tldts-core@npm:^7.0.14": - version: 7.0.14 - resolution: "tldts-core@npm:7.0.14" - checksum: bc13d721605fb66dab2baaf3ae665a8a48722f5b86e2b8a9b299cdbdc34c2a3b7167a08566afe52eed3064a3a0fc08680c456aa170fa9a50d85b9421f787c6db - languageName: node - linkType: hard - -"tldts@npm:^7.0.5": - version: 7.0.14 - resolution: "tldts@npm:7.0.14" - dependencies: - tldts-core: ^7.0.14 - bin: - tldts: bin/cli.js - checksum: dfd07fe27f2d4bfb7219391dcf666e60ca5041c17e037a7eee3171d4a809e003f71abd73295ab846586c1b589f4aa727439038810e19ef86a8e74ac780deb421 - languageName: node - linkType: hard - "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -20488,7 +19452,7 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^4.0.0": +"tough-cookie@npm:^4.0.0, tough-cookie@npm:^4.1.4": version: 4.1.4 resolution: "tough-cookie@npm:4.1.4" dependencies: @@ -20500,15 +19464,6 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^6.0.0": - version: 6.0.0 - resolution: "tough-cookie@npm:6.0.0" - dependencies: - tldts: ^7.0.5 - checksum: 66d32ee40e1c6c61be5388e1c124674871dae0a684c30853f1628a4da2c5ad4199a825d1b0a7ba424dadfba7b5a9b37e8c761eafbf48f1b9f75a4629e73b14bc - languageName: node - linkType: hard - "tr46@npm:^1.0.1": version: 1.0.1 resolution: "tr46@npm:1.0.1" @@ -20534,7 +19489,7 @@ __metadata: languageName: node linkType: hard -"tree-kill@npm:1.2.2": +"tree-kill@npm:^1.2.2": version: 1.2.2 resolution: "tree-kill@npm:1.2.2" bin: @@ -20657,7 +19612,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.6.2": +"tslib@npm:^2.0.3, tslib@npm:^2.1.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a @@ -20964,10 +19919,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~7.12.0": - version: 7.12.0 - resolution: "undici-types@npm:7.12.0" - checksum: 4ad2770b92835757eee6416e8518972d83fc77286c11af81d368a55578d9e4f7ab1b8a3b13c304b0e25a400583e66f3c58464a051f8b5c801ab5d092da13903e +"undici-types@npm:~7.10.0": + version: 7.10.0 + resolution: "undici-types@npm:7.10.0" + checksum: 6917fcd8c80963919fe918952f9243a6749af0e3f759a39f8d2c2486144a66c86ae4125aebbce700b636cb1dcd45e85eb8c49c60d60738a97b63f0e89ef9b053 languageName: node linkType: hard @@ -20988,17 +19943,17 @@ __metadata: languageName: node linkType: hard -"unicode-match-property-value-ecmascript@npm:^2.2.1": - version: 2.2.1 - resolution: "unicode-match-property-value-ecmascript@npm:2.2.1" - checksum: e6c73e07bb4dc4aa399797a14b170e84a30ed290bcf97cc4305cf67dde8744119721ce17cef03f4f9d4ff48654bfa26eadc7fe1e8dd4b71b8f3b2e9a9742f013 +"unicode-match-property-value-ecmascript@npm:^2.1.0": + version: 2.2.0 + resolution: "unicode-match-property-value-ecmascript@npm:2.2.0" + checksum: 9e3151e1d0bc6be35c4cef105e317c04090364173e8462005b5cde08a1e7c858b6586486cfebac39dc2c6c8c9ee24afb245de6d527604866edfa454fe2a35fae languageName: node linkType: hard "unicode-property-aliases-ecmascript@npm:^2.0.0": - version: 2.2.0 - resolution: "unicode-property-aliases-ecmascript@npm:2.2.0" - checksum: 0dd0f6e70130c59b4a841bac206758f70227b113145e4afe238161e3e8540e8eb79963e7a228cd90ad13d499e96f7ef4ee8940835404b2181ad9bf9c174818e3 + version: 2.1.0 + resolution: "unicode-property-aliases-ecmascript@npm:2.1.0" + checksum: 243524431893649b62cc674d877bd64ef292d6071dd2fd01ab4d5ad26efbc104ffcd064f93f8a06b7e4ec54c172bf03f6417921a0d8c3a9994161fe1f88f815b languageName: node linkType: hard @@ -21444,8 +20399,8 @@ __metadata: linkType: hard "vite@npm:^5.0.0": - version: 5.4.20 - resolution: "vite@npm:5.4.20" + version: 5.4.19 + resolution: "vite@npm:5.4.19" dependencies: esbuild: ^0.21.3 fsevents: ~2.3.3 @@ -21482,21 +20437,21 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 67af97e818977e92d1e55bc35d45f58d41eba6fc87f2a18435d3402adb07f4c4ec1ba838d954829f80f7784e65b65f8d147db695cfaefe45f667ee283530770d + checksum: c15af65f2370b59e674c5fab22d8e05ec5c7f8f0345ed99ffec155c77feb5636b4e0680dbd096a6f06d7c386b259dc0b9c67c4f1ec08486a2f2a677c9ea6971b languageName: node linkType: hard "vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": - version: 7.1.5 - resolution: "vite@npm:7.1.5" + version: 7.1.1 + resolution: "vite@npm:7.1.1" dependencies: esbuild: ^0.25.0 - fdir: ^6.5.0 + fdir: ^6.4.6 fsevents: ~2.3.3 picomatch: ^4.0.3 postcss: ^8.5.6 rollup: ^4.43.0 - tinyglobby: ^0.2.15 + tinyglobby: ^0.2.14 peerDependencies: "@types/node": ^20.19.0 || >=22.12.0 jiti: ">=1.21.0" @@ -21537,7 +20492,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 14922d98024a1d93ebe8f3ce38af586c83d55f037f8c5fe8664103d7aa0785d0747f3edf8cb6550dcfa071b90bfd40bce56581d9cb14a19a53d29abb9f3415f5 + checksum: 608b953c9e3067f533874093b2fc7cf7bf47864904fd73dfbb3a6b36395ea710a14fbc76a2ae78661a565b7398a30110eca44837942ac585b9c9b59e6550d114 languageName: node linkType: hard @@ -21839,8 +20794,8 @@ __metadata: linkType: hard "webpack@npm:^5.64.4": - version: 5.101.3 - resolution: "webpack@npm:5.101.3" + version: 5.101.0 + resolution: "webpack@npm:5.101.0" dependencies: "@types/eslint-scope": ^3.7.7 "@types/estree": ^1.0.8 @@ -21852,7 +20807,7 @@ __metadata: acorn-import-phases: ^1.0.3 browserslist: ^4.24.0 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.17.3 + enhanced-resolve: ^5.17.2 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 @@ -21872,7 +20827,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: d23fd86b6bc9854f9b488830d9aa123a7f654ee22849bc8670d0a22add88951f6d9cab1d04087758b642fc31115e3b97e0ac56b80b2200c04c486067aa945663 + checksum: fba0a5146e94bcd3634d3f791637382dc57e746fe8010ad54636bf3e8d7d10c3027e78a85eee74702d9c146f9b858f2e3052d64bfffc4a8a0f2c778d63d0f3d6 languageName: node linkType: hard @@ -22452,21 +21407,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.7.2, yargs@npm:^17.3.1, yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" - 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 - checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a - languageName: node - linkType: hard - "yargs@npm:^15.3.1": version: 15.4.1 resolution: "yargs@npm:15.4.1" @@ -22501,6 +21441,21 @@ __metadata: languageName: node linkType: hard +"yargs@npm:^17.3.1, yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + 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 + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + languageName: node + linkType: hard + "yn@npm:3.1.1": version: 3.1.1 resolution: "yn@npm:3.1.1" @@ -22516,9 +21471,9 @@ __metadata: linkType: hard "yoctocolors-cjs@npm:^2.1.2": - version: 2.1.3 - resolution: "yoctocolors-cjs@npm:2.1.3" - checksum: 207df586996c3b604fa85903f81cc54676f1f372613a0c7247f0d24b1ca781905685075d06955211c4d5d4f629d7d5628464f8af0a42d286b7a8ff88e9dadcb8 + version: 2.1.2 + resolution: "yoctocolors-cjs@npm:2.1.2" + checksum: 1c474d4b30a8c130e679279c5c2c33a0d48eba9684ffa0252cc64846c121fb56c3f25457fef902edbe1e2d7a7872130073a9fc8e795299d75e13fa3f5f548f1b languageName: node linkType: hard From 68b664e8b099c3b6cd8287a12eddb803bb286476 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 17 Sep 2025 16:56:13 -0400 Subject: [PATCH 048/477] #3565 Updated the transformers and added more seed examples --- .../prisma-query-args/machinery.query-args.ts | 17 +++-- src/backend/src/prisma/seed.ts | 68 ++++++++++++++++++- src/backend/src/services/calendar.services.ts | 9 +-- .../src/transformers/calendar.transformer.ts | 11 ++- src/shared/src/types/calendar-types.ts | 6 ++ 5 files changed, 95 insertions(+), 16 deletions(-) diff --git a/src/backend/src/prisma-query-args/machinery.query-args.ts b/src/backend/src/prisma-query-args/machinery.query-args.ts index 991fda3bdf..75b880af8e 100644 --- a/src/backend/src/prisma-query-args/machinery.query-args.ts +++ b/src/backend/src/prisma-query-args/machinery.query-args.ts @@ -1,21 +1,28 @@ import { Prisma } from '@prisma/client'; +import { getUserQueryArgs } from './user.query-args'; export type ShopQueryArgs = ReturnType; export type ShopMachineryQueryArgs = ReturnType; export type MachineryQueryArgs = ReturnType; -export const getShopQueryArgs = () => Prisma.validator()({}); +export const getShopQueryArgs = (organizationId: string) => + Prisma.validator()({ + include: { + userCreated: getUserQueryArgs(organizationId) + } + }); -export const getShopMachineryQueryArgs = () => +export const getShopMachineryQueryArgs = (organizationId: string) => Prisma.validator()({ include: { - shop: getShopQueryArgs() + shop: getShopQueryArgs(organizationId) } }); -export const getMachineryQueryArgs = () => +export const getMachineryQueryArgs = (organizationId: string) => Prisma.validator()({ include: { - shops: getShopMachineryQueryArgs() + shops: getShopMachineryQueryArgs(organizationId), + userCreated: getUserQueryArgs(organizationId) } }); diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index f66738e3a1..5db55df6ce 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3061,7 +3061,7 @@ const performSeed: () => Promise = async () => { thomasEmrax.userId ); - // Create machineries and assign to shops + // Create shops for machinery const advancedShop = await prisma.shop.create({ data: { name: 'Advanced CNC Manufacturing Center', @@ -3070,7 +3070,71 @@ const performSeed: () => Promise = async () => { } }); - await MachineryService.createMachinery(thomasEmrax, 'Iron Man Mark 42 CNC Mill', advancedShop.shopId, 1, ner); + const electronicsLab = await prisma.shop.create({ + data: { + name: 'Electronics Development Lab', + description: 'Electronics testing and development workspace', + userCreatedId: thomasEmrax.userId + } + }); + + const testingFacility = await prisma.shop.create({ + data: { + name: 'Testing & Validation Facility', + description: 'Component and system testing laboratory', + userCreatedId: thomasEmrax.userId + } + }); + + // Create machineries and assign to shops + await MachineryService.createMachinery( + thomasEmrax, + 'Iron Man CNC Mill', + advancedShop.shopId, + 1, + ner, + 'High-precision CNC milling operations' + ); + await MachineryService.createMachinery( + thomasEmrax, + 'Thor Hammer Lathe', + advancedShop.shopId, + 2, + ner, + 'High-precision turning operations' + ); + await MachineryService.createMachinery( + thomasEmrax, + 'Spider-Man 3D Printer', + electronicsLab.shopId, + 1, + ner, + 'Rapid prototyping for electronics enclosures' + ); + await MachineryService.createMachinery( + thomasEmrax, + 'Captain America Oscilloscope', + electronicsLab.shopId, + 3, + ner, + 'High-speed signal analysis' + ); + await MachineryService.createMachinery( + thomasEmrax, + 'Hulk Dynamometer', + testingFacility.shopId, + 1, + ner, + 'Engine and motor testing' + ); + await MachineryService.createMachinery( + thomasEmrax, + 'Black Widow Thermal Camera', + testingFacility.shopId, + 2, + ner, + 'Thermal imaging and analysis' + ); }; performSeed() diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 80cbd19a53..1562d543a3 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -4,6 +4,7 @@ import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { machineryTransformer } from '../transformers/calendar.transformer'; +import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; export default class CalendarService { /** @@ -46,13 +47,7 @@ export default class CalendarService { ] } }, - include: { - shops: { - include: { - shop: true - } - } - } + ...getMachineryQueryArgs(organization.organizationId) }); return machineryTransformer(newMachinery); diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 012aff97ff..79ca5c7fe8 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -1,11 +1,15 @@ import { Prisma } from '@prisma/client'; import { Machinery, Shop, ShopMachinery } from 'shared'; import { MachineryQueryArgs, ShopQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; +import { userTransformer } from './user.transformer'; export const shopTransformer = (shop: Prisma.ShopGetPayload): Shop => { return { + shopId: shop.shopId, name: shop.name, - description: shop.description + description: shop.description, + dateCreated: shop.dateCreated, + userCreated: userTransformer(shop.userCreated) }; }; @@ -21,7 +25,10 @@ export const shopMachineryTransformer = ( export const machineryTransformer = (machinery: Prisma.MachineryGetPayload): Machinery => { return { + machineryId: machinery.machineryId, name: machinery.name, - shops: machinery.shops.map(shopMachineryTransformer) + shops: machinery.shops.map(shopMachineryTransformer), + dateCreated: machinery.dateCreated, + userCreated: userTransformer(machinery.userCreated) }; }; diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 4ca68ccfc9..0fb21cdee7 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -32,8 +32,11 @@ export interface EventType { } export interface Shop { + shopId: string; name: string; description: string; + dateCreated: Date; + userCreated: User; } export interface ShopMachinery { @@ -43,8 +46,11 @@ export interface ShopMachinery { } export interface Machinery { + machineryId: string; name: string; shops: ShopMachinery[]; + dateCreated: Date; + userCreated: User; } export interface Event { From ce80f1d497411401a57bb0bb670699826818b129 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 17 Sep 2025 18:27:50 -0400 Subject: [PATCH 049/477] #3565 Updated some types to minimize merge conflict for now --- .../20250904214316_calendar/migration.sql | 22 ++++++++--------- src/backend/src/prisma/schema.prisma | 24 +++++++++---------- src/shared/src/types/calendar-types.ts | 16 +++++++++++++ 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index 9c6c8f6c37..6de267d24a 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -95,17 +95,17 @@ CREATE TABLE "public"."EventType" ( "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, "initialDateScheduled" BOOLEAN, - "allDay" BOOLEAN, - "recurring" BOOLEAN, - "members" BOOLEAN, - "location" BOOLEAN, - "zoomLink" BOOLEAN, - "availabilities" BOOLEAN, - "shop" BOOLEAN, - "machinery" BOOLEAN, - "workPackage" BOOLEAN, - "documents" BOOLEAN, - "description" BOOLEAN, + "allDay" BOOLEAN NOT NULL DEFAULT FALSE, + "recurring" BOOLEAN NOT NULL DEFAULT FALSE, + "members" BOOLEAN NOT NULL DEFAULT FALSE, + "location" BOOLEAN NOT NULL DEFAULT FALSE, + "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, + "availabilities" BOOLEAN NOT NULL DEFAULT FALSE, + "shop" BOOLEAN NOT NULL DEFAULT FALSE, + "machinery" BOOLEAN NOT NULL DEFAULT FALSE, + "workPackage" BOOLEAN NOT NULL DEFAULT FALSE, + "documents" BOOLEAN NOT NULL DEFAULT FALSE, + "description" BOOLEAN NOT NULL DEFAULT FALSE, CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") ); diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 8f3cb5c732..868398e7f2 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -991,18 +991,18 @@ model EventType { userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") calendars Calendar[] - initialDateScheduled Boolean? - allDay Boolean? - recurring Boolean? - members Boolean? - location Boolean? - zoomLink Boolean? - availabilities Boolean? - shop Boolean? - machinery Boolean? - workPackage Boolean? - documents Boolean? - description Boolean? + initialDateScheduled Boolean + allDay Boolean + recurring Boolean + members Boolean + location Boolean + zoomLink Boolean + availabilities Boolean + shop Boolean + machinery Boolean + workPackage Boolean + documents Boolean + description Boolean events Event[] } diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 0fb21cdee7..d8afb8ff70 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -28,7 +28,23 @@ export interface ScheduleSlot { } export interface EventType { + eventTypeId: string; name: string; + userCreated: User; + dateCreated: Date; + initialDateScheduled: boolean; + allDay: boolean; + recurring: boolean; + members: boolean; + location: boolean; + zoomLink: boolean; + availability: boolean; + shop: boolean; + machinery: boolean; + workPackage: boolean; + questionDocument: boolean; + documents: boolean; + description: boolean; } export interface Shop { From a63a12dc0ad3dafa0f24213e449d8ccd0c429bcf Mon Sep 17 00:00:00 2001 From: wavehassman Date: Wed, 17 Sep 2025 18:43:26 -0400 Subject: [PATCH 050/477] #3555 chanes --- .../20250904214316_calendar/migration.sql | 26 +++++++++--------- src/backend/src/prisma/schema.prisma | 26 +++++++++--------- src/backend/src/prisma/seed.ts | 5 ++-- src/backend/src/routes/calendar.routes.ts | 27 ++++++++++--------- src/backend/src/services/calendar.services.ts | 26 +++++++++--------- .../src/transformers/calendar.transformer.ts | 26 +++++++++--------- src/backend/tests/unit/calendar.test.ts | 27 ++++++++++++++++--- src/shared/src/types/calendar-types.ts | 26 +++++++++--------- 8 files changed, 106 insertions(+), 83 deletions(-) diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index 74043a0da0..129354bef9 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -94,19 +94,19 @@ CREATE TABLE "public"."EventType" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, - "initialDateScheduled" BOOLEAN, - "allDay" BOOLEAN, - "recurring" BOOLEAN, - "members" BOOLEAN, - "location" BOOLEAN, - "zoomLink" BOOLEAN, - "availabilities" BOOLEAN, - "shop" BOOLEAN, - "machinery" BOOLEAN, - "workPackage" BOOLEAN, - "questionDocument" BOOLEAN, - "documents" BOOLEAN, - "description" BOOLEAN, + "initialDateScheduled" BOOLEAN NOT NULL DEFAULT FALSE, + "allDay" BOOLEAN NOT NULL DEFAULT FALSE, + "recurring" BOOLEAN NOT NULL DEFAULT FALSE, + "members" BOOLEAN NOT NULL DEFAULT FALSE, + "location" BOOLEAN NOT NULL DEFAULT FALSE, + "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, + "availabilities" BOOLEAN NOT NULL DEFAULT FALSE, + "shop" BOOLEAN NOT NULL DEFAULT FALSE, + "machinery" BOOLEAN NOT NULL DEFAULT FALSE, + "workPackage" BOOLEAN NOT NULL DEFAULT FALSE, + "questionDocument" BOOLEAN NOT NULL DEFAULT FALSE, + "documents" BOOLEAN NOT NULL DEFAULT FALSE, + "description" BOOLEAN NOT NULL DEFAULT FALSE, CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") ); diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 7a443a7eca..df5d6e6d14 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -991,19 +991,19 @@ model EventType { userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") calendars Calendar[] - initialDateScheduled Boolean? - allDay Boolean? - recurring Boolean? - members Boolean? - location Boolean? - zoomLink Boolean? - availabilities Boolean? - shop Boolean? - machinery Boolean? - workPackage Boolean? - questionDocument Boolean? - documents Boolean? - description Boolean? + initialDateScheduled Boolean + allDay Boolean + recurring Boolean + members Boolean + location Boolean + zoomLink Boolean + availabilities Boolean + shop Boolean + machinery Boolean + workPackage Boolean + questionDocument Boolean + documents Boolean + description Boolean events Event[] } diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index f8e877d18a..befe4ba7ef 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3076,7 +3076,7 @@ const performSeed: () => Promise = async () => { await CalendarService.createEventType( thomasEmrax, 'Meeting', - [], + [calendar.calendarId], ner, true, true, @@ -3089,6 +3089,7 @@ const performSeed: () => Promise = async () => { false, true, true, + false, true ); @@ -3096,7 +3097,7 @@ const performSeed: () => Promise = async () => { await CalendarService.createEventType( thomasEmrax, 'Design Review', - [], + [calendar.calendarId], ner, true, true, diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 91f40bdccb..bf1f258867 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -9,19 +9,20 @@ calendarRouter.post( '/event-type/create', nonEmptyString(body('name')), body('calendarIds').isArray(), - body('initialDateScheduled').isBoolean().optional(), - body('allDay').isBoolean().optional(), - body('recurring').isBoolean().optional(), - body('members').isBoolean().optional(), - body('location').isBoolean().optional(), - body('zoomLink').isBoolean().optional(), - body('availabilities').isBoolean().optional(), - body('shop').isBoolean().optional(), - body('machinery').isBoolean().optional(), - body('workPackage').isBoolean().optional(), - body('questionDocument').isBoolean().optional(), - body('documents').isBoolean().optional(), - body('description').isBoolean().optional(), + body('calendarIds.*').isString(), + body('initialDateScheduled').isBoolean(), + body('allDay').isBoolean(), + body('recurring').isBoolean(), + body('members').isBoolean(), + body('location').isBoolean(), + body('zoomLink').isBoolean(), + body('availabilities').isBoolean(), + body('shop').isBoolean(), + body('machinery').isBoolean(), + body('workPackage').isBoolean(), + body('questionDocument').isBoolean(), + body('documents').isBoolean(), + body('description').isBoolean(), validateInputs, CalendarController.createEventType ); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 31c5ed36f5..2301a4a3c5 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -37,19 +37,19 @@ export default class CalendarService { name: string, calendarIds: string[], organization: Organization, - initialDateScheduled?: boolean, - recurring?: boolean, - allDay?: boolean, - members?: boolean, - location?: boolean, - zoomLink?: boolean, - availabilities?: boolean, - shop?: boolean, - machinery?: boolean, - workPackage?: boolean, - questionDocument?: boolean, - documents?: boolean, - description?: boolean + initialDateScheduled: boolean, + recurring: boolean, + allDay: boolean, + members: boolean, + location: boolean, + zoomLink: boolean, + availabilities: boolean, + shop: boolean, + machinery: boolean, + workPackage: boolean, + questionDocument: boolean, + documents: boolean, + description: boolean ): Promise { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create event type'); diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index a5801e4353..5d4f17bf0e 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -9,18 +9,18 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload { let orgId: string; let organization: Organization; + let calendar: Calendar; beforeEach(async () => { organization = await createTestOrganization(); orgId = organization.organizationId; + calendar = await prisma.calendar.create({ + data: { + name: 'Engineering Team Calendar', + description: 'Tracks all engineering team events, meetings, and deadlines.', + colorHexCode: '#3498db', + userCreated: { connect: { userId: (await createTestUser(supermanAdmin, orgId)).userId } }, + dateCreated: new Date() + } + }); }); afterEach(async () => { @@ -24,9 +35,19 @@ describe('Calendar Tests', () => { await CalendarService.createEventType( await createTestUser(wonderwomanGuest, orgId), 'Team Meeting', - [], + [calendar.calendarId], organization, true, + true, + true, + true, + true, + true, + false, + false, + false, + true, + true, false, true ) diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index fb14fabd78..4659abb942 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -36,19 +36,19 @@ export interface EventType { name: string; userCreated: User; dateCreated: Date; - initialDateScheduled?: boolean; - allDay?: boolean; - recurring?: boolean; - members?: boolean; - location?: boolean; - zoomLink?: boolean; - availability?: boolean; - shop?: boolean; - machinery?: boolean; - workPackage?: boolean; - questionDocument?: boolean; - documents?: boolean; - description?: boolean; + initialDateScheduled: boolean; + allDay: boolean; + recurring: boolean; + members: boolean; + location: boolean; + zoomLink: boolean; + availability: boolean; + shop: boolean; + machinery: boolean; + workPackage: boolean; + questionDocument: boolean; + documents: boolean; + description: boolean; } export interface Shop { From 9591b24e413cb565e2a4ce8ea4847b08897e23b1 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 17 Sep 2025 18:54:01 -0400 Subject: [PATCH 051/477] folder changes --- src/backend/index.ts | 4 ++-- .../{shop.controllers.ts => calendar.controllers.ts} | 4 ++-- src/backend/src/prisma/seed.ts | 6 +++--- .../src/routes/{shop.routes.ts => calendar.routes.ts} | 4 ++-- .../src/services/{shop.services.ts => calendar.services.ts} | 0 5 files changed, 9 insertions(+), 9 deletions(-) rename src/backend/src/controllers/{shop.controllers.ts => calendar.controllers.ts} (63%) rename src/backend/src/routes/{shop.routes.ts => calendar.routes.ts} (77%) rename src/backend/src/services/{shop.services.ts => calendar.services.ts} (100%) diff --git a/src/backend/index.ts b/src/backend/index.ts index 10b4e921ff..f958e82b98 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -25,7 +25,7 @@ import statisticsRouter from './src/routes/statistics.routes'; import retrospectiveRouter from './src/routes/retrospective.routes'; import partsRouter from './src/routes/parts.routes'; import financeRouter from './src/routes/finance.routes'; -import shopRouter from './src/routes/shop.routes'; +import calendarRouter from './src/routes/calendar.routes'; const app = express(); @@ -88,7 +88,7 @@ app.use('/statistics', statisticsRouter); app.use('/retrospective', retrospectiveRouter); app.use('/parts', partsRouter); app.use('/finance', financeRouter); -app.use('/shops', shopRouter); +app.use('/calendar', calendarRouter); app.use('/', (_req, res) => { res.status(200).json('Welcome to FinishLine'); }); diff --git a/src/backend/src/controllers/shop.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts similarity index 63% rename from src/backend/src/controllers/shop.controllers.ts rename to src/backend/src/controllers/calendar.controllers.ts index f7beffeb91..5b2b403cce 100644 --- a/src/backend/src/controllers/shop.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -1,11 +1,11 @@ import { NextFunction, Request, Response } from 'express'; -import ShopService from '../services/shop.services'; +import CalendarService from '../services/calendar.services'; export default class ShopController { static async createShop(req: Request, res: Response, next: NextFunction) { try { const { name, description } = req.body; - const shop = await ShopService.createShop((req as any).currentUser, name, description, (req as any).organization); + const shop = await CalendarService.createShop((req as any).currentUser, name, description, (req as any).organization); res.status(201).json(shop); } catch (error) { next(error); diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 39210e3c22..7773ea110e 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -50,7 +50,7 @@ import AnnouncementService from '../services/announcement.services'; import OnboardingServices from '../services/onboarding.services'; import { dbSeedAllParts, dbSeedAllPartTags } from './seed-data/parts.seed'; import FinanceServices from '../services/finance.services'; -import ShopServices from '../services/shop.services'; +import CalendarServices from '../services/calendar.services'; const prisma = new PrismaClient(); @@ -3061,14 +3061,14 @@ const performSeed: () => Promise = async () => { thomasEmrax.userId ); - await ShopServices.createShop( + await CalendarServices.createShop( thomasEmrax, 'Precision Manufacturing Lab', 'CNC machining and precision manufacturing facility', ner ); - await ShopServices.createShop(thomasEmrax, 'Electronics Design Center', 'Electronics testing and circuit design lab', ner); + await CalendarServices.createShop(thomasEmrax, 'Electronics Design Center', 'Electronics testing and circuit design lab', ner); }; performSeed() diff --git a/src/backend/src/routes/shop.routes.ts b/src/backend/src/routes/calendar.routes.ts similarity index 77% rename from src/backend/src/routes/shop.routes.ts rename to src/backend/src/routes/calendar.routes.ts index ae70de6c97..ad90809115 100644 --- a/src/backend/src/routes/shop.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,7 +1,7 @@ import express from 'express'; import { body } from 'express-validator'; import { nonEmptyString, validateInputs } from '../utils/validation.utils'; -import ShopController from '../controllers/shop.controllers'; +import CalendarController from '../controllers/calendar.controllers'; const shopRouter = express.Router(); shopRouter.post( @@ -9,7 +9,7 @@ shopRouter.post( nonEmptyString(body('name')), nonEmptyString(body('description')), validateInputs, - ShopController.createShop + CalendarController.createShop ); export default shopRouter; diff --git a/src/backend/src/services/shop.services.ts b/src/backend/src/services/calendar.services.ts similarity index 100% rename from src/backend/src/services/shop.services.ts rename to src/backend/src/services/calendar.services.ts From 5af17604b8b5d17d63bc94f725f878ccbb822a98 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 17 Sep 2025 19:40:06 -0400 Subject: [PATCH 052/477] Addition of transformer and query-args --- .../src/prisma-query-args/shop.query-args.ts | 11 +++++++++++ .../src/transformers/calendar.transformer.ts | 16 +++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/backend/src/prisma-query-args/shop.query-args.ts diff --git a/src/backend/src/prisma-query-args/shop.query-args.ts b/src/backend/src/prisma-query-args/shop.query-args.ts new file mode 100644 index 0000000000..36a1009ce0 --- /dev/null +++ b/src/backend/src/prisma-query-args/shop.query-args.ts @@ -0,0 +1,11 @@ +import { Prisma } from '@prisma/client'; +import { getUserQueryArgs } from './user.query-args'; + +export type ShopQueryArgs = ReturnType; + +export const getShopQueryArgs = (organizationId: string) => + Prisma.validator()({ + include: { + userCreated: getUserQueryArgs(organizationId), + }, + }); diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 5d4f17bf0e..3ccd332a0c 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -1,5 +1,7 @@ import { Prisma } from '@prisma/client'; import { EventType } from 'shared'; +import { Shop } from 'shared'; +import { ShopQueryArgs } from '../prisma-query-args/shop.query-args'; import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { userTransformer } from './user.transformer'; @@ -23,4 +25,16 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload + ): Shop => { + return { + shopId: shop.shopId, + name: shop.name, + description: shop.description ?? '', + userCreated: userTransformer(shop.userCreated), + dateCreated: shop.dateCreated, + }; +} + From 6db096486739d733dd4ff8ae48e22282ba4e20bc Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 17 Sep 2025 19:54:14 -0400 Subject: [PATCH 053/477] fixing checks --- .../src/prisma-query-args/shop.query-args.ts | 4 +- src/backend/src/services/calendar.services.ts | 4 +- .../src/transformers/calendar.transformer.ts | 13 +++--- src/backend/tests/unit/calendar.test.ts | 37 ++++++++++++++++ src/backend/tests/unit/shop.test.ts | 43 ------------------- 5 files changed, 45 insertions(+), 56 deletions(-) delete mode 100644 src/backend/tests/unit/shop.test.ts diff --git a/src/backend/src/prisma-query-args/shop.query-args.ts b/src/backend/src/prisma-query-args/shop.query-args.ts index 36a1009ce0..0e327f5e92 100644 --- a/src/backend/src/prisma-query-args/shop.query-args.ts +++ b/src/backend/src/prisma-query-args/shop.query-args.ts @@ -6,6 +6,6 @@ export type ShopQueryArgs = ReturnType; export const getShopQueryArgs = (organizationId: string) => Prisma.validator()({ include: { - userCreated: getUserQueryArgs(organizationId), - }, + userCreated: getUserQueryArgs(organizationId) + } }); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 7e8fa9c09c..d404832014 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -81,7 +81,7 @@ export default class CalendarService { return eventTypeTransformer(newEventType); } - /** + /** * Creates a new shop * requires the submiter to be Admin */ @@ -99,5 +99,3 @@ export default class CalendarService { return shop; } } - - diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 3ccd332a0c..3ec969ad0d 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -25,16 +25,13 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload - ): Shop => { - return { +}; +export const shopTransformer = (shop: Prisma.ShopGetPayload): Shop => { + return { shopId: shop.shopId, name: shop.name, description: shop.description ?? '', userCreated: userTransformer(shop.userCreated), - dateCreated: shop.dateCreated, + dateCreated: shop.dateCreated }; -} - +}; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index d548ee334b..81b5770a6c 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -91,4 +91,41 @@ describe('Calendar Tests', () => { expect(result.description).toBe(true); }); }); + describe('Shop Tests', () => { + let organization: Organization; + let orgId: string; + + beforeEach(async () => { + organization = await createTestOrganization(); + orgId = organization.organizationId; + }); + + afterEach(async () => { + await resetUsers(); + }); + + describe('create shop', () => { + it('fails if user is not an admin', async () => { + await expect( + CalendarService.createShop(await createTestUser(wonderwomanGuest, orgId), 'Non-Admin Shop', 'desc', organization) + ).rejects.toThrow(new AccessDeniedAdminOnlyException('create shop')); + }); + + it('succeeds for admin', async () => { + const admin = await createTestUser(supermanAdmin, orgId); + const result = await CalendarService.createShop(admin, 'Demo Shop', 'A seeded demo shop', organization); + + expect(result.name).toBe('Demo Shop'); + expect(result.description).toBe('A seeded demo shop'); + expect(result.userCreatedId).toBe(admin.userId); + }); + + it('fails on duplicate name', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); + await CalendarService.createShop(admin, 'UniqueName', 'first', organization); + + await expect(CalendarService.createShop(admin, 'UniqueName', 'second attempt', organization)).rejects.toBeTruthy(); + }); + }); + }); }); diff --git a/src/backend/tests/unit/shop.test.ts b/src/backend/tests/unit/shop.test.ts deleted file mode 100644 index efc6ca95c7..0000000000 --- a/src/backend/tests/unit/shop.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Organization } from '@prisma/client'; -import ShopServices from '../../src/services/shop.services'; -import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; -import { batmanAppAdmin, wonderwomanGuest, supermanAdmin } from '../test-data/users.test-data'; -import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; - -describe('Shop Tests', () => { - let organization: Organization; - let orgId: string; - - beforeEach(async () => { - organization = await createTestOrganization(); - orgId = organization.organizationId; - }); - - afterEach(async () => { - await resetUsers(); - }); - - describe('create shop', () => { - it('fails if user is not an admin', async () => { - await expect( - ShopServices.createShop(await createTestUser(wonderwomanGuest, orgId), 'Non-Admin Shop', 'desc', organization) - ).rejects.toThrow(new AccessDeniedAdminOnlyException('create shop')); - }); - - it('succeeds for admin', async () => { - const admin = await createTestUser(supermanAdmin, orgId); - const result = await ShopServices.createShop(admin, 'Demo Shop', 'A seeded demo shop', organization); - - expect(result.name).toBe('Demo Shop'); - expect(result.description).toBe('A seeded demo shop'); - expect(result.userCreatedId).toBe(admin.userId); - }); - - it('fails on duplicate name', async () => { - const admin = await createTestUser(batmanAppAdmin, orgId); - await ShopServices.createShop(admin, 'UniqueName', 'first', organization); - - await expect(ShopServices.createShop(admin, 'UniqueName', 'second attempt', organization)).rejects.toBeTruthy(); - }); - }); -}); From f998f9fff4ccfed0d00dc239715fba8953f7f7d4 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 17 Sep 2025 20:09:28 -0400 Subject: [PATCH 054/477] #3565 fixed calendar tests --- src/backend/tests/unit/calendar.test.ts | 118 ++++++++++++------------ 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index b6921e6f58..11c38e3614 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,4 +1,3 @@ -import MachineryService from '../../src/services/calendar.services'; import { Calendar, Organization } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; @@ -6,76 +5,42 @@ import { batmanAppAdmin, wonderwomanGuest, supermanAdmin } from '../test-data/us import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; -describe('Machinery Tests', () => { +describe('Calendar Tests', () => { let orgId: string; let organization: Organization; + let calendar: Calendar; let shopId: string; - describe('Calendar Tests', () => { - let orgId: string; - let organization: Organization; - let calendar: Calendar; - beforeEach(async () => { - organization = await createTestOrganization(); - orgId = organization.organizationId; + beforeEach(async () => { + organization = await createTestOrganization(); + orgId = organization.organizationId; - // Create a test shop for shopId, assuming prisma create shop works - const shopName = 'Precision Manufacturing Lab'; - const shop = await prisma.shop.create({ - data: { - name: shopName, - description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', - userCreatedId: (await createTestUser(batmanAppAdmin, orgId)).userId - } - }); - ({ shopId } = shop); - calendar = await prisma.calendar.create({ - data: { - name: 'Engineering Team Calendar', - description: 'Tracks all engineering team events, meetings, and deadlines.', - colorHexCode: '#3498db', - userCreated: { connect: { userId: (await createTestUser(supermanAdmin, orgId)).userId } }, - dateCreated: new Date() - } - }); + calendar = await prisma.calendar.create({ + data: { + name: 'Engineering Team Calendar', + description: 'Tracks all engineering team events, meetings, and deadlines.', + colorHexCode: '#3498db', + userCreated: { connect: { userId: (await createTestUser(supermanAdmin, orgId)).userId } }, + dateCreated: new Date() + } }); - afterEach(async () => { - await resetUsers(); + // Create a test shop for machinery tests + const shopName = 'Precision Manufacturing Lab'; + const shop = await prisma.shop.create({ + data: { + name: shopName, + description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', + userCreatedId: (await createTestUser(batmanAppAdmin, orgId)).userId + } }); + ({ shopId } = shop); + }); - describe('Create machinery', () => { - it('Fails if user is not an admin', async () => { - await expect( - async () => - await MachineryService.createMachinery( - await createTestUser(wonderwomanGuest, orgId), - 'Captain America Shield Press', - shopId, - 1, - organization - ) - ).rejects.toThrow(new AccessDeniedAdminOnlyException('create machinery')); - }); - - it('Succeeds and creates machinery', async () => { - const result = await MachineryService.createMachinery( - await createTestUser(supermanAdmin, orgId), - 'Iron Man Mark 42 CNC Mill', - shopId, - 2, - organization - ); - - expect(result.name).toEqual('Iron Man Mark 42 CNC Mill'); - expect(result.shops).toHaveLength(1); - expect(result.shops[0].quantity).toBe(2); - expect(result.shops[0].shop.name).toBe('Precision Manufacturing Lab'); - expect(result.shops[0].description).toBe(undefined); - }); - }); + afterEach(async () => { + await resetUsers(); }); - //16d5afbe-95f0-4214-8a31-100e5e7e408d + describe('Create EventType', () => { it('Fails if user is not an admin', async () => { await expect( @@ -139,4 +104,35 @@ describe('Machinery Tests', () => { expect(result.description).toBe(true); }); }); + + describe('Create Machinery', () => { + it('Fails if user is not an admin', async () => { + await expect( + async () => + await CalendarService.createMachinery( + await createTestUser(wonderwomanGuest, orgId), + 'Captain America Shield Press', + shopId, + 1, + organization + ) + ).rejects.toThrow(new AccessDeniedAdminOnlyException('create machinery')); + }); + + it('Succeeds and creates machinery', async () => { + const result = await CalendarService.createMachinery( + await createTestUser(supermanAdmin, orgId), + 'Iron Man Mark 42 CNC Mill', + shopId, + 2, + organization + ); + + expect(result.name).toEqual('Iron Man Mark 42 CNC Mill'); + expect(result.shops).toHaveLength(1); + expect(result.shops[0].quantity).toBe(2); + expect(result.shops[0].shop.name).toBe('Precision Manufacturing Lab'); + expect(result.shops[0].description).toBe(undefined); + }); + }); }); From 0f0e8c87c06cd26747960a1d439f043b90fde7b3 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 17 Sep 2025 20:43:44 -0400 Subject: [PATCH 055/477] #3565 machinery test fix hopefully? --- src/backend/tests/unit/calendar.test.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 11c38e3614..8adab0828b 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -106,6 +106,25 @@ describe('Calendar Tests', () => { }); describe('Create Machinery', () => { + beforeEach(async () => { + organization = await createTestOrganization(); + orgId = organization.organizationId; + // Create a test shop for shopId, assuming prisma create shop works + const shopName = 'Precision Manufacturing Lab'; + const shop = await prisma.shop.create({ + data: { + name: shopName, + description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', + userCreatedId: (await createTestUser(batmanAppAdmin, orgId)).userId + } + }); + ({ shopId } = shop); + }); + + afterEach(async () => { + await resetUsers(); + }); + it('Fails if user is not an admin', async () => { await expect( async () => From 2e71aa6879ccdc17f6c7bac99abfa769b8f80204 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 17 Sep 2025 21:09:22 -0400 Subject: [PATCH 056/477] #3565 Tried to update calendar structure fix --- src/backend/tests/unit/calendar.test.ts | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 8adab0828b..f0a4fa3f64 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -25,11 +25,9 @@ describe('Calendar Tests', () => { } }); - // Create a test shop for machinery tests - const shopName = 'Precision Manufacturing Lab'; const shop = await prisma.shop.create({ data: { - name: shopName, + name: 'Precision Manufacturing Lab', description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', userCreatedId: (await createTestUser(batmanAppAdmin, orgId)).userId } @@ -106,25 +104,6 @@ describe('Calendar Tests', () => { }); describe('Create Machinery', () => { - beforeEach(async () => { - organization = await createTestOrganization(); - orgId = organization.organizationId; - // Create a test shop for shopId, assuming prisma create shop works - const shopName = 'Precision Manufacturing Lab'; - const shop = await prisma.shop.create({ - data: { - name: shopName, - description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', - userCreatedId: (await createTestUser(batmanAppAdmin, orgId)).userId - } - }); - ({ shopId } = shop); - }); - - afterEach(async () => { - await resetUsers(); - }); - it('Fails if user is not an admin', async () => { await expect( async () => From a30d3fcf8df96f79e274ffe5c4023b23132e22cc Mon Sep 17 00:00:00 2001 From: wavehassman Date: Wed, 17 Sep 2025 22:44:20 -0400 Subject: [PATCH 057/477] #3565 fix tests --- src/backend/tests/unit/calendar.test.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index f0a4fa3f64..a2939eabaa 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,7 +1,14 @@ import { Calendar, Organization } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; -import { batmanAppAdmin, wonderwomanGuest, supermanAdmin } from '../test-data/users.test-data'; +import { + batmanAppAdmin, + wonderwomanGuest, + supermanAdmin, + flashAdmin, + theVisitorGuest, + alfred +} from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; @@ -29,7 +36,7 @@ describe('Calendar Tests', () => { data: { name: 'Precision Manufacturing Lab', description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', - userCreatedId: (await createTestUser(batmanAppAdmin, orgId)).userId + userCreatedId: (await createTestUser(flashAdmin, orgId)).userId } }); ({ shopId } = shop); @@ -44,7 +51,7 @@ describe('Calendar Tests', () => { await expect( async () => await CalendarService.createEventType( - await createTestUser(wonderwomanGuest, orgId), + await createTestUser(theVisitorGuest, orgId), 'Team Meeting', [calendar.calendarId], organization, @@ -119,7 +126,7 @@ describe('Calendar Tests', () => { it('Succeeds and creates machinery', async () => { const result = await CalendarService.createMachinery( - await createTestUser(supermanAdmin, orgId), + await createTestUser(alfred, orgId), 'Iron Man Mark 42 CNC Mill', shopId, 2, From 32cf9dac57dfc0c8db58460491b31f18e52154c4 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 17 Sep 2025 22:58:25 -0400 Subject: [PATCH 058/477] #3565 Removed fallback falses (defaulted in database) --- src/backend/src/transformers/calendar.transformer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index c553a854a7..6d9247bf5b 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -42,9 +42,9 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload Date: Thu, 18 Sep 2025 13:41:28 -0400 Subject: [PATCH 059/477] fixing tests from merging --- src/backend/tests/unit/calendar.test.ts | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 81b5770a6c..8d6b1f2f47 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -92,38 +92,28 @@ describe('Calendar Tests', () => { }); }); describe('Shop Tests', () => { - let organization: Organization; - let orgId: string; - - beforeEach(async () => { - organization = await createTestOrganization(); - orgId = organization.organizationId; - }); - - afterEach(async () => { - await resetUsers(); - }); - describe('create shop', () => { it('fails if user is not an admin', async () => { await expect( CalendarService.createShop(await createTestUser(wonderwomanGuest, orgId), 'Non-Admin Shop', 'desc', organization) ).rejects.toThrow(new AccessDeniedAdminOnlyException('create shop')); }); - + it('succeeds for admin', async () => { - const admin = await createTestUser(supermanAdmin, orgId); + // Using a different admin fixture to avoid googleAuthId collision with the calendar creator + const admin = await createTestUser(batmanAppAdmin, orgId); + const result = await CalendarService.createShop(admin, 'Demo Shop', 'A seeded demo shop', organization); - + expect(result.name).toBe('Demo Shop'); expect(result.description).toBe('A seeded demo shop'); expect(result.userCreatedId).toBe(admin.userId); }); - + it('fails on duplicate name', async () => { const admin = await createTestUser(batmanAppAdmin, orgId); await CalendarService.createShop(admin, 'UniqueName', 'first', organization); - + await expect(CalendarService.createShop(admin, 'UniqueName', 'second attempt', organization)).rejects.toBeTruthy(); }); }); From 57dce7740df32481ca93cac6fd899a197b42f77d Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 20 Sep 2025 11:25:20 -0400 Subject: [PATCH 060/477] Creating route and adding transformer to services --- src/backend/src/routes/calendar.routes.ts | 8 ++++++++ src/backend/src/services/calendar.services.ts | 20 +++++++++++-------- src/backend/tests/unit/calendar.test.ts | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index bf1f258867..8306e9d04a 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -27,4 +27,12 @@ calendarRouter.post( CalendarController.createEventType ); +calendarRouter.post( + '/shop/create', + nonEmptyString(body('name')), + body('description').optional().isString(), + validateInputs, + CalendarController.createShop +); + export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index d404832014..43f74ae9cd 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,10 +1,12 @@ import { Organization, User } from '@prisma/client'; -import { isAdmin, EventType } from 'shared'; +import { isAdmin, EventType, Shop } from 'shared'; import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; +import { shopTransformer } from '../transformers/calendar.transformer'; +import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; export default class CalendarService { /** @@ -83,19 +85,21 @@ export default class CalendarService { } /** * Creates a new shop - * requires the submiter to be Admin + * requires the submitter to be Admin */ - static async createShop(submitter: User, name: string, description: string, organization: Organization) { - const permission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); - if (!permission) throw new AccessDeniedAdminOnlyException('create shop'); + static async createShop(submitter: User, name: string, description: string, organization: Organization): Promise { + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); + if (!hasPermission) throw new AccessDeniedAdminOnlyException('create shop'); - const shop = await prisma.shop.create({ + const newShop = await prisma.shop.create({ data: { name, description, userCreatedId: submitter.userId - } + }, + ...getShopQueryArgs(organization.organizationId) }); - return shop; + + return shopTransformer(newShop); } } diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 8d6b1f2f47..784451d9a9 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -107,7 +107,7 @@ describe('Calendar Tests', () => { expect(result.name).toBe('Demo Shop'); expect(result.description).toBe('A seeded demo shop'); - expect(result.userCreatedId).toBe(admin.userId); + expect(result.userCreated.userId).toBe(admin.userId); }); it('fails on duplicate name', async () => { From 5d2b4aae4c169d56c00f7ca2831883371e2e01b3 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 20 Sep 2025 11:34:50 -0400 Subject: [PATCH 061/477] Fixed the casting issue --- src/backend/src/controllers/calendar.controllers.ts | 8 +++++--- src/backend/src/transformers/calendar.transformer.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index b6d0731139..164458f279 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -50,9 +50,11 @@ export default class CalendarController { static async createShop(req: Request, res: Response, next: NextFunction) { try { const { name, description } = req.body; - const shop = await CalendarService.createShop((req as any).currentUser, name, description, (req as any).organization); - res.status(201).json(shop); - } catch (error) { + + const shop = await CalendarService.createShop(req.currentUser, name, description, req.organization); + + res.status(200).json(shop); + } catch (error: unknown) { next(error); } } diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 3ec969ad0d..1bc889d147 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -30,7 +30,7 @@ export const shopTransformer = (shop: Prisma.ShopGetPayload): Sho return { shopId: shop.shopId, name: shop.name, - description: shop.description ?? '', + description: shop.description, userCreated: userTransformer(shop.userCreated), dateCreated: shop.dateCreated }; From eec12f9de366fd25fdc2c921815ffabec2f19ab1 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 20 Sep 2025 11:39:17 -0400 Subject: [PATCH 062/477] condensing permissions variable --- src/backend/src/services/calendar.services.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 43f74ae9cd..5dd6979831 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -88,8 +88,9 @@ export default class CalendarService { * requires the submitter to be Admin */ static async createShop(submitter: User, name: string, description: string, organization: Organization): Promise { - const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); - if (!hasPermission) throw new AccessDeniedAdminOnlyException('create shop'); + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('create shop'); + } const newShop = await prisma.shop.create({ data: { From d8231a14bf8a356ee3d5b7f1767e614a5f9a9f26 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 21 Sep 2025 13:12:44 -0400 Subject: [PATCH 063/477] #3565 check shop exist for the machinery and organization --- src/backend/src/services/calendar.services.ts | 25 ++++++++++++++++++- src/backend/src/utils/errors.utils.ts | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 694ae456e0..4e2e67430b 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -3,7 +3,7 @@ import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args import { Organization, User } from '@prisma/client'; import { isAdmin, EventType } from 'shared'; import prisma from '../prisma/prisma'; -import { AccessDeniedAdminOnlyException } from '../utils/errors.utils'; +import { AccessDeniedAdminOnlyException, NotFoundException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; @@ -96,6 +96,7 @@ export default class CalendarService { * @returns The created machinery object with associated shop machinery. * * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + * @throws NotFoundException If the shop with the given shopId does not exist. */ static async createMachinery( submitter: User, @@ -110,6 +111,28 @@ export default class CalendarService { throw new AccessDeniedAdminOnlyException('create machinery'); } + // Check if shop with id exists and belongs to the same organization + const existingShop = await prisma.shop.findUnique({ + where: { shopId }, + include: { + userCreated: { + include: { + organizations: { + where: { organizationId: organization.organizationId } + } + } + } + } + }); + + if (!existingShop) { + throw new NotFoundException('Shop', shopId); + } + + if (existingShop.userCreated.organizations.length === 0) { + throw new AccessDeniedAdminOnlyException('create machinery for shop in different organization'); + } + const newMachinery = await prisma.machinery.create({ data: { name, diff --git a/src/backend/src/utils/errors.utils.ts b/src/backend/src/utils/errors.utils.ts index f0de5d014a..aacca11e89 100644 --- a/src/backend/src/utils/errors.utils.ts +++ b/src/backend/src/utils/errors.utils.ts @@ -157,6 +157,7 @@ export type ExceptionObjectNames = | 'Graph Collection' | 'Sponsor' | 'SponsorTask' + | 'Shop' | 'Sponsor Tier' | 'Index Code' | 'Reimbursement Product Other Reason' From 8bf6b8470e0b8f9e74f4beb4b2a44bbf742bbc54 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 21 Sep 2025 13:58:36 -0400 Subject: [PATCH 064/477] #3565 resolve conflict --- .../src/controllers/calendar.controllers.ts | 23 +++++++++++++-- .../src/prisma-query-args/shop.query-args.ts | 11 ++++++++ src/backend/src/routes/calendar.routes.ts | 9 ++++++ src/backend/src/services/calendar.services.ts | 24 +++++++++++++++- .../src/transformers/calendar.transformer.ts | 2 ++ src/backend/tests/test-utils.ts | 3 ++ src/backend/tests/unit/calendar.test.ts | 28 +++++++++++++++++++ 7 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 src/backend/src/prisma-query-args/shop.query-args.ts diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 022e4c3735..fbb2cbc8dd 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -49,12 +49,31 @@ export default class CalendarController { static async createMachinery(req: Request, res: Response, next: NextFunction) { try { - const { name, shopId, quantity } = req.body; + const { name, shopId, quantity, description } = req.body; - const machinery = await MachineryService.createMachinery(req.currentUser, name, shopId, quantity, req.organization); + const machinery = await CalendarService.createMachinery( + req.currentUser, + name, + shopId, + quantity, + req.organization, + description + ); res.status(200).json(machinery); } catch (error: unknown) { next(error); } } + + static async createShop(req: Request, res: Response, next: NextFunction) { + try { + const { name, description } = req.body; + + const shop = await CalendarService.createShop(req.currentUser, name, description, req.organization); + + res.status(200).json(shop); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/prisma-query-args/shop.query-args.ts b/src/backend/src/prisma-query-args/shop.query-args.ts new file mode 100644 index 0000000000..0e327f5e92 --- /dev/null +++ b/src/backend/src/prisma-query-args/shop.query-args.ts @@ -0,0 +1,11 @@ +import { Prisma } from '@prisma/client'; +import { getUserQueryArgs } from './user.query-args'; + +export type ShopQueryArgs = ReturnType; + +export const getShopQueryArgs = (organizationId: string) => + Prisma.validator()({ + include: { + userCreated: getUserQueryArgs(organizationId) + } + }); diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 179929de62..03ad7c2fe4 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -32,8 +32,17 @@ calendarRouter.post( nonEmptyString(body('name')), nonEmptyString(body('shopId')), body('quantity').isInt({ min: 1 }), + body('description').optional().isString(), validateInputs, CalendarController.createMachinery ); +calendarRouter.post( + '/shop/create', + nonEmptyString(body('name')), + body('description').optional().isString(), + validateInputs, + CalendarController.createShop +); + export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 4e2e67430b..452ba35650 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,12 +1,14 @@ import { machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { Organization, User } from '@prisma/client'; -import { isAdmin, EventType } from 'shared'; +import { isAdmin, EventType, Shop } from 'shared'; import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException, NotFoundException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; +import { shopTransformer } from '../transformers/calendar.transformer'; +import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; export default class CalendarService { /** @@ -152,4 +154,24 @@ export default class CalendarService { return machineryTransformer(newMachinery); } + /** + * Creates a new shop + * requires the submitter to be Admin + */ + static async createShop(submitter: User, name: string, description: string, organization: Organization): Promise { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('create shop'); + } + + const newShop = await prisma.shop.create({ + data: { + name, + description, + userCreatedId: submitter.userId + }, + ...getShopQueryArgs(organization.organizationId) + }); + + return shopTransformer(newShop); + } } diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 6d9247bf5b..933409381a 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -3,6 +3,8 @@ import { Machinery, Shop, ShopMachinery } from 'shared'; import { MachineryQueryArgs, ShopQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { userTransformer } from './user.transformer'; import { EventType } from 'shared'; +import { Shop } from 'shared'; +import { ShopQueryArgs } from '../prisma-query-args/shop.query-args'; import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; export const shopTransformer = (shop: Prisma.ShopGetPayload): Shop => { diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index 84f5a59054..bdc45e2ae5 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -172,6 +172,9 @@ export const resetUsers = async () => { await prisma.eventType.deleteMany(); await prisma.calendar.deleteMany(); await prisma.organization.deleteMany(); + await prisma.shopMachinery.deleteMany(); + await prisma.machinery.deleteMany(); + await prisma.shop.deleteMany(); await prisma.user.deleteMany(); }; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index a2939eabaa..b74e7a7782 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -140,4 +140,32 @@ describe('Calendar Tests', () => { expect(result.shops[0].description).toBe(undefined); }); }); + + describe('Shop Tests', () => { + describe('create shop', () => { + it('fails if user is not an admin', async () => { + await expect( + CalendarService.createShop(await createTestUser(wonderwomanGuest, orgId), 'Non-Admin Shop', 'desc', organization) + ).rejects.toThrow(new AccessDeniedAdminOnlyException('create shop')); + }); + + it('succeeds for admin', async () => { + // Using a different admin fixture to avoid googleAuthId collision with the calendar creator + const admin = await createTestUser(batmanAppAdmin, orgId); + + const result = await CalendarService.createShop(admin, 'Demo Shop', 'A seeded demo shop', organization); + + expect(result.name).toBe('Demo Shop'); + expect(result.description).toBe('A seeded demo shop'); + expect(result.userCreated.userId).toBe(admin.userId); + }); + + it('fails on duplicate name', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); + await CalendarService.createShop(admin, 'UniqueName', 'first', organization); + + await expect(CalendarService.createShop(admin, 'UniqueName', 'second attempt', organization)).rejects.toBeTruthy(); + }); + }); + }); }); From a64826c80a68190ed1316999a9dbcd7ad0428c81 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 21 Sep 2025 14:10:52 -0400 Subject: [PATCH 065/477] #3565 fixing linting issues --- src/backend/tests/unit/calendar.test.ts | 27 ------------------------- 1 file changed, 27 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 7c0b1fe39a..b74e7a7782 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -168,31 +168,4 @@ describe('Calendar Tests', () => { }); }); }); - describe('Shop Tests', () => { - describe('create shop', () => { - it('fails if user is not an admin', async () => { - await expect( - CalendarService.createShop(await createTestUser(wonderwomanGuest, orgId), 'Non-Admin Shop', 'desc', organization) - ).rejects.toThrow(new AccessDeniedAdminOnlyException('create shop')); - }); - - it('succeeds for admin', async () => { - // Using a different admin fixture to avoid googleAuthId collision with the calendar creator - const admin = await createTestUser(batmanAppAdmin, orgId); - - const result = await CalendarService.createShop(admin, 'Demo Shop', 'A seeded demo shop', organization); - - expect(result.name).toBe('Demo Shop'); - expect(result.description).toBe('A seeded demo shop'); - expect(result.userCreated.userId).toBe(admin.userId); - }); - - it('fails on duplicate name', async () => { - const admin = await createTestUser(batmanAppAdmin, orgId); - await CalendarService.createShop(admin, 'UniqueName', 'first', organization); - - await expect(CalendarService.createShop(admin, 'UniqueName', 'second attempt', organization)).rejects.toBeTruthy(); - }); - }); - }); }); From bafb398f4b0b1e40d991df2e968446d419f9030c Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 21 Sep 2025 18:35:57 -0400 Subject: [PATCH 066/477] #3610 added organization to shop, machinery, calendar and event type tables --- .../20250904214316_calendar/migration.sql | 28 ++++++ .../src/prisma/migrations/migration_lock.toml | 2 +- src/backend/src/prisma/schema.prisma | 92 +++++++++++-------- src/backend/src/prisma/seed.ts | 3 +- src/backend/src/services/calendar.services.ts | 6 +- src/backend/tests/test-utils.ts | 2 +- src/backend/tests/unit/calendar.test.ts | 3 +- 7 files changed, 94 insertions(+), 42 deletions(-) diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index 129354bef9..e2ddd4581d 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -13,6 +13,7 @@ CREATE TABLE "public"."Shop" ( "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, "description" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId") ); @@ -25,6 +26,7 @@ CREATE TABLE "public"."Machinery" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, + "organizationId" TEXT NOT NULL, CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId") ); @@ -82,6 +84,7 @@ CREATE TABLE "public"."Calendar" ( "userDeletedId" TEXT, "description" TEXT NOT NULL, "colorHexCode" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId") ); @@ -107,6 +110,7 @@ CREATE TABLE "public"."EventType" ( "questionDocument" BOOLEAN NOT NULL DEFAULT FALSE, "documents" BOOLEAN NOT NULL DEFAULT FALSE, "description" BOOLEAN NOT NULL DEFAULT FALSE, + "organizationId" TEXT NOT NULL, CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") ); @@ -186,6 +190,30 @@ CREATE INDEX "_EventToWork_Package_B_index" ON "public"."_EventToWork_Package"(" -- CreateIndex CREATE INDEX "_CalendarToEventType_B_index" ON "public"."_CalendarToEventType"("B"); +-- CreateIndex +CREATE UNIQUE INDEX "Calendar_name_organizationId_key" ON "Calendar"("name", "organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "EventType_name_organizationId_key" ON "EventType"("name", "organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Machinery_name_organizationId_key" ON "Machinery"("name", "organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Shop_name_organizationId_key" ON "Shop"("name", "organizationId"); + +-- AddForeignKey +ALTER TABLE "Shop" ADD CONSTRAINT "Shop_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EventType" ADD CONSTRAINT "EventType_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/migrations/migration_lock.toml b/src/backend/src/prisma/migrations/migration_lock.toml index 044d57cdb0..648c57fd59 100644 --- a/src/backend/src/prisma/migrations/migration_lock.toml +++ b/src/backend/src/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ # Please do not edit this file manually # It should be added in your version-control system (e.g., Git) -provider = "postgresql" +provider = "postgresql" \ No newline at end of file diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index df5d6e6d14..3deb733362 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -881,30 +881,38 @@ model Manufacturer { } model Shop { - shopId String @id @default(uuid()) - name String @unique - dateCreated DateTime @default(now()) - dateDeleted DateTime? - userCreatedId String - userCreated User @relation(name: "shopCreator", fields: [userCreatedId], references: [userId]) - userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") - machinery ShopMachinery[] - description String - events Event[] + shopId String @id @default(uuid()) + name String @unique + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "shopCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") + machinery ShopMachinery[] + description String + events Event[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + + @@unique([name, organizationId], name: "uniqueShop") } model Machinery { - machineryId String @id @default(uuid()) - name String - dateCreated DateTime @default(now()) - dateDeleted DateTime? - userCreatedId String - userCreated User @relation(name: "machineryCreator", fields: [userCreatedId], references: [userId]) - userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "machineryDeleter") - shops ShopMachinery[] - events Event[] + machineryId String @id @default(uuid()) + name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "machineryCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "machineryDeleter") + shops ShopMachinery[] + events Event[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + + @@unique([name, organizationId], name: "uniqueMachinery") } model ShopMachinery { @@ -968,28 +976,32 @@ model Event { } model Calendar { - calendarId String @id @default(uuid()) - name String - dateCreated DateTime @default(now()) - dateDeleted DateTime? - userCreatedId String - userCreated User @relation(name: "calendarCreator", fields: [userCreatedId], references: [userId]) - userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "calendarDeleter") - description String - colorHexCode String - eventTypes EventType[] + calendarId String @id @default(uuid()) + name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "calendarCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "calendarDeleter") + description String + colorHexCode String + eventTypes EventType[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + + @@unique([name, organizationId], name: "uniqueCalendar") } model EventType { - eventTypeId String @id @default(uuid()) + eventTypeId String @id @default(uuid()) name String - dateCreated DateTime @default(now()) + dateCreated DateTime @default(now()) dateDeleted DateTime? userCreatedId String - userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) + userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") calendars Calendar[] initialDateScheduled Boolean allDay Boolean @@ -1005,6 +1017,10 @@ model EventType { documents Boolean description Boolean events Event[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + + @@unique([name, organizationId], name: "uniqueEventType") } model Team_Type { @@ -1246,6 +1262,10 @@ model Organization { sponsors Sponsor[] sponsorTiers Sponsor_Tier[] indexCodes Index_Code[] + shops Shop[] + machineries Machinery[] + calendars Calendar[] + eventTypes EventType[] } model FrequentlyAskedQuestion { diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index befe4ba7ef..66db742de1 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3068,7 +3068,8 @@ const performSeed: () => Promise = async () => { description: 'Tracks all engineering team events, meetings, and deadlines.', colorHexCode: '#3498db', userCreated: { connect: { userId: thomasEmrax.userId } }, - dateCreated: new Date() + dateCreated: new Date(), + organization: { connect: { organizationId } } } }); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 5dd6979831..a40292c200 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -76,7 +76,8 @@ export default class CalendarService { workPackage, questionDocument, documents, - description + description, + organizationId: organization.organizationId }, ...getEventTypeQueryArgs(organization.organizationId) }); @@ -96,7 +97,8 @@ export default class CalendarService { data: { name, description, - userCreatedId: submitter.userId + userCreatedId: submitter.userId, + organizationId: organization.organizationId }, ...getShopQueryArgs(organization.organizationId) }); diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index f634e8523e..fe431601d8 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -168,10 +168,10 @@ export const resetUsers = async () => { await prisma.index_Code.deleteMany(); await prisma.eventType.deleteMany(); await prisma.calendar.deleteMany(); - await prisma.organization.deleteMany(); await prisma.shopMachinery.deleteMany(); await prisma.machinery.deleteMany(); await prisma.shop.deleteMany(); + await prisma.organization.deleteMany(); await prisma.user.deleteMany(); }; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 784451d9a9..918012026b 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -19,7 +19,8 @@ describe('Calendar Tests', () => { description: 'Tracks all engineering team events, meetings, and deadlines.', colorHexCode: '#3498db', userCreated: { connect: { userId: (await createTestUser(supermanAdmin, orgId)).userId } }, - dateCreated: new Date() + dateCreated: new Date(), + organization: { connect: { organizationId: organization.organizationId } } } }); }); From 983e3afd8e33542d72ca79bfd0d92d6af9adf333 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 21 Sep 2025 18:43:12 -0400 Subject: [PATCH 067/477] #3610 changed id to scheduleSlotId --- .../prisma/migrations/20250904214316_calendar/migration.sql | 6 +++--- src/backend/src/prisma/schema.prisma | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index e2ddd4581d..f7c6c10622 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -44,7 +44,7 @@ CREATE TABLE "public"."ShopMachinery" ( -- CreateTable CREATE TABLE "public"."ScheduleSlot" ( - "id" TEXT NOT NULL, + "scheduleSlotId" TEXT NOT NULL, "days" "public"."DayOfWeek"[], "startTime" TIMESTAMP(3), "endTime" TIMESTAMP(3), @@ -52,7 +52,7 @@ CREATE TABLE "public"."ScheduleSlot" ( "initialDateScheduled" DATE NOT NULL, "allDay" BOOLEAN NOT NULL DEFAULT false, - CONSTRAINT "ScheduleSlot_pkey" PRIMARY KEY ("id") + CONSTRAINT "ScheduleSlot_pkey" PRIMARY KEY ("scheduleSlotId") ); -- CreateTable @@ -263,7 +263,7 @@ ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" F ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."ScheduleSlot"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."ScheduleSlot"("scheduleSlotId") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 3deb733362..70dab18a20 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -939,7 +939,7 @@ enum DayOfWeek { } model ScheduleSlot { - id String @id @default(uuid()) + scheduleSlotId String @id @default(uuid()) days DayOfWeek[] startTime DateTime? // time of day (just use a DateTime, ignore the date portion) endTime DateTime? // time of day (just use a DateTime, ignore the date portion) From 0e020ea8cda514a594a7593e988aa3b3cd5dcc1d Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 21 Sep 2025 18:35:57 -0400 Subject: [PATCH 068/477] #3610 added organization to shop, machinery, calendar and event type tables --- .../20250904214316_calendar/migration.sql | 28 ++++++ .../src/prisma/migrations/migration_lock.toml | 2 +- src/backend/src/prisma/schema.prisma | 92 +++++++++++-------- src/backend/src/prisma/seed.ts | 3 +- src/backend/src/services/calendar.services.ts | 6 +- src/backend/tests/test-utils.ts | 2 +- src/backend/tests/unit/calendar.test.ts | 3 +- 7 files changed, 94 insertions(+), 42 deletions(-) diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index 129354bef9..e2ddd4581d 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -13,6 +13,7 @@ CREATE TABLE "public"."Shop" ( "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, "description" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId") ); @@ -25,6 +26,7 @@ CREATE TABLE "public"."Machinery" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, + "organizationId" TEXT NOT NULL, CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId") ); @@ -82,6 +84,7 @@ CREATE TABLE "public"."Calendar" ( "userDeletedId" TEXT, "description" TEXT NOT NULL, "colorHexCode" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId") ); @@ -107,6 +110,7 @@ CREATE TABLE "public"."EventType" ( "questionDocument" BOOLEAN NOT NULL DEFAULT FALSE, "documents" BOOLEAN NOT NULL DEFAULT FALSE, "description" BOOLEAN NOT NULL DEFAULT FALSE, + "organizationId" TEXT NOT NULL, CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") ); @@ -186,6 +190,30 @@ CREATE INDEX "_EventToWork_Package_B_index" ON "public"."_EventToWork_Package"(" -- CreateIndex CREATE INDEX "_CalendarToEventType_B_index" ON "public"."_CalendarToEventType"("B"); +-- CreateIndex +CREATE UNIQUE INDEX "Calendar_name_organizationId_key" ON "Calendar"("name", "organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "EventType_name_organizationId_key" ON "EventType"("name", "organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Machinery_name_organizationId_key" ON "Machinery"("name", "organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Shop_name_organizationId_key" ON "Shop"("name", "organizationId"); + +-- AddForeignKey +ALTER TABLE "Shop" ADD CONSTRAINT "Shop_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "EventType" ADD CONSTRAINT "EventType_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/migrations/migration_lock.toml b/src/backend/src/prisma/migrations/migration_lock.toml index 044d57cdb0..648c57fd59 100644 --- a/src/backend/src/prisma/migrations/migration_lock.toml +++ b/src/backend/src/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ # Please do not edit this file manually # It should be added in your version-control system (e.g., Git) -provider = "postgresql" +provider = "postgresql" \ No newline at end of file diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index df5d6e6d14..3deb733362 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -881,30 +881,38 @@ model Manufacturer { } model Shop { - shopId String @id @default(uuid()) - name String @unique - dateCreated DateTime @default(now()) - dateDeleted DateTime? - userCreatedId String - userCreated User @relation(name: "shopCreator", fields: [userCreatedId], references: [userId]) - userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") - machinery ShopMachinery[] - description String - events Event[] + shopId String @id @default(uuid()) + name String @unique + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "shopCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "shopDeleter") + machinery ShopMachinery[] + description String + events Event[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + + @@unique([name, organizationId], name: "uniqueShop") } model Machinery { - machineryId String @id @default(uuid()) - name String - dateCreated DateTime @default(now()) - dateDeleted DateTime? - userCreatedId String - userCreated User @relation(name: "machineryCreator", fields: [userCreatedId], references: [userId]) - userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "machineryDeleter") - shops ShopMachinery[] - events Event[] + machineryId String @id @default(uuid()) + name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "machineryCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "machineryDeleter") + shops ShopMachinery[] + events Event[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + + @@unique([name, organizationId], name: "uniqueMachinery") } model ShopMachinery { @@ -968,28 +976,32 @@ model Event { } model Calendar { - calendarId String @id @default(uuid()) - name String - dateCreated DateTime @default(now()) - dateDeleted DateTime? - userCreatedId String - userCreated User @relation(name: "calendarCreator", fields: [userCreatedId], references: [userId]) - userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "calendarDeleter") - description String - colorHexCode String - eventTypes EventType[] + calendarId String @id @default(uuid()) + name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "calendarCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "calendarDeleter") + description String + colorHexCode String + eventTypes EventType[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + + @@unique([name, organizationId], name: "uniqueCalendar") } model EventType { - eventTypeId String @id @default(uuid()) + eventTypeId String @id @default(uuid()) name String - dateCreated DateTime @default(now()) + dateCreated DateTime @default(now()) dateDeleted DateTime? userCreatedId String - userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) + userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") calendars Calendar[] initialDateScheduled Boolean allDay Boolean @@ -1005,6 +1017,10 @@ model EventType { documents Boolean description Boolean events Event[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + + @@unique([name, organizationId], name: "uniqueEventType") } model Team_Type { @@ -1246,6 +1262,10 @@ model Organization { sponsors Sponsor[] sponsorTiers Sponsor_Tier[] indexCodes Index_Code[] + shops Shop[] + machineries Machinery[] + calendars Calendar[] + eventTypes EventType[] } model FrequentlyAskedQuestion { diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 10de86c4e7..03b55de61b 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3143,7 +3143,8 @@ const performSeed: () => Promise = async () => { description: 'Tracks all engineering team events, meetings, and deadlines.', colorHexCode: '#3498db', userCreated: { connect: { userId: thomasEmrax.userId } }, - dateCreated: new Date() + dateCreated: new Date(), + organization: { connect: { organizationId } } } }); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 452ba35650..87a322e454 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -78,7 +78,8 @@ export default class CalendarService { workPackage, questionDocument, documents, - description + description, + organizationId: organization.organizationId }, ...getEventTypeQueryArgs(organization.organizationId) }); @@ -167,7 +168,8 @@ export default class CalendarService { data: { name, description, - userCreatedId: submitter.userId + userCreatedId: submitter.userId, + organizationId: organization.organizationId }, ...getShopQueryArgs(organization.organizationId) }); diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index bdc45e2ae5..d6ab68cde7 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -171,10 +171,10 @@ export const resetUsers = async () => { await prisma.shop.deleteMany(); await prisma.eventType.deleteMany(); await prisma.calendar.deleteMany(); - await prisma.organization.deleteMany(); await prisma.shopMachinery.deleteMany(); await prisma.machinery.deleteMany(); await prisma.shop.deleteMany(); + await prisma.organization.deleteMany(); await prisma.user.deleteMany(); }; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index b74e7a7782..a73d8af811 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -28,7 +28,8 @@ describe('Calendar Tests', () => { description: 'Tracks all engineering team events, meetings, and deadlines.', colorHexCode: '#3498db', userCreated: { connect: { userId: (await createTestUser(supermanAdmin, orgId)).userId } }, - dateCreated: new Date() + dateCreated: new Date(), + organization: { connect: { organizationId: organization.organizationId } } } }); From d6d05d91cf091f36e22c16ae8f14cd1f3c064f1c Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 21 Sep 2025 18:43:12 -0400 Subject: [PATCH 069/477] #3610 changed id to scheduleSlotId --- .../prisma/migrations/20250904214316_calendar/migration.sql | 6 +++--- src/backend/src/prisma/schema.prisma | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index e2ddd4581d..f7c6c10622 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -44,7 +44,7 @@ CREATE TABLE "public"."ShopMachinery" ( -- CreateTable CREATE TABLE "public"."ScheduleSlot" ( - "id" TEXT NOT NULL, + "scheduleSlotId" TEXT NOT NULL, "days" "public"."DayOfWeek"[], "startTime" TIMESTAMP(3), "endTime" TIMESTAMP(3), @@ -52,7 +52,7 @@ CREATE TABLE "public"."ScheduleSlot" ( "initialDateScheduled" DATE NOT NULL, "allDay" BOOLEAN NOT NULL DEFAULT false, - CONSTRAINT "ScheduleSlot_pkey" PRIMARY KEY ("id") + CONSTRAINT "ScheduleSlot_pkey" PRIMARY KEY ("scheduleSlotId") ); -- CreateTable @@ -263,7 +263,7 @@ ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" F ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."ScheduleSlot"("id") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."ScheduleSlot"("scheduleSlotId") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 3deb733362..70dab18a20 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -939,7 +939,7 @@ enum DayOfWeek { } model ScheduleSlot { - id String @id @default(uuid()) + scheduleSlotId String @id @default(uuid()) days DayOfWeek[] startTime DateTime? // time of day (just use a DateTime, ignore the date portion) endTime DateTime? // time of day (just use a DateTime, ignore the date portion) From 73f890780212577f89ccb4f6a448e9e509c93118 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 22 Sep 2025 08:47:06 -0400 Subject: [PATCH 070/477] #3565 Adjusted services for creating machinery with new organization field checks --- src/backend/src/prisma/seed.ts | 9 ++++++--- src/backend/src/services/calendar.services.ts | 16 ++++------------ src/backend/tests/unit/calendar.test.ts | 3 ++- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 03b55de61b..988b80155e 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3067,7 +3067,8 @@ const performSeed: () => Promise = async () => { data: { name: 'Advanced CNC Manufacturing Center', description: 'CNC machining and precision manufacturing facility', - userCreatedId: thomasEmrax.userId + userCreatedId: thomasEmrax.userId, + organizationId } }); @@ -3075,7 +3076,8 @@ const performSeed: () => Promise = async () => { data: { name: 'Electronics Development Lab', description: 'Electronics testing and development workspace', - userCreatedId: thomasEmrax.userId + userCreatedId: thomasEmrax.userId, + organizationId } }); @@ -3083,7 +3085,8 @@ const performSeed: () => Promise = async () => { data: { name: 'Testing & Validation Facility', description: 'Component and system testing laboratory', - userCreatedId: thomasEmrax.userId + userCreatedId: thomasEmrax.userId, + organizationId } }); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 87a322e454..fecf20e7d6 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -116,30 +116,22 @@ export default class CalendarService { // Check if shop with id exists and belongs to the same organization const existingShop = await prisma.shop.findUnique({ - where: { shopId }, - include: { - userCreated: { - include: { - organizations: { - where: { organizationId: organization.organizationId } - } - } - } - } + where: { shopId } }); if (!existingShop) { throw new NotFoundException('Shop', shopId); } - if (existingShop.userCreated.organizations.length === 0) { - throw new AccessDeniedAdminOnlyException('create machinery for shop in different organization'); + if (existingShop.organizationId !== organization.organizationId) { + throw new AccessDeniedAdminOnlyException('shop does not belong to the specified organization'); } const newMachinery = await prisma.machinery.create({ data: { name, userCreatedId: submitter.userId, + organizationId: organization.organizationId, shops: { create: [ { diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index a73d8af811..aec322aaa0 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -37,7 +37,8 @@ describe('Calendar Tests', () => { data: { name: 'Precision Manufacturing Lab', description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', - userCreatedId: (await createTestUser(flashAdmin, orgId)).userId + userCreatedId: (await createTestUser(flashAdmin, orgId)).userId, + organizationId: orgId } }); ({ shopId } = shop); From 1c3c37a71297831b0c66e3a6efd3b74efec32efb Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 22 Sep 2025 09:03:25 -0400 Subject: [PATCH 071/477] #3565 correct exception --- src/backend/src/services/calendar.services.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index fecf20e7d6..0f04be9c48 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -3,7 +3,7 @@ import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args import { Organization, User } from '@prisma/client'; import { isAdmin, EventType, Shop } from 'shared'; import prisma from '../prisma/prisma'; -import { AccessDeniedAdminOnlyException, NotFoundException } from '../utils/errors.utils'; +import { AccessDeniedAdminOnlyException, InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; @@ -124,7 +124,7 @@ export default class CalendarService { } if (existingShop.organizationId !== organization.organizationId) { - throw new AccessDeniedAdminOnlyException('shop does not belong to the specified organization'); + throw new InvalidOrganizationException('Shop'); } const newMachinery = await prisma.machinery.create({ From a68a5e36440f8a1589b7ae799e27bff37a2b7df5 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Mon, 22 Sep 2025 13:42:00 -0400 Subject: [PATCH 072/477] added organization checking to event type endpoint --- src/backend/src/services/calendar.services.ts | 21 +++++++++++++++++++ src/backend/src/utils/errors.utils.ts | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 0f04be9c48..8268b33dcf 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -59,6 +59,27 @@ export default class CalendarService { throw new AccessDeniedAdminOnlyException('create event type'); } + // Check if calendars with ids exist and belong to the same organization + const existingCalendars = await prisma.calendar.findMany({ + where: { + calendarId: { in: calendarIds } + } + }); + + // Ensure all provided calendars exist + if (existingCalendars.length !== calendarIds.length) { + const foundIds = existingCalendars.map((c) => c.calendarId); + const missingIds = calendarIds.filter((id) => !foundIds.includes(id)); + throw new NotFoundException('Calendar', missingIds.join(', ')); + } + + // Ensure all calendars belong to the given organization + for (const calendar of existingCalendars) { + if (calendar.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Calendar'); + } + } + const newEventType = await prisma.eventType.create({ data: { name, diff --git a/src/backend/src/utils/errors.utils.ts b/src/backend/src/utils/errors.utils.ts index aacca11e89..1149980dfd 100644 --- a/src/backend/src/utils/errors.utils.ts +++ b/src/backend/src/utils/errors.utils.ts @@ -162,4 +162,5 @@ export type ExceptionObjectNames = | 'Index Code' | 'Reimbursement Product Other Reason' | 'Encryption Key' - | 'Reimbursement Request Comment'; + | 'Reimbursement Request Comment' + | 'Calendar'; From 39979a1efd7cb70a9fa06cf02ac0dd0bea89614f Mon Sep 17 00:00:00 2001 From: wavehassman Date: Mon, 22 Sep 2025 13:50:59 -0400 Subject: [PATCH 073/477] add documentation for event type endpoint --- src/backend/src/services/calendar.services.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 8268b33dcf..a56a466d53 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -35,6 +35,8 @@ export default class CalendarService { * @returns The created event type. * * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + * @throws NotFoundException If the given calendarIds are not found. + * @throws InvalidOrganizationException If the given calendarIds are not part of the same organization. */ static async createEventType( submitter: User, From 202e832a4a69aca8f2e3fff15e4e982f149dfdba Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 24 Sep 2025 11:58:09 -0400 Subject: [PATCH 074/477] Creating deleteShop Endpoint --- .../src/controllers/calendar.controllers.ts | 12 ++++ src/backend/src/prisma/seed.ts | 11 ++++ src/backend/src/routes/calendar.routes.ts | 4 +- src/backend/src/services/calendar.services.ts | 55 ++++++++++++++++++- src/backend/tests/unit/calendar.test.ts | 53 +++++++++++++++++- 5 files changed, 132 insertions(+), 3 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 94220744f7..abb1e55d6f 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -75,4 +75,16 @@ export default class CalendarController { next(error); } } + + static async deleteShop(req: Request, res: Response, next: NextFunction) { + try { + const { shopId } = req.params; + + const shop = await CalendarService.deleteShop(req.currentUser, shopId, req.organization); + + res.status(200).json(shop); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 988b80155e..139e81a057 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3234,6 +3234,17 @@ const performSeed: () => Promise = async () => { false, true ); + + // to delete shop for testing delete shop functionality + const deletableShop = await prisma.shop.create({ + data: { + name: 'Temp Deletable Shop', + description: 'For deleteShop manual testing', + userCreatedId: thomasEmrax.userId, + organizationId + } + }); + console.log('Deletable shopId:', deletableShop.shopId); }; performSeed() diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 03ad7c2fe4..89e5aa1ec3 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { body } from 'express-validator'; +import { body, param } from 'express-validator'; import { nonEmptyString, validateInputs } from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; @@ -45,4 +45,6 @@ calendarRouter.post( CalendarController.createShop ); +calendarRouter.delete('/shop/:shopId', nonEmptyString(param('shopId')), validateInputs, CalendarController.deleteShop); + export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index a56a466d53..cc884a90cb 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -3,7 +3,12 @@ import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args import { Organization, User } from '@prisma/client'; import { isAdmin, EventType, Shop } from 'shared'; import prisma from '../prisma/prisma'; -import { AccessDeniedAdminOnlyException, InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; +import { + AccessDeniedAdminOnlyException, + InvalidOrganizationException, + NotFoundException, + AccessDeniedException +} from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; @@ -191,4 +196,52 @@ export default class CalendarService { return shopTransformer(newShop); } + + /** + * Deletes a shop by its ID. + * Requires the submitter to be head or above. + * @param submitter The user submitting the request. + * @param shopId The ID of the shop to be deleted. + * @param organization The organization to which the shop belongs. + * @returns The deleted shop object. + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + * @throws NotFoundException If the shop with the given ID does not exist. + * @throws InvalidOrganizationException If the shop does not belong to the given organization. + * + */ + + static async deleteShop(submitter: User, shopId: string, organization: Organization): Promise { + if ( + !(await userHasPermission( + submitter.userId, + organization.organizationId, + (role) => !!role && ['HEAD', 'LEADERSHIP', 'ADMIN', 'APP_ADMIN'].includes(String(role)) + )) + ) { + throw new AccessDeniedException('head or above only have the ability to delete shop'); + } + + // Ensure the shop exists + const existing = await prisma.shop.findUnique({ where: { shopId } }); + if (!existing) throw new NotFoundException('Shop', shopId); + + // Ensure it belongs to this org + if (existing.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Shop'); + } + + // not already soft-deleted + if (existing.dateDeleted) { + throw new NotFoundException('Shop', shopId); + } + + // Soft delete and return transformed DTO + const deleted = await prisma.shop.update({ + where: { shopId }, + data: { dateDeleted: new Date() }, + include: getShopQueryArgs(organization.organizationId).include + }); + + return shopTransformer(deleted); + } } diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index aec322aaa0..4838edaf2a 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,11 +1,17 @@ import { Calendar, Organization } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; -import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; +import { + AccessDeniedAdminOnlyException, + NotFoundException, + InvalidOrganizationException, + AccessDeniedException +} from '../../src/utils/errors.utils'; import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, flashAdmin, + greenlanternHead, theVisitorGuest, alfred } from '../test-data/users.test-data'; @@ -169,5 +175,50 @@ describe('Calendar Tests', () => { await expect(CalendarService.createShop(admin, 'UniqueName', 'second attempt', organization)).rejects.toBeTruthy(); }); }); + + describe('Delete shop', () => { + it('fails if user is not head or above', async () => { + await expect( + CalendarService.deleteShop(await createTestUser(wonderwomanGuest, orgId), shopId, organization) + ).rejects.toBeInstanceOf(AccessDeniedException); + }); + + it('succeeds for head', async () => { + const head = await createTestUser(greenlanternHead, orgId); + + const result = await CalendarService.deleteShop(head, shopId, organization); + expect(result.shopId).toBe(shopId); + + // verify soft delete happened + const row = await prisma.shop.findUnique({ where: { shopId } }); + expect(row?.dateDeleted).not.toBeNull(); + }); + + it('fails if shop does not exist', async () => { + const head = await createTestUser(greenlanternHead, orgId); + await expect(CalendarService.deleteShop(head, 'non-existent-id', organization)).rejects.toBeInstanceOf( + NotFoundException + ); + }); + + // optional but useful: + it('fails if shop is already deleted', async () => { + const head = await createTestUser(greenlanternHead, orgId); + await CalendarService.deleteShop(head, shopId, organization); + + await expect(CalendarService.deleteShop(head, shopId, organization)).rejects.toBeInstanceOf(NotFoundException); + }); + + it('fails if shop belongs to a different organization', async () => { + const otherOrg = await createTestOrganization(); + const otherAdmin = await createTestUser(batmanAppAdmin, otherOrg.organizationId); + const otherShop = await CalendarService.createShop(otherAdmin, 'OtherShop', 'desc', otherOrg); + + const head = await createTestUser(greenlanternHead, orgId); + await expect(CalendarService.deleteShop(head, otherShop.shopId, organization)).rejects.toBeInstanceOf( + InvalidOrganizationException + ); + }); + }); }); }); From c700e239d21141146a1edeb4eb027507ba3085d9 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 24 Sep 2025 15:20:56 -0400 Subject: [PATCH 075/477] Fixing test --- src/backend/tests/unit/calendar.test.ts | 26 +++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 4838edaf2a..f03a3afe92 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -201,7 +201,6 @@ describe('Calendar Tests', () => { ); }); - // optional but useful: it('fails if shop is already deleted', async () => { const head = await createTestUser(greenlanternHead, orgId); await CalendarService.deleteShop(head, shopId, organization); @@ -210,13 +209,24 @@ describe('Calendar Tests', () => { }); it('fails if shop belongs to a different organization', async () => { - const otherOrg = await createTestOrganization(); - const otherAdmin = await createTestUser(batmanAppAdmin, otherOrg.organizationId); - const otherShop = await CalendarService.createShop(otherAdmin, 'OtherShop', 'desc', otherOrg); - - const head = await createTestUser(greenlanternHead, orgId); - await expect(CalendarService.deleteShop(head, otherShop.shopId, organization)).rejects.toBeInstanceOf( - InvalidOrganizationException + const existing = await prisma.user.findFirstOrThrow({ + where: { googleAuthId: supermanAdmin.googleAuthId }, + select: { userId: true } + }); + + const otherOrg = await prisma.organization.create({ + data: { + name: 'Other Org (calendar test)', + description: 'for cross-org negative case', + applicationLink: '', + userCreated: { connect: { userId: existing.userId } } + } + }); + + const headInOtherOrg = await createTestUser(greenlanternHead, otherOrg.organizationId); + + await expect(CalendarService.deleteShop(headInOtherOrg, shopId, otherOrg)).rejects.toThrow( + new InvalidOrganizationException('Shop') ); }); }); From 208e3a522cf3270550adf4067d541aedd528c021 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 24 Sep 2025 16:18:10 -0400 Subject: [PATCH 076/477] Fixing some comments --- src/backend/src/prisma/seed.ts | 10 ---------- src/backend/src/routes/calendar.routes.ts | 7 ++++++- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 139e81a057..2432e8a580 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3235,16 +3235,6 @@ const performSeed: () => Promise = async () => { true ); - // to delete shop for testing delete shop functionality - const deletableShop = await prisma.shop.create({ - data: { - name: 'Temp Deletable Shop', - description: 'For deleteShop manual testing', - userCreatedId: thomasEmrax.userId, - organizationId - } - }); - console.log('Deletable shopId:', deletableShop.shopId); }; performSeed() diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 89e5aa1ec3..748f2a38dd 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -45,6 +45,11 @@ calendarRouter.post( CalendarController.createShop ); -calendarRouter.delete('/shop/:shopId', nonEmptyString(param('shopId')), validateInputs, CalendarController.deleteShop); +calendarRouter.post( + '/shop/:shopId/delete', + nonEmptyString(param('shopId')), + validateInputs, + CalendarController.deleteShop +); export default calendarRouter; From 9aded42b585a5ff7e023c8f6bfa167b551851f94 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 24 Sep 2025 16:25:00 -0400 Subject: [PATCH 077/477] fixing prettier --- src/backend/src/prisma/seed.ts | 1 - src/backend/src/routes/calendar.routes.ts | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 2432e8a580..988b80155e 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3234,7 +3234,6 @@ const performSeed: () => Promise = async () => { false, true ); - }; performSeed() diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 748f2a38dd..b9d626184b 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -45,11 +45,6 @@ calendarRouter.post( CalendarController.createShop ); -calendarRouter.post( - '/shop/:shopId/delete', - nonEmptyString(param('shopId')), - validateInputs, - CalendarController.deleteShop -); +calendarRouter.post('/shop/:shopId/delete', nonEmptyString(param('shopId')), validateInputs, CalendarController.deleteShop); export default calendarRouter; From 22cdb06f34c0b105b526b4b644a7fabc192f7023 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Thu, 25 Sep 2025 14:05:45 -0400 Subject: [PATCH 078/477] adding isAdmin --- src/backend/src/services/calendar.services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index cc884a90cb..1fca6139e6 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -215,7 +215,7 @@ export default class CalendarService { !(await userHasPermission( submitter.userId, organization.organizationId, - (role) => !!role && ['HEAD', 'LEADERSHIP', 'ADMIN', 'APP_ADMIN'].includes(String(role)) + isAdmin )) ) { throw new AccessDeniedException('head or above only have the ability to delete shop'); From 8661dd2a0dc3f72205e9d313e6c2a4a6b55457ea Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Thu, 25 Sep 2025 14:08:41 -0400 Subject: [PATCH 079/477] prettier --- src/backend/src/services/calendar.services.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 1fca6139e6..aaada087e4 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -211,13 +211,7 @@ export default class CalendarService { */ static async deleteShop(submitter: User, shopId: string, organization: Organization): Promise { - if ( - !(await userHasPermission( - submitter.userId, - organization.organizationId, - isAdmin - )) - ) { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedException('head or above only have the ability to delete shop'); } From 08733980c1fe59795235c4570b8061ae8cdb76f0 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Thu, 25 Sep 2025 14:14:05 -0400 Subject: [PATCH 080/477] updating tests --- src/backend/src/services/calendar.services.ts | 9 ++----- src/backend/tests/unit/calendar.test.ts | 26 +++++++++---------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index aaada087e4..3a092d6a7f 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -3,12 +3,7 @@ import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args import { Organization, User } from '@prisma/client'; import { isAdmin, EventType, Shop } from 'shared'; import prisma from '../prisma/prisma'; -import { - AccessDeniedAdminOnlyException, - InvalidOrganizationException, - NotFoundException, - AccessDeniedException -} from '../utils/errors.utils'; +import { AccessDeniedAdminOnlyException, InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; @@ -212,7 +207,7 @@ export default class CalendarService { static async deleteShop(submitter: User, shopId: string, organization: Organization): Promise { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { - throw new AccessDeniedException('head or above only have the ability to delete shop'); + throw new AccessDeniedAdminOnlyException('delete shop'); } // Ensure the shop exists diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index f03a3afe92..f473cc600a 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -3,15 +3,13 @@ import CalendarService from '../../src/services/calendar.services'; import { AccessDeniedAdminOnlyException, NotFoundException, - InvalidOrganizationException, - AccessDeniedException + InvalidOrganizationException } from '../../src/utils/errors.utils'; import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, flashAdmin, - greenlanternHead, theVisitorGuest, alfred } from '../test-data/users.test-data'; @@ -180,13 +178,13 @@ describe('Calendar Tests', () => { it('fails if user is not head or above', async () => { await expect( CalendarService.deleteShop(await createTestUser(wonderwomanGuest, orgId), shopId, organization) - ).rejects.toBeInstanceOf(AccessDeniedException); + ).rejects.toBeInstanceOf(AccessDeniedAdminOnlyException); }); - it('succeeds for head', async () => { - const head = await createTestUser(greenlanternHead, orgId); + it('succeeds for admin', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); - const result = await CalendarService.deleteShop(head, shopId, organization); + const result = await CalendarService.deleteShop(admin, shopId, organization); expect(result.shopId).toBe(shopId); // verify soft delete happened @@ -195,17 +193,17 @@ describe('Calendar Tests', () => { }); it('fails if shop does not exist', async () => { - const head = await createTestUser(greenlanternHead, orgId); - await expect(CalendarService.deleteShop(head, 'non-existent-id', organization)).rejects.toBeInstanceOf( + const admin = await createTestUser(batmanAppAdmin, orgId); + await expect(CalendarService.deleteShop(admin, 'non-existent-id', organization)).rejects.toBeInstanceOf( NotFoundException ); }); it('fails if shop is already deleted', async () => { - const head = await createTestUser(greenlanternHead, orgId); - await CalendarService.deleteShop(head, shopId, organization); + const admin = await createTestUser(batmanAppAdmin, orgId); + await CalendarService.deleteShop(admin, shopId, organization); - await expect(CalendarService.deleteShop(head, shopId, organization)).rejects.toBeInstanceOf(NotFoundException); + await expect(CalendarService.deleteShop(admin, shopId, organization)).rejects.toBeInstanceOf(NotFoundException); }); it('fails if shop belongs to a different organization', async () => { @@ -223,9 +221,9 @@ describe('Calendar Tests', () => { } }); - const headInOtherOrg = await createTestUser(greenlanternHead, otherOrg.organizationId); + const AdminInOtherOrg = await createTestUser(batmanAppAdmin, otherOrg.organizationId); - await expect(CalendarService.deleteShop(headInOtherOrg, shopId, otherOrg)).rejects.toThrow( + await expect(CalendarService.deleteShop(AdminInOtherOrg, shopId, otherOrg)).rejects.toThrow( new InvalidOrganizationException('Shop') ); }); From e25523de6962b57729f0c05517c421e919861d72 Mon Sep 17 00:00:00 2001 From: Lisa W Date: Sun, 28 Sep 2025 01:53:35 -0400 Subject: [PATCH 081/477] Added deleteCalendar route, controller, and service method --- .../src/controllers/calendar.controllers.ts | 12 +++++ src/backend/src/routes/calendar.routes.ts | 5 ++ src/backend/src/services/calendar.services.ts | 53 +++++++++++++++++-- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 94220744f7..f72cb8f862 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -75,4 +75,16 @@ export default class CalendarController { next(error); } } + + static async deleteCalendar(req: Request, res: Response, next: NextFunction) { + try { + const { calendarId } = req.params; + + const updatedCalendar = await CalendarService.deleteCalendar(req.currentUser, calendarId, req.organization); + + res.status(200).json(updatedCalendar); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 03ad7c2fe4..61d052cda5 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -45,4 +45,9 @@ calendarRouter.post( CalendarController.createShop ); +calendarRouter.post( + '/:calendarId/delete', + CalendarController.deleteCalendar +); + export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index a56a466d53..2b4fe4fce9 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,14 +1,21 @@ import { machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { Organization, User } from '@prisma/client'; -import { isAdmin, EventType, Shop } from 'shared'; +import { isAdmin, isHead, EventType, Shop } from 'shared'; import prisma from '../prisma/prisma'; -import { AccessDeniedAdminOnlyException, InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; -import { userHasPermission } from '../utils/users.utils'; +import { + AccessDeniedAdminOnlyException, + AccessDeniedException, + DeletedException, + InvalidOrganizationException, + NotFoundException +} from '../utils/errors.utils'; +import { userHasPermission, getUserRole } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { shopTransformer } from '../transformers/calendar.transformer'; import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; +import { getTaskQueryArgs } from '../prisma-query-args/tasks.query-args'; export default class CalendarService { /** @@ -191,4 +198,44 @@ export default class CalendarService { return shopTransformer(newShop); } + + /** + * Delete calendar in the database + * @param submitter The user submitting the request, who must be a head or above. + * @param calendarId The id of the given calendar. + * @param organization The organization for which the calendar is being deleted. + * + * @returns The deleted calendar ID. + * + * @throws NotFoundException If the given calendarIds are not found. + * @throws InvalidOrganizationException If the given calendarIds are not part of the same organization. + * @throws DeletedException If the calendar has already been deleted. + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + */ + static async deleteCalendar(submitter: User, calendarId: string, organization: Organization): Promise { + const calendar = await prisma.calendar.findUnique({ + where: { calendarId } + }); + + if (!calendar) throw new NotFoundException('Calendar', calendarId); + if (calendar.dateDeleted) throw new DeletedException('Calendar', calendarId); + if (calendar.organizationId !== organization.organizationId) throw new InvalidOrganizationException('Calendar'); + + const hasPermission = await userHasPermission( + submitter.userId, + organization.organizationId, + (role) => isAdmin(role) || isHead(role) + ); + + if (!hasPermission) { + throw new AccessDeniedException('Only heads and above can delete calendars'); + } + + const deletedCalendar = await prisma.calendar.update({ + where: { calendarId }, + data: { dateDeleted: new Date(), userDeletedId: submitter.userId } + }); + + return deletedCalendar.calendarId; + } } From 9cfb8a6857eeeb2262b62649718186c7b8a46fd0 Mon Sep 17 00:00:00 2001 From: Lisa W Date: Sun, 28 Sep 2025 02:52:12 -0400 Subject: [PATCH 082/477] Added deleteCalendar tests --- src/backend/tests/unit/calendar.test.ts | 98 ++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index aec322aaa0..ed935e6043 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,13 +1,19 @@ import { Calendar, Organization } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; -import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; +import { + AccessDeniedAdminOnlyException, + AccessDeniedException, + DeletedException, + NotFoundException +} from '../../src/utils/errors.utils'; import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, flashAdmin, theVisitorGuest, - alfred + alfred, + greenlanternHead } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; @@ -48,6 +54,94 @@ describe('Calendar Tests', () => { await resetUsers(); }); + describe('delete calendar', () => { + it('fails if user is not a head or admin', async () => { + const member = await createTestUser(wonderwomanGuest, orgId); + + const calendar = await prisma.calendar.create({ + data: { + name: 'Test Calendar', + description: 'Test', + colorHexCode: '#000000', + userCreatedId: member.userId, + organizationId: orgId + } + }); + + await expect(CalendarService.deleteCalendar(member, calendar.calendarId, organization)).rejects.toThrow( + new AccessDeniedException('Only heads and above can delete calendars') + ); + }); + + it('succeeds for head', async () => { + const head = await createTestUser(greenlanternHead, orgId); + + const calendar = await prisma.calendar.create({ + data: { + name: 'Calendar to Delete', + description: 'Test', + colorHexCode: '#FF0000', + userCreatedId: head.userId, + organizationId: orgId + } + }); + + const result = await CalendarService.deleteCalendar(head, calendar.calendarId, organization); + + expect(result).toBe(calendar.calendarId); + + const deletedCalendar = await prisma.calendar.findUnique({ + where: { calendarId: calendar.calendarId } + }); + expect(deletedCalendar?.dateDeleted).toBeTruthy(); + expect(deletedCalendar?.userDeletedId).toBe(head.userId); + }); + + it('succeeds for admin', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); + + const calendar = await prisma.calendar.create({ + data: { + name: 'Admin Delete Calendar', + description: 'Test', + colorHexCode: '#00FF00', + userCreatedId: admin.userId, + organizationId: orgId + } + }); + + const result = await CalendarService.deleteCalendar(admin, calendar.calendarId, organization); + expect(result).toBe(calendar.calendarId); + }); + + it('fails if calendar not found', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); + + await expect(CalendarService.deleteCalendar(admin, 'non-existent-id', organization)).rejects.toThrow( + new NotFoundException('Calendar', 'non-existent-id') + ); + }); + + it('fails if calendar already deleted', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); + + const calendar = await prisma.calendar.create({ + data: { + name: 'Already Deleted', + description: 'Test', + colorHexCode: '#0000FF', + userCreatedId: admin.userId, + organizationId: orgId, + dateDeleted: new Date() // Already deleted + } + }); + + await expect(CalendarService.deleteCalendar(admin, calendar.calendarId, organization)).rejects.toThrow( + new DeletedException('Calendar', calendar.calendarId) + ); + }); + }); + describe('Create EventType', () => { it('Fails if user is not an admin', async () => { await expect( From f60f060934c7bc80057c54c90a07e76031e30253 Mon Sep 17 00:00:00 2001 From: Lisa W Date: Sun, 28 Sep 2025 03:01:03 -0400 Subject: [PATCH 083/477] Trying to Fix Linting --- src/backend/src/services/calendar.services.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 2b4fe4fce9..c0a6daa9ff 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -10,12 +10,11 @@ import { InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; -import { userHasPermission, getUserRole } from '../utils/users.utils'; +import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { shopTransformer } from '../transformers/calendar.transformer'; import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; -import { getTaskQueryArgs } from '../prisma-query-args/tasks.query-args'; export default class CalendarService { /** From 12bc5a4fa0c9551fe9591b48ef3c00885654ae0a Mon Sep 17 00:00:00 2001 From: Lisa W Date: Sun, 28 Sep 2025 03:06:25 -0400 Subject: [PATCH 084/477] Trying to Fix Prettier --- src/backend/src/routes/calendar.routes.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 61d052cda5..6598ecb3df 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -45,9 +45,6 @@ calendarRouter.post( CalendarController.createShop ); -calendarRouter.post( - '/:calendarId/delete', - CalendarController.deleteCalendar -); +calendarRouter.post('/:calendarId/delete', CalendarController.deleteCalendar); export default calendarRouter; From 2993318b1757ca0e7cfdb0d482b0f9c39608b192 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sun, 28 Sep 2025 10:21:47 -0400 Subject: [PATCH 085/477] Deleting Connected Shop Machinery --- src/backend/src/services/calendar.services.ts | 14 ++++++++----- src/backend/tests/unit/calendar.test.ts | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 3a092d6a7f..41383f6ad3 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -224,11 +224,15 @@ export default class CalendarService { throw new NotFoundException('Shop', shopId); } - // Soft delete and return transformed DTO - const deleted = await prisma.shop.update({ - where: { shopId }, - data: { dateDeleted: new Date() }, - include: getShopQueryArgs(organization.organizationId).include + // Soft delete the shop and its associated shop machinery in a transaction + const deleted = await prisma.$transaction(async (tx) => { + await tx.shopMachinery.deleteMany({ where: { shopId } }); + + return tx.shop.update({ + where: { shopId }, + data: { dateDeleted: new Date() }, + include: getShopQueryArgs(organization.organizationId).include + }); }); return shopTransformer(deleted); diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index f473cc600a..2310a5c9f6 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -206,6 +206,27 @@ describe('Calendar Tests', () => { await expect(CalendarService.deleteShop(admin, shopId, organization)).rejects.toBeInstanceOf(NotFoundException); }); + it('also deletes associated shopMachinery bridge rows', async () => { + // create a machinery that links to this shop + const admin = await createTestUser(batmanAppAdmin, orgId); + await CalendarService.createMachinery(admin, 'Bridge-Linked', shopId, 1, organization); + + //confirm the bridge row exists before delete + const before = await prisma.shopMachinery.count({ where: { shopId } }); + expect(before).toBeGreaterThan(0); + + // delete shop + await CalendarService.deleteShop(admin, shopId, organization); + + // the bridge should be cleaned up + const after = await prisma.shopMachinery.count({ where: { shopId } }); + expect(after).toBe(0); + + // the shop should be soft-deleted + const deletedShop = await prisma.shop.findUnique({ where: { shopId } }); + expect(deletedShop?.dateDeleted).not.toBeNull(); + }); + it('fails if shop belongs to a different organization', async () => { const existing = await prisma.user.findFirstOrThrow({ where: { googleAuthId: supermanAdmin.googleAuthId }, From 713a5a018b7ca8ef1b04f1c3692d71994c9abc37 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sun, 28 Sep 2025 10:26:32 -0400 Subject: [PATCH 086/477] Prettier fix --- src/backend/tests/unit/calendar.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 2310a5c9f6..26353ade3e 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -207,7 +207,7 @@ describe('Calendar Tests', () => { }); it('also deletes associated shopMachinery bridge rows', async () => { - // create a machinery that links to this shop + // create a machinery that links to this shop const admin = await createTestUser(batmanAppAdmin, orgId); await CalendarService.createMachinery(admin, 'Bridge-Linked', shopId, 1, organization); From 97be9f34533c45a78dfc83b4a892e9c01af1b95e Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 28 Sep 2025 16:07:05 -0400 Subject: [PATCH 087/477] #3576 hopefully correct commit for new editmachinery endpoint --- .../src/controllers/calendar.controllers.ts | 20 +++ src/backend/src/routes/calendar.routes.ts | 10 ++ src/backend/src/services/calendar.services.ts | 98 +++++++++++- src/backend/src/utils/errors.utils.ts | 1 + src/backend/tests/unit/calendar.test.ts | 148 +++++++++++++++++- 5 files changed, 274 insertions(+), 3 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 94220744f7..1aed921e3a 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -64,6 +64,26 @@ export default class CalendarController { } } + static async editMachinery(req: Request, res: Response, next: NextFunction) { + try { + const { machineryId } = req.params; + const { name, shopId, quantity, description } = req.body; + + const machinery = await CalendarService.editMachinery( + req.currentUser, + machineryId, + name, + shopId, + quantity, + req.organization, + description + ); + res.status(200).json(machinery); + } catch (error: unknown) { + next(error); + } + } + static async createShop(req: Request, res: Response, next: NextFunction) { try { const { name, description } = req.body; diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 03ad7c2fe4..0118a7323c 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -37,6 +37,16 @@ calendarRouter.post( CalendarController.createMachinery ); +calendarRouter.put( + '/machinery/edit/:machineryId', + nonEmptyString(body('name')), + nonEmptyString(body('shopId')), + body('quantity').isInt({ min: 1 }), + body('description').optional().isString(), + validateInputs, + CalendarController.editMachinery +); + calendarRouter.post( '/shop/create', nonEmptyString(body('name')), diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index a56a466d53..4b225bc34a 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,9 +1,14 @@ import { machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { Organization, User } from '@prisma/client'; -import { isAdmin, EventType, Shop } from 'shared'; +import { isAdmin, isHead, EventType, Shop } from 'shared'; import prisma from '../prisma/prisma'; -import { AccessDeniedAdminOnlyException, InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; +import { + AccessDeniedAdminOnlyException, + AccessDeniedException, + InvalidOrganizationException, + NotFoundException +} from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; @@ -170,6 +175,95 @@ export default class CalendarService { return machineryTransformer(newMachinery); } + + /** + * Edits an existing machinery and its associated shop machinery. + * + * @param submitter The user submitting the request, who must be a head or above. + * @param machineryId The ID of the machinery to edit. + * @param name The new name of the machinery. + * @param shopId The shop ID to associate with the machinery. + * @param quantity The quantity of machinery in the shop. + * @param organization The organization for which the machinery is being edited. + * @param description The description of the machinery (optional). + * + * @returns The updated machinery object with associated shop machinery. + * + * @throws AccessDeniedException If the submitter is not a head or above. + * @throws NotFoundException If the machinery or shop with the given IDs do not exist. + * @throws InvalidOrganizationException If the machinery or shop does not belong to the same organization. + */ + static async editMachinery( + submitter: User, + machineryId: string, + name: string, + shopId: string, + quantity: number, + organization: Organization, + description?: string + ) { + // Check if user is head or above + if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead))) { + throw new AccessDeniedException('Only heads and above can edit machinery'); + } + + // Check if machinery with id exists and belongs to the same organization + const existingMachinery = await prisma.machinery.findUnique({ + where: { machineryId } + }); + + if (!existingMachinery) { + throw new NotFoundException('Machinery', machineryId); + } + + if (existingMachinery.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Shop'); + } + + // Check if shop with id exists and belongs to the same organization + const existingShop = await prisma.shop.findUnique({ + where: { shopId } + }); + + if (!existingShop) { + throw new NotFoundException('Shop', shopId); + } + + if (existingShop.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Shop'); + } + + // Update the machinery and its shop machinery relationship + const updatedMachinery = await prisma.machinery.update({ + where: { machineryId }, + data: { + name, + shops: { + upsert: { + where: { + uniqueShopMachinery: { + shopId, + machineryId + } + }, + create: { + shopId, + quantity, + description + }, + update: { + quantity, + description + } + } + } + }, + ...getMachineryQueryArgs(organization.organizationId) + }); + + return machineryTransformer(updatedMachinery); + } + /** * Creates a new shop * requires the submitter to be Admin diff --git a/src/backend/src/utils/errors.utils.ts b/src/backend/src/utils/errors.utils.ts index 1149980dfd..2cb1ff7918 100644 --- a/src/backend/src/utils/errors.utils.ts +++ b/src/backend/src/utils/errors.utils.ts @@ -158,6 +158,7 @@ export type ExceptionObjectNames = | 'Sponsor' | 'SponsorTask' | 'Shop' + | 'Machinery' | 'Sponsor Tier' | 'Index Code' | 'Reimbursement Product Other Reason' diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index aec322aaa0..1a2f58437f 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,6 +1,6 @@ import { Calendar, Organization } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; -import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; +import { AccessDeniedAdminOnlyException, AccessDeniedException, NotFoundException } from '../../src/utils/errors.utils'; import { batmanAppAdmin, wonderwomanGuest, @@ -143,6 +143,152 @@ describe('Calendar Tests', () => { }); }); + describe('Edit Machinery', () => { + let machineryId: string; + let anotherShopId: string; + + //Create some machinery beforehand so we can edit it + beforeEach(async () => { + await resetUsers(); + + // Recreate the organization and shop since resetUsers() cleared everything + organization = await createTestOrganization(); + orgId = organization.organizationId; + + const shop = await prisma.shop.create({ + data: { + name: 'Precision Manufacturing Lab', + description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', + userCreatedId: (await createTestUser(supermanAdmin, orgId)).userId, + organizationId: orgId + } + }); + ({ shopId } = shop); + + const machinery = await CalendarService.createMachinery( + await createTestUser(alfred, orgId), + 'Original Machinery Name', + shopId, + 1, + organization, + 'Original description' + ); + const { machineryId: machineryIdFromResponse } = machinery; + machineryId = machineryIdFromResponse; + + // Create another shop for testing (add onto the created machinery above) + const anotherShop = await prisma.shop.create({ + data: { + name: 'Advanced Testing Lab', + description: 'Advanced testing facility', + userCreatedId: (await createTestUser(flashAdmin, orgId)).userId, + organizationId: orgId + } + }); + const { shopId: anotherShopIdFromResponse } = anotherShop; + anotherShopId = anotherShopIdFromResponse; + }); + + it('Fails if user is not a head or above', async () => { + await expect( + async () => + await CalendarService.editMachinery( + await createTestUser(wonderwomanGuest, orgId), + machineryId, + 'Updated Machinery Name', + shopId, + 2, + organization, + 'Updated description' + ) + ).rejects.toThrow(new AccessDeniedException('Only heads and above can edit machinery')); + }); + + it('Fails if machinery does not exist', async () => { + const nonExistentId = 'non-existent-id'; + await expect( + async () => + await CalendarService.editMachinery( + await createTestUser(supermanAdmin, orgId), + nonExistentId, + 'Updated Machinery Name', + shopId, + 2, + organization, + 'Updated description' + ) + ).rejects.toThrow(new NotFoundException('Machinery', nonExistentId)); + }); + + it('Fails if shop does not exist', async () => { + const nonExistentShopId = 'non-existent-shop-id'; + await expect( + async () => + await CalendarService.editMachinery( + await createTestUser(supermanAdmin, orgId), + machineryId, + 'Updated Machinery Name', + nonExistentShopId, + 2, + organization, + 'Updated description' + ) + ).rejects.toThrow(new NotFoundException('Shop', nonExistentShopId)); + }); + + it('Succeeds and updates machinery for head user', async () => { + const result = await CalendarService.editMachinery( + await createTestUser(supermanAdmin, orgId), + machineryId, + 'Updated Machinery Name', + shopId, + 3, + organization, + 'Updated description' + ); + + expect(result.name).toEqual('Updated Machinery Name'); + expect(result.shops).toHaveLength(1); + expect(result.shops[0].quantity).toBe(3); + expect(result.shops[0].description).toBe('Updated description'); + expect(result.shops[0].shop.name).toBe('Precision Manufacturing Lab'); + }); + + it('Succeeds and updates machinery for admin user', async () => { + const result = await CalendarService.editMachinery( + await createTestUser(batmanAppAdmin, orgId), + machineryId, + 'Admin Updated Machinery', + anotherShopId, + 5, + organization, + 'Admin updated description' + ); + + expect(result.name).toEqual('Admin Updated Machinery'); + expect(result.shops).toHaveLength(1); + expect(result.shops[0].quantity).toBe(5); + expect(result.shops[0].description).toBe('Admin updated description'); + expect(result.shops[0].shop.name).toBe('Advanced Testing Lab'); + }); + + it('Succeeds and updates machinery without description', async () => { + const result = await CalendarService.editMachinery( + await createTestUser(supermanAdmin, orgId), + machineryId, + 'No Description Machinery', + shopId, + 2, + organization + ); + + expect(result.name).toEqual('No Description Machinery'); + expect(result.shops).toHaveLength(1); + expect(result.shops[0].quantity).toBe(2); + expect(result.shops[0].description).toBe(undefined); + }); + }); + describe('Shop Tests', () => { describe('create shop', () => { it('fails if user is not an admin', async () => { From b3fb081912874b6f21d0c0a5ab0e6e6db44f4283 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 28 Sep 2025 18:33:17 -0400 Subject: [PATCH 088/477] #3576 revamp tests --- src/backend/tests/unit/calendar.test.ts | 135 +++++++++--------------- 1 file changed, 50 insertions(+), 85 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 1a2f58437f..0738579590 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,47 +1,50 @@ -import { Calendar, Organization } from '@prisma/client'; +import { Calendar, Organization, User } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; import { AccessDeniedAdminOnlyException, AccessDeniedException, NotFoundException } from '../../src/utils/errors.utils'; -import { - batmanAppAdmin, - wonderwomanGuest, - supermanAdmin, - flashAdmin, - theVisitorGuest, - alfred -} from '../test-data/users.test-data'; +import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; +import { Machinery, Shop } from 'shared'; describe('Calendar Tests', () => { let orgId: string; let organization: Organization; + let adminUser: User; let calendar: Calendar; - let shopId: string; + let shop: Shop; + let machinery: Machinery; beforeEach(async () => { organization = await createTestOrganization(); orgId = organization.organizationId; + adminUser = await createTestUser(batmanAppAdmin, orgId); calendar = await prisma.calendar.create({ data: { name: 'Engineering Team Calendar', description: 'Tracks all engineering team events, meetings, and deadlines.', colorHexCode: '#3498db', - userCreated: { connect: { userId: (await createTestUser(supermanAdmin, orgId)).userId } }, + userCreated: { connect: { userId: adminUser.userId } }, dateCreated: new Date(), organization: { connect: { organizationId: organization.organizationId } } } }); - const shop = await prisma.shop.create({ - data: { - name: 'Precision Manufacturing Lab', - description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', - userCreatedId: (await createTestUser(flashAdmin, orgId)).userId, - organizationId: orgId - } - }); - ({ shopId } = shop); + shop = await CalendarService.createShop( + adminUser, + 'Precision Manufacturing Lab', + 'Manufacturing facility equipped with advanced machinery and tools for engineering', + organization + ); + + machinery = await CalendarService.createMachinery( + adminUser, + 'Original Machinery Name', + shop.shopId, + 1, + organization, + 'Original description' + ); }); afterEach(async () => { @@ -76,7 +79,7 @@ describe('Calendar Tests', () => { it('Succeeds and creates an event type', async () => { const result = await CalendarService.createEventType( - await createTestUser(batmanAppAdmin, orgId), + await createTestUser(supermanAdmin, orgId), 'Team Meeting', [], organization, @@ -119,7 +122,7 @@ describe('Calendar Tests', () => { await CalendarService.createMachinery( await createTestUser(wonderwomanGuest, orgId), 'Captain America Shield Press', - shopId, + shop.shopId, 1, organization ) @@ -128,9 +131,9 @@ describe('Calendar Tests', () => { it('Succeeds and creates machinery', async () => { const result = await CalendarService.createMachinery( - await createTestUser(alfred, orgId), + await createTestUser(supermanAdmin, orgId), 'Iron Man Mark 42 CNC Mill', - shopId, + shop.shopId, 2, organization ); @@ -144,59 +147,14 @@ describe('Calendar Tests', () => { }); describe('Edit Machinery', () => { - let machineryId: string; - let anotherShopId: string; - - //Create some machinery beforehand so we can edit it - beforeEach(async () => { - await resetUsers(); - - // Recreate the organization and shop since resetUsers() cleared everything - organization = await createTestOrganization(); - orgId = organization.organizationId; - - const shop = await prisma.shop.create({ - data: { - name: 'Precision Manufacturing Lab', - description: 'Manufacturing facility equipped with advanced machinery and tools for engineering', - userCreatedId: (await createTestUser(supermanAdmin, orgId)).userId, - organizationId: orgId - } - }); - ({ shopId } = shop); - - const machinery = await CalendarService.createMachinery( - await createTestUser(alfred, orgId), - 'Original Machinery Name', - shopId, - 1, - organization, - 'Original description' - ); - const { machineryId: machineryIdFromResponse } = machinery; - machineryId = machineryIdFromResponse; - - // Create another shop for testing (add onto the created machinery above) - const anotherShop = await prisma.shop.create({ - data: { - name: 'Advanced Testing Lab', - description: 'Advanced testing facility', - userCreatedId: (await createTestUser(flashAdmin, orgId)).userId, - organizationId: orgId - } - }); - const { shopId: anotherShopIdFromResponse } = anotherShop; - anotherShopId = anotherShopIdFromResponse; - }); - it('Fails if user is not a head or above', async () => { await expect( async () => await CalendarService.editMachinery( await createTestUser(wonderwomanGuest, orgId), - machineryId, + machinery.machineryId, 'Updated Machinery Name', - shopId, + shop.shopId, 2, organization, 'Updated description' @@ -212,7 +170,7 @@ describe('Calendar Tests', () => { await createTestUser(supermanAdmin, orgId), nonExistentId, 'Updated Machinery Name', - shopId, + shop.shopId, 2, organization, 'Updated description' @@ -226,7 +184,7 @@ describe('Calendar Tests', () => { async () => await CalendarService.editMachinery( await createTestUser(supermanAdmin, orgId), - machineryId, + machinery.machineryId, 'Updated Machinery Name', nonExistentShopId, 2, @@ -239,9 +197,9 @@ describe('Calendar Tests', () => { it('Succeeds and updates machinery for head user', async () => { const result = await CalendarService.editMachinery( await createTestUser(supermanAdmin, orgId), - machineryId, + machinery.machineryId, 'Updated Machinery Name', - shopId, + shop.shopId, 3, organization, 'Updated description' @@ -255,11 +213,18 @@ describe('Calendar Tests', () => { }); it('Succeeds and updates machinery for admin user', async () => { + const anotherShop = await CalendarService.createShop( + await createTestUser(alfred, orgId), + 'Advanced Testing Lab', + 'Advanced testing facility', + organization + ); + const result = await CalendarService.editMachinery( - await createTestUser(batmanAppAdmin, orgId), - machineryId, + await createTestUser(supermanAdmin, orgId), + machinery.machineryId, 'Admin Updated Machinery', - anotherShopId, + anotherShop.shopId, 5, organization, 'Admin updated description' @@ -275,9 +240,9 @@ describe('Calendar Tests', () => { it('Succeeds and updates machinery without description', async () => { const result = await CalendarService.editMachinery( await createTestUser(supermanAdmin, orgId), - machineryId, + machinery.machineryId, 'No Description Machinery', - shopId, + shop.shopId, 2, organization ); @@ -298,8 +263,7 @@ describe('Calendar Tests', () => { }); it('succeeds for admin', async () => { - // Using a different admin fixture to avoid googleAuthId collision with the calendar creator - const admin = await createTestUser(batmanAppAdmin, orgId); + const admin = await createTestUser(supermanAdmin, orgId); const result = await CalendarService.createShop(admin, 'Demo Shop', 'A seeded demo shop', organization); @@ -309,10 +273,11 @@ describe('Calendar Tests', () => { }); it('fails on duplicate name', async () => { - const admin = await createTestUser(batmanAppAdmin, orgId); - await CalendarService.createShop(admin, 'UniqueName', 'first', organization); + await CalendarService.createShop(await createTestUser(supermanAdmin, orgId), 'UniqueName', 'first', organization); - await expect(CalendarService.createShop(admin, 'UniqueName', 'second attempt', organization)).rejects.toBeTruthy(); + await expect( + CalendarService.createShop(await createTestUser(alfred, orgId), 'UniqueName', 'second attempt', organization) + ).rejects.toBeTruthy(); }); }); }); From 8cc1d575953badfd9451de68b75da691483c0120 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 28 Sep 2025 22:48:04 -0400 Subject: [PATCH 089/477] endpoint stuff --- .../src/controllers/calendar.controllers.ts | 18 +++++++ .../prisma-query-args/calendar.query-args.ts | 13 +++++ src/backend/src/prisma/seed.ts | 36 ++++++++++---- src/backend/src/routes/calendar.routes.ts | 9 ++++ src/backend/src/services/calendar.services.ts | 41 +++++++++++++++- .../src/transformers/calendar.transformer.ts | 15 +++++- src/backend/tests/unit/calendar.test.ts | 49 +++++++++++++++++++ 7 files changed, 168 insertions(+), 13 deletions(-) create mode 100644 src/backend/src/prisma-query-args/calendar.query-args.ts diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 94220744f7..07b35bdc7c 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -75,4 +75,22 @@ export default class CalendarController { next(error); } } + + static async createCalendar(req: Request, res: Response, next: NextFunction) { + try { + const { name, description, colorHexCode } = req.body; + + const calendar = await CalendarService.createCalendar( + req.currentUser, + name, + description, + colorHexCode, + req.organization + ); + + res.status(200).json(calendar); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/prisma-query-args/calendar.query-args.ts b/src/backend/src/prisma-query-args/calendar.query-args.ts new file mode 100644 index 0000000000..82d2b10a1c --- /dev/null +++ b/src/backend/src/prisma-query-args/calendar.query-args.ts @@ -0,0 +1,13 @@ +import { Prisma } from '@prisma/client'; +import { getUserQueryArgs } from './user.query-args'; +import { getEventTypeQueryArgs } from './event-type.query-args'; + +export type CalendarQueryArgs = ReturnType; + +export const getCalendarQueryArgs = (organizationId: string) => + Prisma.validator()({ + include: { + userCreated: getUserQueryArgs(organizationId), + eventTypes: getEventTypeQueryArgs(organizationId) + } + }); diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 8662325644..4e85904c00 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3134,16 +3134,30 @@ const performSeed: () => Promise = async () => { 'Thermal imaging and analysis' ); - const calendar = await prisma.calendar.create({ - data: { - name: 'Engineering Team Calendar', - description: 'Tracks all engineering team events, meetings, and deadlines.', - colorHexCode: '#3498db', - userCreated: { connect: { userId: thomasEmrax.userId } }, - dateCreated: new Date(), - organization: { connect: { organizationId } } - } - }); + // various calendars for testing + const calendar = await CalendarService.createCalendar( + thomasEmrax, + 'Engineering Team Calendar', + 'Tracks all engineering team events, meetings, and deadlines.', + '#3498db', + ner + ); + + const calendarFinishline = await CalendarService.createCalendar( + joeShmoe, + 'Finishline Projects Calendar', + 'Tracks all ongoing projects currently being developed for Finishline', + '#911111ff', + ner + ); + + const calendarMeta = await CalendarService.createCalendar( + thomasEmrax, + 'Calendar Improvements Calendar', + 'Tracks all current improvements and schedulings for the improvement of the Finishline Calendar', + '#bf40e6ff', + ner + ); // meeting event type await CalendarService.createEventType( @@ -3228,6 +3242,8 @@ const performSeed: () => Promise = async () => { false, true ); + + console.log('Thomas Emrax:', thomasEmrax.userId); }; performSeed() diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 03ad7c2fe4..5b4294bd04 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -45,4 +45,13 @@ calendarRouter.post( CalendarController.createShop ); +calendarRouter.post( + '/calendar/create', + nonEmptyString(body('name')), + body('description').optional().isString(), + nonEmptyString(body('colorHexCode')), + validateInputs, + CalendarController.createCalendar +); + export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index a56a466d53..f2ced67dc2 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,7 +1,7 @@ -import { machineryTransformer } from '../transformers/calendar.transformer'; +import { calendarTransformer, machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { Organization, User } from '@prisma/client'; -import { isAdmin, EventType, Shop } from 'shared'; +import { isAdmin, EventType, Shop, Calendar } from 'shared'; import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException, InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; @@ -9,6 +9,7 @@ import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { shopTransformer } from '../transformers/calendar.transformer'; import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; +import { getCalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; export default class CalendarService { /** @@ -191,4 +192,40 @@ export default class CalendarService { return shopTransformer(newShop); } + + /** + * @param submitter The user submitting the request, who must be an admin + * @param name The name of the calendar + * @param description A summary of what the calendar is used for + * @param colorHexCode The color of the calendar + * @param organization The organization for which the calendar is being created + * + * @returns The created calendar + * + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + */ + static async createCalendar( + submitter: User, + name: string, + description: string, + colorHexCode: string, + organization: Organization + ): Promise { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('create calendar'); + } + + const newCalendar = await prisma.calendar.create({ + data: { + name, + description, + colorHexCode, + userCreatedId: submitter.userId, + organizationId: organization.organizationId + }, + ...getCalendarQueryArgs(organization.organizationId) + }); + + return calendarTransformer(newCalendar); + } } diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 1e65e4508e..268e636e8e 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -1,8 +1,9 @@ import { Prisma } from '@prisma/client'; -import { Machinery, Shop, ShopMachinery, EventType } from 'shared'; +import { Machinery, Shop, ShopMachinery, EventType, Calendar } from 'shared'; import { MachineryQueryArgs, ShopQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { userTransformer } from './user.transformer'; import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; +import { CalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; export const shopTransformer = (shop: Prisma.ShopGetPayload): Shop => { return { @@ -56,3 +57,15 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload): Calendar => { + return { + calendarId: calendar.calendarId, + name: calendar.name, + description: calendar.description, + color: calendar.colorHexCode, + userCreated: userTransformer(calendar.userCreated), + dateCreated: calendar.dateCreated, + eventTypes: calendar.eventTypes.map(eventTypeTransformer) + }; +}; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index aec322aaa0..0155193119 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -170,4 +170,53 @@ describe('Calendar Tests', () => { }); }); }); + + describe('Main Calendar Tests', () => { + describe('create calendar', () => { + it('fails if user is not an admin', async () => { + await expect( + CalendarService.createCalendar( + await createTestUser(wonderwomanGuest, orgId), + 'Non-Admin Calendar', + 'desc', + '#3498db', + organization + ) + ).rejects.toThrow(new AccessDeniedAdminOnlyException('create calendar')); + }); + + it('succeeds for admin', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); + + const result = await CalendarService.createCalendar( + admin, + 'Cool Calendar', + 'A very cool calendar', + '#3498db', + organization + ); + + expect(result.name).toBe('Cool Calendar'); + expect(result.description).toBe('A very cool calendar'); + expect(result.color).toBe('#3498db'); + expect(result.userCreated.userId).toBe(admin.userId); + }); + + it('fails on duplicate name', async () => { + const admin = await createTestUser(batmanAppAdmin, orgId); + + await CalendarService.createCalendar(admin, 'Cool Calendar', 'A very cool calendar', '#3498db', organization); + + await expect( + CalendarService.createCalendar( + admin, + 'Cool Calendar', + 'A very cool calendar, but not quite as cool', + '#0062a3ff', + organization + ) + ).rejects.toBeTruthy(); + }); + }); + }); }); From 2c94b328f56552ee0ea715b13763a346171cff33 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 29 Sep 2025 08:50:46 -0400 Subject: [PATCH 090/477] #3576 Adjusted machinery service for editing by "refreshing" connected shops --- src/backend/src/services/calendar.services.ts | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 4b225bc34a..cc39d6fbfd 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -239,22 +239,11 @@ export default class CalendarService { data: { name, shops: { - upsert: { - where: { - uniqueShopMachinery: { - shopId, - machineryId - } - }, - create: { - shopId, - quantity, - description - }, - update: { - quantity, - description - } + deleteMany: {}, + create: { + shopId, + quantity, + description } } }, From 5cd76918d4d1fb154fba2e643c105ff19a3ec5af Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 29 Sep 2025 12:29:07 -0400 Subject: [PATCH 091/477] minor fix --- src/backend/src/routes/calendar.routes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 5b4294bd04..f75824ab9c 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -46,9 +46,9 @@ calendarRouter.post( ); calendarRouter.post( - '/calendar/create', + '/create', nonEmptyString(body('name')), - body('description').optional().isString(), + body('description').isString(), nonEmptyString(body('colorHexCode')), validateInputs, CalendarController.createCalendar From 3d0710d617f1dcede3170f8e79df28ca40b69d5f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 29 Sep 2025 12:39:07 -0400 Subject: [PATCH 092/477] minor update 2 --- src/backend/src/routes/calendar.routes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index f75824ab9c..9aa1bd843f 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -48,7 +48,7 @@ calendarRouter.post( calendarRouter.post( '/create', nonEmptyString(body('name')), - body('description').isString(), + nonEmptyString(body('description')), nonEmptyString(body('colorHexCode')), validateInputs, CalendarController.createCalendar From 7f89991a5fcd489b3eaaecc20410fe945ba9074d Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 29 Sep 2025 18:50:48 -0400 Subject: [PATCH 093/477] prettier --- src/backend/src/services/calendar.services.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 7a91beba6e..c20b5b1e61 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -275,4 +275,3 @@ export default class CalendarService { return shopTransformer(deleted); } } - From 0a59e0002803fb21b6b860544c4183bec57b8335 Mon Sep 17 00:00:00 2001 From: Lisa W Date: Mon, 29 Sep 2025 20:01:36 -0400 Subject: [PATCH 094/477] Fixed Permissions and Return Value --- .../prisma-query-args/calendar.query-args.ts | 25 ++++++++++++++ src/backend/src/services/calendar.services.ts | 20 +++++------ .../src/transformers/calendar.transformer.ts | 14 +++++++- src/backend/tests/unit/calendar.test.ts | 33 ++++--------------- 4 files changed, 54 insertions(+), 38 deletions(-) create mode 100644 src/backend/src/prisma-query-args/calendar.query-args.ts diff --git a/src/backend/src/prisma-query-args/calendar.query-args.ts b/src/backend/src/prisma-query-args/calendar.query-args.ts new file mode 100644 index 0000000000..3055ff6856 --- /dev/null +++ b/src/backend/src/prisma-query-args/calendar.query-args.ts @@ -0,0 +1,25 @@ +import { Prisma } from '@prisma/client'; + +export type CalendarQueryArgs = ReturnType; + +export const getCalendarQueryArgs = (_organizationId: string) => + Prisma.validator()({ + include: { + userCreated: { + include: { + roles: true, + organizations: true + } + }, + eventTypes: { + include: { + userCreated: { + include: { + roles: true, + organizations: true + } + } + } + } + } + }); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index c0a6daa9ff..e9bd043b97 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,7 +1,7 @@ -import { machineryTransformer } from '../transformers/calendar.transformer'; +import { calendarTransformer, machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { Organization, User } from '@prisma/client'; -import { isAdmin, isHead, EventType, Shop } from 'shared'; +import { isAdmin, EventType, Shop, Calendar } from 'shared'; import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException, @@ -15,6 +15,7 @@ import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { shopTransformer } from '../transformers/calendar.transformer'; import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; +import { getCalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; export default class CalendarService { /** @@ -211,7 +212,7 @@ export default class CalendarService { * @throws DeletedException If the calendar has already been deleted. * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. */ - static async deleteCalendar(submitter: User, calendarId: string, organization: Organization): Promise { + static async deleteCalendar(submitter: User, calendarId: string, organization: Organization): Promise { const calendar = await prisma.calendar.findUnique({ where: { calendarId } }); @@ -220,21 +221,18 @@ export default class CalendarService { if (calendar.dateDeleted) throw new DeletedException('Calendar', calendarId); if (calendar.organizationId !== organization.organizationId) throw new InvalidOrganizationException('Calendar'); - const hasPermission = await userHasPermission( - submitter.userId, - organization.organizationId, - (role) => isAdmin(role) || isHead(role) - ); + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); if (!hasPermission) { - throw new AccessDeniedException('Only heads and above can delete calendars'); + throw new AccessDeniedException('Only admins can delete calendars'); } const deletedCalendar = await prisma.calendar.update({ where: { calendarId }, - data: { dateDeleted: new Date(), userDeletedId: submitter.userId } + data: { dateDeleted: new Date(), userDeletedId: submitter.userId }, + ...getCalendarQueryArgs(organization.organizationId) }); - return deletedCalendar.calendarId; + return calendarTransformer(deletedCalendar); } } diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 1e65e4508e..c73057c245 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -1,5 +1,5 @@ import { Prisma } from '@prisma/client'; -import { Machinery, Shop, ShopMachinery, EventType } from 'shared'; +import { Machinery, Shop, ShopMachinery, EventType, Calendar } from 'shared'; import { MachineryQueryArgs, ShopQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { userTransformer } from './user.transformer'; import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; @@ -56,3 +56,15 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload { + return { + calendarId: calendar.calendarId, + name: calendar.name, + description: calendar.description ?? '', + color: calendar.colorHexCode, + userCreated: userTransformer(calendar.userCreated), + dateCreated: calendar.dateCreated, + eventTypes: calendar.eventTypes?.map(eventTypeTransformer) ?? [] + }; +}; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index ed935e6043..5521ee9f8c 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -69,34 +69,10 @@ describe('Calendar Tests', () => { }); await expect(CalendarService.deleteCalendar(member, calendar.calendarId, organization)).rejects.toThrow( - new AccessDeniedException('Only heads and above can delete calendars') + new AccessDeniedException('Only admins can delete calendars') ); }); - it('succeeds for head', async () => { - const head = await createTestUser(greenlanternHead, orgId); - - const calendar = await prisma.calendar.create({ - data: { - name: 'Calendar to Delete', - description: 'Test', - colorHexCode: '#FF0000', - userCreatedId: head.userId, - organizationId: orgId - } - }); - - const result = await CalendarService.deleteCalendar(head, calendar.calendarId, organization); - - expect(result).toBe(calendar.calendarId); - - const deletedCalendar = await prisma.calendar.findUnique({ - where: { calendarId: calendar.calendarId } - }); - expect(deletedCalendar?.dateDeleted).toBeTruthy(); - expect(deletedCalendar?.userDeletedId).toBe(head.userId); - }); - it('succeeds for admin', async () => { const admin = await createTestUser(batmanAppAdmin, orgId); @@ -111,7 +87,12 @@ describe('Calendar Tests', () => { }); const result = await CalendarService.deleteCalendar(admin, calendar.calendarId, organization); - expect(result).toBe(calendar.calendarId); + + expect(result.calendarId).toBe(calendar.calendarId); + expect(result.name).toBe('Admin Delete Calendar'); + expect(result.description).toBe('Test'); + expect(result.color).toBe('#00FF00'); + expect(result.userCreated.userId).toBe(admin.userId); }); it('fails if calendar not found', async () => { From b0f198b9bb5e879cb85524bc309e48858113b25c Mon Sep 17 00:00:00 2001 From: Lisa W Date: Mon, 29 Sep 2025 20:05:28 -0400 Subject: [PATCH 095/477] Removing Unused Import --- src/backend/tests/unit/calendar.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 5521ee9f8c..6a92eb8a91 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -12,8 +12,7 @@ import { supermanAdmin, flashAdmin, theVisitorGuest, - alfred, - greenlanternHead + alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; From 51352b4568cfe6a4785e706845bb5bfed81580d6 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Tue, 30 Sep 2025 15:50:06 -0400 Subject: [PATCH 096/477] #3565 small repeated imported fix --- src/backend/tests/unit/calendar.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index fb4fb49c84..2be0f1b647 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -4,7 +4,6 @@ import { AccessDeniedAdminOnlyException, AccessDeniedException, NotFoundException, - NotFoundException, InvalidOrganizationException } from '../../src/utils/errors.utils'; import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; From 6738e37b36e0198c5a6cd863b76e121b3339e083 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Tue, 30 Sep 2025 15:58:15 -0400 Subject: [PATCH 097/477] #3565 build failed due to shop not accessed via shopId --- src/backend/tests/unit/calendar.test.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 2be0f1b647..fd13b766ee 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -289,18 +289,18 @@ describe('Calendar Tests', () => { describe('Delete shop', () => { it('fails if user is not head or above', async () => { await expect( - CalendarService.deleteShop(await createTestUser(wonderwomanGuest, orgId), shopId, organization) + CalendarService.deleteShop(await createTestUser(wonderwomanGuest, orgId), shop.shopId, organization) ).rejects.toBeInstanceOf(AccessDeniedAdminOnlyException); }); it('succeeds for admin', async () => { const admin = await createTestUser(batmanAppAdmin, orgId); - const result = await CalendarService.deleteShop(admin, shopId, organization); - expect(result.shopId).toBe(shopId); + const result = await CalendarService.deleteShop(admin, shop.shopId, organization); + expect(result.shopId).toBe(shop.shopId); // verify soft delete happened - const row = await prisma.shop.findUnique({ where: { shopId } }); + const row = await prisma.shop.findUnique({ where: { shopId: shop.shopId } }); expect(row?.dateDeleted).not.toBeNull(); }); @@ -313,29 +313,29 @@ describe('Calendar Tests', () => { it('fails if shop is already deleted', async () => { const admin = await createTestUser(batmanAppAdmin, orgId); - await CalendarService.deleteShop(admin, shopId, organization); + await CalendarService.deleteShop(admin, shop.shopId, organization); - await expect(CalendarService.deleteShop(admin, shopId, organization)).rejects.toBeInstanceOf(NotFoundException); + await expect(CalendarService.deleteShop(admin, shop.shopId, organization)).rejects.toBeInstanceOf(NotFoundException); }); it('also deletes associated shopMachinery bridge rows', async () => { // create a machinery that links to this shop const admin = await createTestUser(batmanAppAdmin, orgId); - await CalendarService.createMachinery(admin, 'Bridge-Linked', shopId, 1, organization); + await CalendarService.createMachinery(admin, 'Bridge-Linked', shop.shopId, 1, organization); //confirm the bridge row exists before delete - const before = await prisma.shopMachinery.count({ where: { shopId } }); + const before = await prisma.shopMachinery.count({ where: { shopId: shop.shopId } }); expect(before).toBeGreaterThan(0); // delete shop - await CalendarService.deleteShop(admin, shopId, organization); + await CalendarService.deleteShop(admin, shop.shopId, organization); // the bridge should be cleaned up - const after = await prisma.shopMachinery.count({ where: { shopId } }); + const after = await prisma.shopMachinery.count({ where: { shopId: shop.shopId } }); expect(after).toBe(0); // the shop should be soft-deleted - const deletedShop = await prisma.shop.findUnique({ where: { shopId } }); + const deletedShop = await prisma.shop.findUnique({ where: { shopId: shop.shopId } }); expect(deletedShop?.dateDeleted).not.toBeNull(); }); @@ -356,7 +356,7 @@ describe('Calendar Tests', () => { const AdminInOtherOrg = await createTestUser(batmanAppAdmin, otherOrg.organizationId); - await expect(CalendarService.deleteShop(AdminInOtherOrg, shopId, otherOrg)).rejects.toThrow( + await expect(CalendarService.deleteShop(AdminInOtherOrg, shop.shopId, otherOrg)).rejects.toThrow( new InvalidOrganizationException('Shop') ); }); From 9b42d05f637ed68ec87f392f710347c9e06cd927 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Tue, 30 Sep 2025 16:00:11 -0400 Subject: [PATCH 098/477] #3576 fixed the shopId updated test for build --- src/backend/tests/unit/calendar.test.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index fb4fb49c84..806bf41ac7 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -290,18 +290,18 @@ describe('Calendar Tests', () => { describe('Delete shop', () => { it('fails if user is not head or above', async () => { await expect( - CalendarService.deleteShop(await createTestUser(wonderwomanGuest, orgId), shopId, organization) + CalendarService.deleteShop(await createTestUser(wonderwomanGuest, orgId), shop.shopId, organization) ).rejects.toBeInstanceOf(AccessDeniedAdminOnlyException); }); it('succeeds for admin', async () => { const admin = await createTestUser(batmanAppAdmin, orgId); - const result = await CalendarService.deleteShop(admin, shopId, organization); - expect(result.shopId).toBe(shopId); + const result = await CalendarService.deleteShop(admin, shop.shopId, organization); + expect(result.shopId).toBe(shop.shopId); // verify soft delete happened - const row = await prisma.shop.findUnique({ where: { shopId } }); + const row = await prisma.shop.findUnique({ where: { shopId: shop.shopId } }); expect(row?.dateDeleted).not.toBeNull(); }); @@ -314,29 +314,29 @@ describe('Calendar Tests', () => { it('fails if shop is already deleted', async () => { const admin = await createTestUser(batmanAppAdmin, orgId); - await CalendarService.deleteShop(admin, shopId, organization); + await CalendarService.deleteShop(admin, shop.shopId, organization); - await expect(CalendarService.deleteShop(admin, shopId, organization)).rejects.toBeInstanceOf(NotFoundException); + await expect(CalendarService.deleteShop(admin, shop.shopId, organization)).rejects.toBeInstanceOf(NotFoundException); }); it('also deletes associated shopMachinery bridge rows', async () => { // create a machinery that links to this shop const admin = await createTestUser(batmanAppAdmin, orgId); - await CalendarService.createMachinery(admin, 'Bridge-Linked', shopId, 1, organization); + await CalendarService.createMachinery(admin, 'Bridge-Linked', shop.shopId, 1, organization); //confirm the bridge row exists before delete - const before = await prisma.shopMachinery.count({ where: { shopId } }); + const before = await prisma.shopMachinery.count({ where: { shopId: shop.shopId } }); expect(before).toBeGreaterThan(0); // delete shop - await CalendarService.deleteShop(admin, shopId, organization); + await CalendarService.deleteShop(admin, shop.shopId, organization); // the bridge should be cleaned up - const after = await prisma.shopMachinery.count({ where: { shopId } }); + const after = await prisma.shopMachinery.count({ where: { shopId: shop.shopId } }); expect(after).toBe(0); // the shop should be soft-deleted - const deletedShop = await prisma.shop.findUnique({ where: { shopId } }); + const deletedShop = await prisma.shop.findUnique({ where: { shopId: shop.shopId } }); expect(deletedShop?.dateDeleted).not.toBeNull(); }); @@ -357,7 +357,7 @@ describe('Calendar Tests', () => { const AdminInOtherOrg = await createTestUser(batmanAppAdmin, otherOrg.organizationId); - await expect(CalendarService.deleteShop(AdminInOtherOrg, shopId, otherOrg)).rejects.toThrow( + await expect(CalendarService.deleteShop(AdminInOtherOrg, shop.shopId, otherOrg)).rejects.toThrow( new InvalidOrganizationException('Shop') ); }); From 651dd1a467c1025e30f4ffa125ac4101a1a88e63 Mon Sep 17 00:00:00 2001 From: Lisa W Date: Tue, 30 Sep 2025 21:46:25 -0400 Subject: [PATCH 099/477] Fixing Minor Errors --- src/backend/src/controllers/calendar.controllers.ts | 2 -- src/backend/src/services/calendar.services.ts | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 72f3ac1a3f..f345568bf8 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -94,7 +94,6 @@ export default class CalendarController { } } - static async deleteCalendar(req: Request, res: Response, next: NextFunction) { try { const { calendarId } = req.params; @@ -107,7 +106,6 @@ export default class CalendarController { } } - static async deleteShop(req: Request, res: Response, next: NextFunction) { try { const { shopId } = req.params; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index faa060d130..f1ce4e81db 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -199,6 +199,7 @@ export default class CalendarService { return shopTransformer(newShop); } + /** * @param submitter The user submitting the request, who must be an admin * @param name The name of the calendar * @param description A summary of what the calendar is used for @@ -233,7 +234,7 @@ export default class CalendarService { return calendarTransformer(newCalendar); } - + /** * Delete calendar in the database * @param submitter The user submitting the request, who must be a head or above. From 6d295012de0fe683dd4dfffa43444843e88d0d65 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 1 Oct 2025 19:15:38 -0400 Subject: [PATCH 100/477] #3576 fix test adminUser --- src/backend/tests/unit/calendar.test.ts | 132 +----------------------- 1 file changed, 1 insertion(+), 131 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index fd13b766ee..0738579590 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,11 +1,6 @@ import { Calendar, Organization, User } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; -import { - AccessDeniedAdminOnlyException, - AccessDeniedException, - NotFoundException, - InvalidOrganizationException -} from '../../src/utils/errors.utils'; +import { AccessDeniedAdminOnlyException, AccessDeniedException, NotFoundException } from '../../src/utils/errors.utils'; import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; @@ -285,130 +280,5 @@ describe('Calendar Tests', () => { ).rejects.toBeTruthy(); }); }); - - describe('Delete shop', () => { - it('fails if user is not head or above', async () => { - await expect( - CalendarService.deleteShop(await createTestUser(wonderwomanGuest, orgId), shop.shopId, organization) - ).rejects.toBeInstanceOf(AccessDeniedAdminOnlyException); - }); - - it('succeeds for admin', async () => { - const admin = await createTestUser(batmanAppAdmin, orgId); - - const result = await CalendarService.deleteShop(admin, shop.shopId, organization); - expect(result.shopId).toBe(shop.shopId); - - // verify soft delete happened - const row = await prisma.shop.findUnique({ where: { shopId: shop.shopId } }); - expect(row?.dateDeleted).not.toBeNull(); - }); - - it('fails if shop does not exist', async () => { - const admin = await createTestUser(batmanAppAdmin, orgId); - await expect(CalendarService.deleteShop(admin, 'non-existent-id', organization)).rejects.toBeInstanceOf( - NotFoundException - ); - }); - - it('fails if shop is already deleted', async () => { - const admin = await createTestUser(batmanAppAdmin, orgId); - await CalendarService.deleteShop(admin, shop.shopId, organization); - - await expect(CalendarService.deleteShop(admin, shop.shopId, organization)).rejects.toBeInstanceOf(NotFoundException); - }); - - it('also deletes associated shopMachinery bridge rows', async () => { - // create a machinery that links to this shop - const admin = await createTestUser(batmanAppAdmin, orgId); - await CalendarService.createMachinery(admin, 'Bridge-Linked', shop.shopId, 1, organization); - - //confirm the bridge row exists before delete - const before = await prisma.shopMachinery.count({ where: { shopId: shop.shopId } }); - expect(before).toBeGreaterThan(0); - - // delete shop - await CalendarService.deleteShop(admin, shop.shopId, organization); - - // the bridge should be cleaned up - const after = await prisma.shopMachinery.count({ where: { shopId: shop.shopId } }); - expect(after).toBe(0); - - // the shop should be soft-deleted - const deletedShop = await prisma.shop.findUnique({ where: { shopId: shop.shopId } }); - expect(deletedShop?.dateDeleted).not.toBeNull(); - }); - - it('fails if shop belongs to a different organization', async () => { - const existing = await prisma.user.findFirstOrThrow({ - where: { googleAuthId: supermanAdmin.googleAuthId }, - select: { userId: true } - }); - - const otherOrg = await prisma.organization.create({ - data: { - name: 'Other Org (calendar test)', - description: 'for cross-org negative case', - applicationLink: '', - userCreated: { connect: { userId: existing.userId } } - } - }); - - const AdminInOtherOrg = await createTestUser(batmanAppAdmin, otherOrg.organizationId); - - await expect(CalendarService.deleteShop(AdminInOtherOrg, shop.shopId, otherOrg)).rejects.toThrow( - new InvalidOrganizationException('Shop') - ); - }); - }); - }); - - describe('Main Calendar Tests', () => { - describe('create calendar', () => { - it('fails if user is not an admin', async () => { - await expect( - CalendarService.createCalendar( - await createTestUser(wonderwomanGuest, orgId), - 'Non-Admin Calendar', - 'desc', - '#3498db', - organization - ) - ).rejects.toThrow(new AccessDeniedAdminOnlyException('create calendar')); - }); - - it('succeeds for admin', async () => { - const admin = await createTestUser(batmanAppAdmin, orgId); - - const result = await CalendarService.createCalendar( - admin, - 'Cool Calendar', - 'A very cool calendar', - '#3498db', - organization - ); - - expect(result.name).toBe('Cool Calendar'); - expect(result.description).toBe('A very cool calendar'); - expect(result.color).toBe('#3498db'); - expect(result.userCreated.userId).toBe(admin.userId); - }); - - it('fails on duplicate name', async () => { - const admin = await createTestUser(batmanAppAdmin, orgId); - - await CalendarService.createCalendar(admin, 'Cool Calendar', 'A very cool calendar', '#3498db', organization); - - await expect( - CalendarService.createCalendar( - admin, - 'Cool Calendar', - 'A very cool calendar, but not quite as cool', - '#0062a3ff', - organization - ) - ).rejects.toBeTruthy(); - }); - }); }); }); From 9bd26480216de2025fd101c729f0cf1d36ea6285 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 1 Oct 2025 19:33:36 -0400 Subject: [PATCH 101/477] #3576 edit machinery final test fix? --- src/backend/tests/unit/calendar.test.ts | 105 +++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 0738579590..bf50d9bc7b 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,6 +1,11 @@ import { Calendar, Organization, User } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; -import { AccessDeniedAdminOnlyException, AccessDeniedException, NotFoundException } from '../../src/utils/errors.utils'; +import { + AccessDeniedAdminOnlyException, + AccessDeniedException, + InvalidOrganizationException, + NotFoundException +} from '../../src/utils/errors.utils'; import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; @@ -13,6 +18,7 @@ describe('Calendar Tests', () => { let calendar: Calendar; let shop: Shop; let machinery: Machinery; + let shopId: string; beforeEach(async () => { organization = await createTestOrganization(); @@ -36,6 +42,7 @@ describe('Calendar Tests', () => { 'Manufacturing facility equipped with advanced machinery and tools for engineering', organization ); + ({ shopId } = shop); machinery = await CalendarService.createMachinery( adminUser, @@ -281,4 +288,100 @@ describe('Calendar Tests', () => { }); }); }); + + describe('Delete shop', () => { + it('fails if user is not head or above', async () => { + await expect( + CalendarService.deleteShop(await createTestUser(wonderwomanGuest, orgId), shop.shopId, organization) + ).rejects.toBeInstanceOf(AccessDeniedAdminOnlyException); + }); + it('succeeds for admin', async () => { + const result = await CalendarService.deleteShop(adminUser, shop.shopId, organization); + expect(result.shopId).toBe(shop.shopId); + // verify soft delete happened + const row = await prisma.shop.findUnique({ where: { shopId } }); + expect(row?.dateDeleted).not.toBeNull(); + }); + it('fails if shop does not exist', async () => { + await expect(CalendarService.deleteShop(adminUser, 'non-existent-id', organization)).rejects.toBeInstanceOf( + NotFoundException + ); + }); + it('fails if shop is already deleted', async () => { + await CalendarService.deleteShop(adminUser, shop.shopId, organization); + await expect(CalendarService.deleteShop(adminUser, shop.shopId, organization)).rejects.toBeInstanceOf( + NotFoundException + ); + }); + it('also deletes associated shopMachinery bridge rows', async () => { + // create a machinery that links to this shop + await CalendarService.createMachinery(adminUser, 'Bridge-Linked', shop.shopId, 1, organization); + //confirm the bridge row exists before delete + const before = await prisma.shopMachinery.count({ where: { shopId } }); + expect(before).toBeGreaterThan(0); + // delete shop + await CalendarService.deleteShop(adminUser, shop.shopId, organization); + // the bridge should be cleaned up + const after = await prisma.shopMachinery.count({ where: { shopId } }); + expect(after).toBe(0); + // the shop should be soft-deleted + const deletedShop = await prisma.shop.findUnique({ where: { shopId } }); + expect(deletedShop?.dateDeleted).not.toBeNull(); + }); + it('fails if shop belongs to a different organization', async () => { + const otherOrg = await prisma.organization.create({ + data: { + name: 'Other Org (calendar test)', + description: 'for cross-org negative case', + applicationLink: '', + userCreated: { connect: { userId: adminUser.userId } } + } + }); + const AdminInOtherOrg = await createTestUser(alfred, otherOrg.organizationId); + await expect(CalendarService.deleteShop(AdminInOtherOrg, shop.shopId, otherOrg)).rejects.toThrow( + new InvalidOrganizationException('Shop') + ); + }); + }); + + describe('Main Calendar Tests', () => { + describe('create calendar', () => { + it('fails if user is not an admin', async () => { + await expect( + CalendarService.createCalendar( + await createTestUser(wonderwomanGuest, orgId), + 'Non-Admin Calendar', + 'desc', + '#3498DB', + organization + ) + ).rejects.toThrow(new AccessDeniedAdminOnlyException('create calendar')); + }); + it('succeeds for admin', async () => { + const result = await CalendarService.createCalendar( + adminUser, + 'Cool Calendar', + 'A very cool calendar', + '#3498DB', + organization + ); + expect(result.name).toBe('Cool Calendar'); + expect(result.description).toBe('A very cool calendar'); + expect(result.color).toBe('#3498DB'); + expect(result.userCreated.userId).toBe(adminUser.userId); + }); + it('fails on duplicate name', async () => { + await CalendarService.createCalendar(adminUser, 'Cool Calendar', 'A very cool calendar', '#3498DB', organization); + await expect( + CalendarService.createCalendar( + adminUser, + 'Cool Calendar', + 'A very cool calendar, but not quite as cool', + '#0062a3ff', + organization + ) + ).rejects.toBeTruthy(); + }); + }); + }); }); From 03881ae29e8a186518c5b08aaa4050254e5bff37 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 4 Oct 2025 12:03:47 -0400 Subject: [PATCH 102/477] shop hook --- src/frontend/src/apis/calendar.api.ts | 20 +++++++++++++++++++ .../apis/transformers/calendar.transformer.ts | 16 +++++++++++++++ src/frontend/src/hooks/calendar.hooks.ts | 1 + src/frontend/src/utils/urls.ts | 11 ++++++++++ 4 files changed, 48 insertions(+) create mode 100644 src/frontend/src/apis/calendar.api.ts create mode 100644 src/frontend/src/apis/transformers/calendar.transformer.ts create mode 100644 src/frontend/src/hooks/calendar.hooks.ts diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts new file mode 100644 index 0000000000..42ead937b5 --- /dev/null +++ b/src/frontend/src/apis/calendar.api.ts @@ -0,0 +1,20 @@ + +import axios from '../utils/axios'; +import { apiUrls } from '../utils/urls'; +import { Shop } from 'shared'; +import { shopTransformer } from './transformers/calendar.transformer'; + +export const getShops = () => + axios.get(apiUrls.calendarShops(), { + transformResponse: (data) => JSON.parse(data).map(shopTransformer), + }); + +export const createShop = (payload: { name: string; description?: string }) => + axios.post(apiUrls.calendarCreateShop(), payload, { + transformResponse: (data) => shopTransformer(JSON.parse(data)), + }); + +export const deleteShop = (shopId: string) => + axios.delete(apiUrls.calendarDeleteShop(shopId), { + transformResponse: (data) => shopTransformer(JSON.parse(data)), + }); diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts new file mode 100644 index 0000000000..f8abdd5365 --- /dev/null +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -0,0 +1,16 @@ +import { Shop, User } from 'shared'; + +const userTransformer = (user: User): User => { + // Nothing to coerce on User right now + return { + ...user, + }; +}; + +export const shopTransformer = (shop: Shop): Shop => { + return { + ...shop, + dateCreated: new Date(shop.dateCreated), + userCreated: userTransformer(shop.userCreated), + }; +}; \ No newline at end of file diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts new file mode 100644 index 0000000000..f002600ba4 --- /dev/null +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -0,0 +1 @@ +import { useState, useContext } from 'react'; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 6cc32f0124..c6e5c849db 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -424,6 +424,12 @@ const retrospectiveTimelines = (startDate?: Date, endDate?: Date) => (endDate ? `end=${encodeURIComponent(endDate.toISOString())}` : ''); const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; +/**************** Calendar Endpoints ****************/ +const calendar = () => `${API_URL}/calendar`; +const calendarShops = () => `${calendar()}/shops`; +const calendarCreateShop = () => `${calendar()}/shop/create`; +const calendarDeleteShop = (shopId: string) => `${calendar()}/shop/${shopId}`; + /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -715,5 +721,10 @@ export const apiUrls = { retrospectiveTimelines, retrospectiveBudgets, + calendar, + calendarShops, + calendarCreateShop, + calendarDeleteShop, + version }; From 53e7047214e2ffa16762d1f789d472be7de1809f Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 4 Oct 2025 12:13:44 -0400 Subject: [PATCH 103/477] hook fully setup --- src/frontend/src/hooks/calendar.hooks.ts | 37 +++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index f002600ba4..be98df6dc1 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1 +1,36 @@ -import { useState, useContext } from 'react'; +import { useMutation, useQuery, useQueryClient } from 'react-query'; +import { Shop } from 'shared'; +import { getShops, createShop} from '../apis/calendar.api'; + +/** + * Get all shops for the current org + */ +export const useShops = () => { + return useQuery(['calendar', 'shops'], async () => { + const { data } = await getShops(); + return data; + }); +}; + +/** + * Create a shop + */ +type CreateShopPayload = { name: string; description: string }; + +export const useCreateShop = () => { + const queryClient = useQueryClient(); + + return useMutation( + ['calendar', 'shops', 'create'], + async ({ name, description }) => { + const { data } = await createShop({ name, description }); + return data; + }, + { + onSuccess: () => { + // refresh the table + queryClient.invalidateQueries(['calendar', 'shops']); + } + } + ); +}; From 067a83ab26ec024e9494a1f95dd33568c1b4e849 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 4 Oct 2025 13:51:02 -0400 Subject: [PATCH 104/477] admin tools + modal --- .../pages/AdminToolsPage/AdminToolsPage.tsx | 11 +- .../AdminToolsScheduleConfig.tsx | 139 ++++++++++++++++++ .../ScheduleConfig/CreateShopModal.tsx | 79 ++++++++++ 3 files changed, 226 insertions(+), 3 deletions(-) create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx diff --git a/src/frontend/src/pages/AdminToolsPage/AdminToolsPage.tsx b/src/frontend/src/pages/AdminToolsPage/AdminToolsPage.tsx index c3f8bcd4d4..a5b10bcb19 100644 --- a/src/frontend/src/pages/AdminToolsPage/AdminToolsPage.tsx +++ b/src/frontend/src/pages/AdminToolsPage/AdminToolsPage.tsx @@ -21,6 +21,7 @@ import AdminToolsRecruitmentConfig from './RecruitmentConfig/AdminToolsRecruitme import GuestViewConfig from './EditGuestView/GuestViewConfig'; import AdminToolsSlackIds from './AdminToolsSlackIds'; import AdminToolsOnboardingConfig from './OnboardingConfig/AdminToolsOnboardingConfig'; +import AdminToolsScheduleConfig from './ScheduleConfig/AdminToolsScheduleConfig'; const AdminToolsPage: React.FC = () => { const currentUser = useCurrentUser(); @@ -37,6 +38,7 @@ const AdminToolsPage: React.FC = () => { if (isUserHead || isUserAdmin) { tabs.push({ tabUrlValue: 'user-management', tabName: 'User Management' }); tabs.push({ tabUrlValue: 'project-configuration', tabName: 'Project Configuration' }); + tabs.push({ tabUrlValue: 'schedule', tabName: 'Schedule' }); } if (isUserAdmin || isUserFinanceLead) { tabs.push({ tabUrlValue: 'finance-configuration', tabName: 'Finance Configuration' }); @@ -75,12 +77,15 @@ const AdminToolsPage: React.FC = () => { {isUserAdmin && } ) : tabIndex === 2 ? ( + + + ) : tabIndex === 3 ? ( - ) : tabIndex === 3 ? ( - ) : tabIndex === 4 ? ( - + ) : tabIndex === 5 ? ( + + ) : tabIndex === 6 ? ( ) : ( diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx new file mode 100644 index 0000000000..7d63550937 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -0,0 +1,139 @@ +// src/layouts/pages/admintoolspage/AdminToolsScheduleConfig.tsx +import React, { useState } from 'react'; +import { + Box, + Grid, + Typography, + Paper, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Button +} from '@mui/material'; +import LoadingIndicator from '../../../components/LoadingIndicator'; +import ErrorPage from '../../ErrorPage'; +import { useShops, useCreateShop } from '../../../hooks/calendar.hooks'; +import CreateShopModal from './CreateShopModal'; + +const AdminToolsScheduleConfig: React.FC = () => { + const { data: shops, isLoading, isError, error } = useShops(); + const createShop = useCreateShop(); + + const [openCreate, setOpenCreate] = useState(false); + + if (isError) return ; + if (isLoading || !shops) return ; + + return ( + + {/* top page header*/} + + Schedule + + + + {/* Top-left (placeholder) */} + + + + Calendars + + + ... + + + + + {/* Top-right (placeholder) */} + + + + Event Types + + + ... + + + + + {/* Shops table */} + + + + Shops + + + + + + + Name + Description + + Actions + + + + + {shops.length === 0 ? ( + + + No shops yet. + + + ) : ( + shops.map((shop) => ( + + {shop.name} + + {shop.description ?? '—'} + + + + + + + + + )) + )} + +
+
+
+ + {/* Bottom-right (placeholder) */} + + + + Machinery + + + ... + + + +
+ + {/* Create Shop Modal */} + setOpenCreate(false)} + onSubmit={async ({ name, description }) => { + await createShop.mutateAsync({ name, description }); + setOpenCreate(false); + }} + /> +
+ ); +}; + +export default AdminToolsScheduleConfig; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx new file mode 100644 index 0000000000..4a7c80f093 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx @@ -0,0 +1,79 @@ +import { Box, FormControl, FormHelperText, Typography } from '@mui/material'; +import NERFormModal from '../../../components/NERFormModal'; +import ReactHookTextField from '../../../components/ReactHookTextField'; +import { useToast } from '../../../hooks/toasts.hooks'; +import { useForm } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; + +export interface CreateShopFormValues { + name: string; + description: string; +} + +const schema = yup.object({ + name: yup.string().required('Shop Name is required'), + description: yup.string().required('Description is required') +}); + +interface CreateShopModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: CreateShopFormValues) => Promise | unknown; +} + +export const CreateShopModal: React.FC = ({ open, onClose, onSubmit }) => { + const toast = useToast(); + + const { + handleSubmit, + control, + reset, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { name: '', description: '' } + }); + + const onFormSubmit = async (data: CreateShopFormValues) => { + try { + await onSubmit(data); // expects { name, description } + } catch (e: unknown) { + if (e instanceof Error) toast.error(e.message); + } + onClose(); + reset({ name: '', description: '' }); + }; + + return ( + reset({ name: '', description: '' })} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="create-shop-form" + showCloseButton + > + + + + Shop:* + + + {errors.name?.message} + + + + + Description:* + + + {errors.description?.message} + + + + ); +}; +export default CreateShopModal; \ No newline at end of file From 35ab27177b35fb43311e8132695c74a601e2fdfe Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 4 Oct 2025 13:54:45 -0400 Subject: [PATCH 105/477] prettier --- src/frontend/src/apis/calendar.api.ts | 7 +++---- .../apis/transformers/calendar.transformer.ts | 6 +++--- src/frontend/src/hooks/calendar.hooks.ts | 4 ++-- .../src/pages/AdminToolsPage/AdminToolsPage.tsx | 5 ++--- .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 17 ++--------------- .../ScheduleConfig/CreateShopModal.tsx | 2 +- src/frontend/src/utils/urls.ts | 10 +++++----- 7 files changed, 18 insertions(+), 33 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 42ead937b5..2922c761b7 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,4 +1,3 @@ - import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; import { Shop } from 'shared'; @@ -6,15 +5,15 @@ import { shopTransformer } from './transformers/calendar.transformer'; export const getShops = () => axios.get(apiUrls.calendarShops(), { - transformResponse: (data) => JSON.parse(data).map(shopTransformer), + transformResponse: (data) => JSON.parse(data).map(shopTransformer) }); export const createShop = (payload: { name: string; description?: string }) => axios.post(apiUrls.calendarCreateShop(), payload, { - transformResponse: (data) => shopTransformer(JSON.parse(data)), + transformResponse: (data) => shopTransformer(JSON.parse(data)) }); export const deleteShop = (shopId: string) => axios.delete(apiUrls.calendarDeleteShop(shopId), { - transformResponse: (data) => shopTransformer(JSON.parse(data)), + transformResponse: (data) => shopTransformer(JSON.parse(data)) }); diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts index f8abdd5365..ed712b590a 100644 --- a/src/frontend/src/apis/transformers/calendar.transformer.ts +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -3,7 +3,7 @@ import { Shop, User } from 'shared'; const userTransformer = (user: User): User => { // Nothing to coerce on User right now return { - ...user, + ...user }; }; @@ -11,6 +11,6 @@ export const shopTransformer = (shop: Shop): Shop => { return { ...shop, dateCreated: new Date(shop.dateCreated), - userCreated: userTransformer(shop.userCreated), + userCreated: userTransformer(shop.userCreated) }; -}; \ No newline at end of file +}; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index be98df6dc1..eca64b4eb1 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,6 +1,6 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; import { Shop } from 'shared'; -import { getShops, createShop} from '../apis/calendar.api'; +import { getShops, createShop } from '../apis/calendar.api'; /** * Get all shops for the current org @@ -13,7 +13,7 @@ export const useShops = () => { }; /** - * Create a shop + * Create a shop */ type CreateShopPayload = { name: string; description: string }; diff --git a/src/frontend/src/pages/AdminToolsPage/AdminToolsPage.tsx b/src/frontend/src/pages/AdminToolsPage/AdminToolsPage.tsx index a5b10bcb19..03a52f9e2f 100644 --- a/src/frontend/src/pages/AdminToolsPage/AdminToolsPage.tsx +++ b/src/frontend/src/pages/AdminToolsPage/AdminToolsPage.tsx @@ -77,9 +77,8 @@ const AdminToolsPage: React.FC = () => { {isUserAdmin && }
) : tabIndex === 2 ? ( - - - ) : tabIndex === 3 ? ( + + ) : tabIndex === 3 ? ( ) : tabIndex === 4 ? ( diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 7d63550937..eab2e82cae 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -1,17 +1,6 @@ // src/layouts/pages/admintoolspage/AdminToolsScheduleConfig.tsx import React, { useState } from 'react'; -import { - Box, - Grid, - Typography, - Paper, - Table, - TableBody, - TableCell, - TableHead, - TableRow, - Button -} from '@mui/material'; +import { Box, Grid, Typography, Paper, Table, TableBody, TableCell, TableHead, TableRow, Button } from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; import { useShops, useCreateShop } from '../../../hooks/calendar.hooks'; @@ -89,9 +78,7 @@ const AdminToolsScheduleConfig: React.FC = () => { shops.map((shop) => ( {shop.name} - - {shop.description ?? '—'} - + {shop.description ?? '—'} - + + + + + + + + + + + + + + + diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 686f9f272f..348d4a4439 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -433,7 +433,6 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; const calendarCreateShop = () => `${calendar()}/shop/create`; -const calendarDeleteShop = (shopId: string) => `${calendar()}/shop/${shopId}`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -730,10 +729,9 @@ export const apiUrls = { retrospectiveTimelines, retrospectiveBudgets, - calendar, calendarShops, calendarCreateShop, - calendarDeleteShop, + //calendarDeleteShop, version }; From 3e945fab5fc060f3aeeb0831d4a2f18ff9c52721 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 13 Oct 2025 14:19:21 -0400 Subject: [PATCH 116/477] #3633 prettier fix --- .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 16f8ad3a6e..c468303578 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -96,12 +96,7 @@ const AdminToolsScheduleConfig: React.FC = () => { - + From 3fd29b1b033f373905ddc9e67bb7f08c2cd86965 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Mon, 13 Oct 2025 14:54:28 -0400 Subject: [PATCH 117/477] #3553 unit tests --- src/backend/src/services/calendar.services.ts | 18 +- .../src/transformers/calendar.transformer.ts | 4 +- src/backend/tests/test-utils.ts | 2 + src/backend/tests/unit/calendar.test.ts | 219 +++++++++++++++++- src/shared/src/types/calendar-types.ts | 2 +- 5 files changed, 233 insertions(+), 12 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 75f2a3daa7..ee41a020b9 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -10,8 +10,7 @@ import { User, ScheduleSlotCreateArgs, AvailabilityCreateArgs, - Event, - DayOfWeek + Event } from 'shared'; import prisma from '../prisma/prisma'; import { @@ -214,8 +213,8 @@ export default class CalendarService { * @returns The created event. * * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. - * @throws NotFoundException If the given calendarIds are not found. - * @throws InvalidOrganizationException If the given calendarIds are not part of the same organization. + * @throws NotFoundException If the given event type is not found. + * @throws InvalidOrganizationException If the given event types are not part of the same organization. */ static async createEvent( submitter: User, @@ -236,8 +235,15 @@ export default class CalendarService { zoomLink?: string, description?: string ): Promise { - if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { - throw new AccessDeniedAdminOnlyException('create event'); + const foundEventType = await prisma.eventType.findUnique({ + where: { eventTypeId, organizationId: organization.organizationId } + }); + if (!foundEventType) throw new NotFoundException('Event Type', eventTypeId); + if (foundEventType.dateDeleted) throw new DeletedException('Event Type', eventTypeId); + + // Ensure the event belongs to the given organization + if (foundEventType.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Event Type'); } // Ensure each availability has a scheduleSettingsId diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 72c7acb6c9..dd0d34b0f8 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -92,8 +92,8 @@ export const eventTransformer = (event: Prisma.EventGetPayload): userCreated: userTransformer(event.userCreated), dateCreated: event.dateCreated, eventTypeId: event.eventTypeId, - people: event.members, - shops: event.shops, + people: event.members.map(userTransformer), + shops: event.shops.map(shopTransformer), machinery: event.machinery.map(machineryTransformer), workPackages: event.workPackages.map(workPackageTransformer), documentIds: event.documentIds, diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index fe431601d8..65b8188280 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -146,6 +146,7 @@ export const resetUsers = async () => { await prisma.wBS_Element_Template.deleteMany(); await prisma.user_Settings.deleteMany(); await prisma.session.deleteMany(); + await prisma.availability.deleteMany(); await prisma.user_Secure_Settings.deleteMany(); await prisma.schedule_Settings.deleteMany(); await prisma.role.deleteMany(); @@ -166,6 +167,7 @@ export const resetUsers = async () => { await prisma.account_Code.deleteMany(); await prisma.refund_Source.deleteMany(); await prisma.index_Code.deleteMany(); + await prisma.event.deleteMany(); await prisma.eventType.deleteMany(); await prisma.calendar.deleteMany(); await prisma.shopMachinery.deleteMany(); diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 3d28b3bf8e..e522da7b3b 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -10,7 +10,7 @@ import { import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; -import { EventType, Machinery, Shop } from 'shared'; +import { DayOfWeek, EventType, Machinery, Shop, ScheduleSlot, Availability } from 'shared'; describe('Calendar Tests', () => { let orgId: string; @@ -20,6 +20,7 @@ describe('Calendar Tests', () => { let shop: Shop; let machinery: Machinery; let shopId: string; + let eventType: EventType; beforeEach(async () => { organization = await createTestOrganization(); @@ -53,6 +54,25 @@ describe('Calendar Tests', () => { organization, 'Original description' ); + eventType = await CalendarService.createEventType( + adminUser, + 'Team Meeting', + [calendar.calendarId], + organization, + true, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true + ); }); afterEach(async () => { @@ -151,7 +171,7 @@ describe('Calendar Tests', () => { it('Succeeds and creates an event type', async () => { const result = await CalendarService.createEventType( await createTestUser(supermanAdmin, orgId), - 'Team Meeting', + 'Meeting', [], organization, true, @@ -169,7 +189,7 @@ describe('Calendar Tests', () => { true ); - expect(result.name).toEqual('Team Meeting'); + expect(result.name).toEqual('Meeting'); expect(result.initialDateScheduled).toBe(true); expect(result.recurring).toBe(false); expect(result.allDay).toBe(true); @@ -614,4 +634,197 @@ describe('Calendar Tests', () => { expect(result.description).toBe(false); }); }); + + describe('Create Event', () => { + let member: User; + let scheduleSettings: any; + + beforeEach(async () => { + member = await createTestUser(supermanAdmin, orgId); + scheduleSettings = await prisma.schedule_Settings.create({ + data: { + userId: member.userId, + personalGmail: '', + personalZoomLink: '' + } + }); + }); + + it('succeeds for admin with valid inputs', async () => { + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; + const availabilities = [ + { + availability: [9, 10], + dateSet: new Date('2025-10-13'), + scheduleSettingsId: scheduleSettings.scheduleSettingsId + } + ]; + + const result = await CalendarService.createEvent( + adminUser, + 'Team Sync', + eventType.eventTypeId, + organization, + [member.userId], + [shop.shopId], + [machinery.machineryId], + [], + [], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + + expect(result.title).toBe('Team Sync'); + expect(result.eventTypeId).toBe(eventType.eventTypeId); + expect(result.people).toHaveLength(1); + expect(result.people[0].userId).toBe(member.userId); + expect(result.shops).toHaveLength(1); + expect(result.shops[0].shopId).toBe(shop.shopId); + expect(result.machinery).toHaveLength(1); + expect(result.machinery[0].machineryId).toBe(machinery.machineryId); + expect(result.scheduledTimes).toHaveLength(1); + expect(result.scheduledTimes[0].days).toEqual(['MONDAY', 'TUESDAY']); + expect(result.availability).toHaveLength(1); + expect(result.availability[0].availability).toEqual([9, 10]); + expect(result.approved).toBe(true); + expect(result.approvedBy!.userId).toBe(adminUser.userId); + expect(result.questionDocument).toBe('https://example.com/questions.pdf'); + expect(result.location).toBe('Conference Room A'); + expect(result.zoomLink).toBe('https://zoom.us/j/123456789'); + expect(result.description).toBe('Weekly team synchronization meeting'); + }); + + it('fails if eventTypeId does not exist', async () => { + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; + const availabilities = [ + { + availability: [9, 10], + dateSet: new Date('2025-10-13'), + scheduleSettingsId: scheduleSettings.scheduleSettingsId + } + ]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Invalid Event Type', + 'non-existent-event-type-id', + organization, + [member.userId], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Event Type', 'non-existent-event-type-id')); + }); + + it('fails if organization is invalid', async () => { + const otherOrg = await prisma.organization.create({ + data: { + name: 'Other Org', + description: 'Different organization', + applicationLink: '', + userCreated: { connect: { userId: adminUser.userId } } + } + }); + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; + const availabilities = [ + { + availability: [9, 10], + dateSet: new Date('2025-10-13'), + scheduleSettingsId: scheduleSettings.scheduleSettingsId + } + ]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Wrong Org Event', + eventType.eventTypeId, + otherOrg, + [member.userId], + [shop.shopId], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Event Type', eventType.eventTypeId)); + }); + + it('succeeds with minimal inputs', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + const result = await CalendarService.createEvent( + adminUser, + 'Minimal Event', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ); + + expect(result.title).toBe('Minimal Event'); + expect(result.eventTypeId).toBe(eventType.eventTypeId); + expect(result.people).toHaveLength(0); + expect(result.shops).toHaveLength(0); + expect(result.machinery).toHaveLength(0); + expect(result.workPackages).toHaveLength(0); + expect(result.documentIds).toHaveLength(0); + expect(result.scheduledTimes).toHaveLength(0); + expect(result.availability).toHaveLength(0); + expect(result.approved).toBe(false); + expect(result.approvedBy).toBeUndefined(); + expect(result.questionDocument).toBeUndefined(); + expect(result.location).toBeUndefined(); + expect(result.zoomLink).toBeUndefined(); + expect(result.description).toBeUndefined(); + }); + }); }); diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 7f3b2e8800..b3a378819e 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -92,7 +92,7 @@ export interface Event { eventTypeId: string; approvedBy?: User; scheduledTimes: ScheduleSlot[]; - people?: User[]; + people: User[]; location?: string; zoomLink?: string; availability: Availability[]; From e2f7889e81ef97fe0f1469bd3cda7501d45d5be9 Mon Sep 17 00:00:00 2001 From: Lisa W Date: Mon, 13 Oct 2025 14:55:06 -0400 Subject: [PATCH 118/477] Added editCalendar endpoint --- .../src/controllers/calendar.controllers.ts | 20 ++++ src/backend/src/routes/calendar.routes.ts | 9 ++ src/backend/src/services/calendar.services.ts | 58 +++++++++++- src/backend/tests/unit/calendar.test.ts | 92 ++++++++++++++++++- 4 files changed, 174 insertions(+), 5 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index b11cae7571..18aeecf016 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -115,6 +115,26 @@ export default class CalendarController { } } + static async editCalendar(req: Request, res: Response, next: NextFunction) { + try { + const { calendarId } = req.params; + const { name, colorHexCode, description } = req.body; + + const updatedCalendar = await CalendarService.editCalendar( + req.currentUser, + calendarId, + name, + description, + colorHexCode, + req.organization + ); + + res.status(200).json(updatedCalendar); + } catch (error: unknown) { + next(error); + } + } + static async deleteCalendar(req: Request, res: Response, next: NextFunction) { try { const { calendarId } = req.params; diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 24f8422be2..5456026c68 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -56,6 +56,15 @@ calendarRouter.put( CalendarController.editMachinery ); +calendarRouter.put( + '/:calendarId/edit', + nonEmptyString(body('name')), + nonEmptyString(body('description')), + nonEmptyString(body('colorHexCode')), + validateInputs, + CalendarController.editCalendar +); + calendarRouter.post( '/shop/create', nonEmptyString(body('name')), diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 899e1bbbd9..98c3def40e 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -314,16 +314,66 @@ export default class CalendarService { return calendarTransformer(newCalendar); } + /** + * @param submitter The user submitting the request, who must be an admin. + * @param calendarId The id of the given calendar. + * @param name The name of the calendar. + * @param description The summary of what the calendar is used for. + * @param colorHexCode The color of the calendar. + * @param organization The organization for which the calendar is being edited. + * + * @returns The edited calendar. + * + * @throws NotFoundException If the given calendarId is not found. + * @throws InvalidOrganizationException If the given calendarId is not part of the same organization. + * @throws DeletedException If the calendar has already been deleted. + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + */ + static async editCalendar( + submitter: User, + calendarId: string, + name: string, + description: string, + colorHexCode: string, + organization: Organization + ): Promise { + const calendar = await prisma.calendar.findUnique({ + where: { calendarId } + }); + + if (!calendar) throw new NotFoundException('Calendar', calendarId); + if (calendar.dateDeleted) throw new DeletedException('Calendar', calendarId); + if (calendar.organizationId !== organization.organizationId) throw new InvalidOrganizationException('Calendar'); + + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); + + if (!hasPermission) { + throw new AccessDeniedException('Only admins can edit calendars'); + } + + const newCalendar = await prisma.calendar.update({ + where: { calendarId }, + data: { + name, + description, + colorHexCode + }, + ...getCalendarQueryArgs(organization.organizationId) + }); + + return calendarTransformer(newCalendar); + } + /** * Delete calendar in the database - * @param submitter The user submitting the request, who must be a head or above. + * @param submitter The user submitting the request, who must be an admin. * @param calendarId The id of the given calendar. * @param organization The organization for which the calendar is being deleted. * - * @returns The deleted calendar ID. + * @returns The deleted calendar. * - * @throws NotFoundException If the given calendarIds are not found. - * @throws InvalidOrganizationException If the given calendarIds are not part of the same organization. + * @throws NotFoundException If the given calendarId is not found. + * @throws InvalidOrganizationException If the given calendarId is not part of the same organization. * @throws DeletedException If the calendar has already been deleted. * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. */ diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 3d28b3bf8e..5074f12539 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -59,8 +59,98 @@ describe('Calendar Tests', () => { await resetUsers(); }); + describe('edit calendar', () => { + it('fails if user is not an admin', async () => { + const member = await createTestUser(wonderwomanGuest, orgId); + + const calendar = await prisma.calendar.create({ + data: { + name: 'Test Calendar', + description: 'Test', + colorHexCode: '#000000', + userCreatedId: member.userId, + organizationId: orgId + } + }); + + await expect( + CalendarService.editCalendar( + member, + calendar.calendarId, + 'Updated Name', + 'Updated Description', + '#FF0000', + organization + ) + ).rejects.toThrow(new AccessDeniedException('Only admins can edit calendars')); + }); + + it('succeeds for admin', async () => { + const calendar = await prisma.calendar.create({ + data: { + name: 'Original Calendar', + description: 'Original Description', + colorHexCode: '#00FF00', + userCreatedId: adminUser.userId, + organizationId: orgId + } + }); + + const result = await CalendarService.editCalendar( + adminUser, + calendar.calendarId, + 'Updated Calendar', + 'Updated Description', + '#0000FF', + organization + ); + + expect(result.calendarId).toBe(calendar.calendarId); + expect(result.name).toBe('Updated Calendar'); + expect(result.description).toBe('Updated Description'); + expect(result.color).toBe('#0000FF'); + }); + + it('fails if calendar not found', async () => { + await expect( + CalendarService.editCalendar( + adminUser, + 'non-existent-id', + 'Updated Name', + 'Updated Description', + '#FF0000', + organization + ) + ).rejects.toThrow(new NotFoundException('Calendar', 'non-existent-id')); + }); + + it('fails if calendar already deleted', async () => { + const calendar = await prisma.calendar.create({ + data: { + name: 'Already Deleted', + description: 'Test', + colorHexCode: '#0000FF', + userCreatedId: adminUser.userId, + organizationId: orgId, + dateDeleted: new Date() + } + }); + + await expect( + CalendarService.editCalendar( + adminUser, + calendar.calendarId, + 'Updated Name', + 'Updated Description', + '#FF0000', + organization + ) + ).rejects.toThrow(new DeletedException('Calendar', calendar.calendarId)); + }); + }); + describe('delete calendar', () => { - it('fails if user is not a head or admin', async () => { + it('fails if user is not an admin', async () => { const member = await createTestUser(wonderwomanGuest, orgId); const calendar = await prisma.calendar.create({ From f8a2ed7337ed3bbdfcaee57cd5eb0745ae02d347 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Mon, 13 Oct 2025 14:56:22 -0400 Subject: [PATCH 119/477] #3553 small tests fix --- src/backend/tests/unit/calendar.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index e522da7b3b..be995eadc4 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -650,7 +650,7 @@ describe('Calendar Tests', () => { }); }); - it('succeeds for admin with valid inputs', async () => { + it('succeeds with valid inputs', async () => { const scheduleSlots = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], From 8b4d9fde6826291dc2d74bd1ff0ce9ab9f0be483 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Mon, 13 Oct 2025 16:12:42 -0400 Subject: [PATCH 120/477] #3553 more testing and seed data --- .../src/controllers/calendar.controllers.ts | 12 +- src/backend/src/prisma/seed.ts | 143 +++++++- src/backend/src/routes/calendar.routes.ts | 6 +- src/backend/src/services/calendar.services.ts | 89 ++++- src/backend/src/utils/validation.utils.ts | 23 +- src/backend/tests/unit/calendar.test.ts | 328 ++++++++++++++++-- 6 files changed, 553 insertions(+), 48 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 9f53566f9f..ab92642452 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -194,10 +194,10 @@ export default class CalendarController { machineryIds, workPackageIds, documentIds, - scheduleSlots, - availabilities, + scheduleSlot, + availability, approved, - approveByUserId, + approvedByUserId, questionDocument, location, zoomLink, @@ -214,10 +214,10 @@ export default class CalendarController { machineryIds, workPackageIds, documentIds, - scheduleSlots, - availabilities, + scheduleSlot, + availability, approved, - approveByUserId, + approvedByUserId, questionDocument, location, zoomLink, diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 9c94319f57..eeb2e2fca5 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -22,6 +22,7 @@ import { dbSeedAllTeams } from './seed-data/teams.seed'; import ChangeRequestsService from '../services/change-requests.services'; import TeamsService from '../services/teams.services'; import { + DayOfWeek, DesignReviewStatus, MaterialStatus, RoleEnum, @@ -3082,7 +3083,7 @@ const performSeed: () => Promise = async () => { }); // Create machineries and assign to shops - await MachineryService.createMachinery( + const ironMachine = await MachineryService.createMachinery( thomasEmrax, 'Iron Man CNC Mill', advancedShop.shopId, @@ -3090,7 +3091,7 @@ const performSeed: () => Promise = async () => { ner, 'High-precision CNC milling operations' ); - await MachineryService.createMachinery( + const hammer = await MachineryService.createMachinery( thomasEmrax, 'Thor Hammer Lathe', advancedShop.shopId, @@ -3098,7 +3099,7 @@ const performSeed: () => Promise = async () => { ner, 'High-precision turning operations' ); - await MachineryService.createMachinery( + const printer = await MachineryService.createMachinery( thomasEmrax, 'Spider-Man 3D Printer', electronicsLab.shopId, @@ -3239,6 +3240,142 @@ const performSeed: () => Promise = async () => { false, true ); + + // Add these event creations after the event type creations in the seed script + await CalendarService.createEvent( + thomasEmrax, + 'Impact Attenuator Design Review', + meetingEventType.eventTypeId, + ner, + [joeShmoe.userId, joeBlow.userId, batman.userId], + [advancedShop.shopId], + [printer.machineryId, hammer.machineryId], + [workPackage1.id], + [], + [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date(), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-20T00:00:00.000Z'), + allDay: false + } + ], + [ + { + availability: [9, 10], + dateSet: new Date('2025-10-20T00:00:00.000Z') + } + ], + true, + batman.userId, + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'https://docs.google.com/document/d/1_example', + 'Review design specifications for the impact attenuator' + ); + + await CalendarService.createEvent( + batman, + 'Wiring Harness Installation Planning', + meetingEventType.eventTypeId, + ner, + [regina.userId, janis.userId, cady.userId], + [electronicsLab.shopId], + [printer.machineryId], + [workPackage3.id, workPackage4.id], + [], + [ + { + days: [DayOfWeek.WEDNESDAY], + startTime: new Date('2025-10-22T14:00:00.000Z'), + endTime: new Date('2025-10-22T15:30:00.000Z'), + recurrenceNumber: 2, + initialDateScheduled: new Date('2025-10-22T00:00:00.000Z'), + allDay: false + } + ], + [ + { + availability: [14, 15], + dateSet: new Date('2025-10-22T00:00:00.000Z') + } + ], + true, + thomasEmrax.userId, + 'Electronics Lab', + 'https://zoom.us/j/987654321', + 'https://docs.google.com/document/d/2_example', + 'Plan the installation process for the wiring harness' + ); + + await CalendarService.createEvent( + aang, + 'Appa Plush Design Brainstorm', + meetingEventType.eventTypeId, + ner, + [katara.userId, sokka.userId, toph.userId], + [], + [], + [workPackage5.id], + [], + [ + { + days: [DayOfWeek.FRIDAY], + startTime: new Date('2025-10-24T10:00:00.000Z'), + endTime: new Date('2025-10-24T11:00:00.000Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-24T00:00:00.000Z'), + allDay: false + } + ], + [ + { + availability: [10, 11], + dateSet: new Date('2025-10-24T00:00:00.000Z') + } + ], + true, + katara.userId, + 'Design Studio', + 'https://zoom.us/j/456789123', + 'https://docs.google.com/document/d/3_example', + 'Brainstorm design ideas for Appa plush prototypes' + ); + + await CalendarService.createEvent( + lexLuther, + 'Laser Cannon Prototype Review', + meetingEventType.eventTypeId, + ner, + [zatanna.userId, superman.userId, wonderwoman.userId], + [testingFacility.shopId], + [ironMachine.machineryId, hammer.machineryId], + [project3WP1.id], + [], + [ + { + days: [DayOfWeek.MONDAY], + startTime: new Date('2025-10-27T13:00:00.000Z'), + endTime: new Date('2025-10-27T14:30:00.000Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-27T00:00:00.000Z'), + allDay: false + } + ], + [ + { + availability: [13, 14], + dateSet: new Date('2025-10-27T00:00:00.000Z') + } + ], + true, + batman.userId, + 'Testing Facility', + 'https://zoom.us/j/789123456', + 'https://docs.google.com/document/d/4_example', + 'Review progress and test results for laser cannon prototype' + ); }; performSeed() diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 951264832a..ae98b9d821 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,6 +1,6 @@ import express from 'express'; import { body, param } from 'express-validator'; -import { intMinZero, isDate, nonEmptyString, validateInputs } from '../utils/validation.utils'; +import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek } from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; const calendarRouter = express.Router(); @@ -41,7 +41,7 @@ calendarRouter.post( nonEmptyString(body('title')), body('eventTypeId').isString(), body('approved').isBoolean(), - body('approveByUserId').optional().isString(), + body('approvedByUserId').optional().isString(), body('memberIds').isArray(), body('memberIds.*').isString(), body('location').optional().isString(), @@ -58,7 +58,7 @@ calendarRouter.post( body('description').optional().isString(), body('scheduleSlot').isArray(), body('scheduleSlot.*.daysOfWeek').isArray(), - body('scheduleSlot.*.daysOfWeek.*').isString(), + isDayOfWeek(body('scheduleSlot.*.daysOfWeek.*')), isDate(body('scheduleSlot.*.startTime')).optional(), isDate(body('scheduleSlot.*.endTime')).optional(), intMinZero(body('scheduleSlot.*.recurrenceNumber')), diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index ee41a020b9..f2f52d51f1 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -213,8 +213,8 @@ export default class CalendarService { * @returns The created event. * * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. - * @throws NotFoundException If the given event type is not found. - * @throws InvalidOrganizationException If the given event types are not part of the same organization. + * @throws NotFoundException If the given event type, member IDs, shop IDs, machinery IDs, work package IDs, document IDs, or approvedByUserId are not found. + * @throws InvalidOrganizationException If the given event type, members, shops, machinery, work packages, or approvedByUserId are not part of the same organization. */ static async createEvent( submitter: User, @@ -226,8 +226,8 @@ export default class CalendarService { machineryIds: string[], workPackageIds: string[], documentIds: string[], - scheduleSlots: ScheduleSlotCreateArgs[], - availabilities: AvailabilityCreateArgs[], + scheduleSlot: ScheduleSlotCreateArgs[], + availability: AvailabilityCreateArgs[], approved: boolean, approvedByUserId?: string, questionDocument?: string, @@ -235,22 +235,89 @@ export default class CalendarService { zoomLink?: string, description?: string ): Promise { + // Validate eventTypeId const foundEventType = await prisma.eventType.findUnique({ - where: { eventTypeId, organizationId: organization.organizationId } + where: { eventTypeId } }); if (!foundEventType) throw new NotFoundException('Event Type', eventTypeId); if (foundEventType.dateDeleted) throw new DeletedException('Event Type', eventTypeId); - - // Ensure the event belongs to the given organization if (foundEventType.organizationId !== organization.organizationId) { throw new InvalidOrganizationException('Event Type'); } + // Validate memberIds + if (memberIds.length > 0) { + const foundMembers = await prisma.user.findMany({ + where: { + userId: { in: memberIds }, + organizations: { some: { organizationId: organization.organizationId } } + } + }); + if (foundMembers.length !== memberIds.length) { + const missingIds = memberIds.filter((id) => !foundMembers.some((user) => user.userId === id)); + throw new NotFoundException('User', missingIds.join(', ')); + } + } + + // Validate shopIds + if (shopIds.length > 0) { + const foundShops = await prisma.shop.findMany({ + where: { + shopId: { in: shopIds }, + organizationId: organization.organizationId, + dateDeleted: null + } + }); + if (foundShops.length !== shopIds.length) { + const missingIds = shopIds.filter((id) => !foundShops.some((shop) => shop.shopId === id)); + throw new NotFoundException('Shop', missingIds.join(', ')); + } + } + + // Validate machineryIds + if (machineryIds.length > 0) { + const foundMachinery = await prisma.machinery.findMany({ + where: { + machineryId: { in: machineryIds }, + organizationId: organization.organizationId, + dateDeleted: null + } + }); + if (foundMachinery.length !== machineryIds.length) { + const missingIds = machineryIds.filter((id) => !foundMachinery.some((m) => m.machineryId === id)); + throw new NotFoundException('Machinery', missingIds.join(', ')); + } + } + + // Validate workPackageIds + if (workPackageIds.length > 0) { + const foundWorkPackages = await prisma.work_Package.findMany({ + where: { + workPackageId: { in: workPackageIds } + } + }); + if (foundWorkPackages.length !== workPackageIds.length) { + const missingIds = workPackageIds.filter((id) => !foundWorkPackages.some((wp) => wp.workPackageId === id)); + throw new NotFoundException('Work Package', missingIds.join(', ')); + } + } + + // Validate approvedByUserId + if (approvedByUserId) { + const foundApprovedByUser = await prisma.user.findUnique({ + where: { + userId: approvedByUserId, + organizations: { some: { organizationId: organization.organizationId } } + } + }); + if (!foundApprovedByUser) { + throw new NotFoundException('User', approvedByUserId); + } + } + // Ensure each availability has a scheduleSettingsId const availabilitiesWithScheduleSettings = await Promise.all( - availabilities.map(async (availability) => { - // For each availability, find or create the ScheduleSettings for the relevant user - // Assuming availabilities are tied to the submitter; adjust if tied to other users + availability.map(async (availability) => { let scheduleSettings = await prisma.schedule_Settings.findUnique({ where: { userId: submitter.userId } }); @@ -293,7 +360,7 @@ export default class CalendarService { }, documentIds, scheduledTimes: { - create: scheduleSlots.map((s) => ({ + create: scheduleSlot.map((s) => ({ days: s.days, startTime: s.startTime ?? null, endTime: s.endTime ?? null, diff --git a/src/backend/src/utils/validation.utils.ts b/src/backend/src/utils/validation.utils.ts index 3a11e4fb7c..8f23d173e4 100644 --- a/src/backend/src/utils/validation.utils.ts +++ b/src/backend/src/utils/validation.utils.ts @@ -1,4 +1,11 @@ -import { Design_Review_Status, Graph_Display_Type, Graph_Type, Measure, Special_Permission } from '@prisma/client'; +import { + DayOfWeek, + Design_Review_Status, + Graph_Display_Type, + Graph_Type, + Measure, + Special_Permission +} from '@prisma/client'; import { Request, Response } from 'express'; import { body, query, ValidationChain, validationResult } from 'express-validator'; import { MaterialStatus, TaskPriority, TaskStatus, WorkPackageStage, RoleEnum, WbsElementStatus } from 'shared'; @@ -164,6 +171,20 @@ export const isDesignReviewStatus = (validationObject: ValidationChain): Validat ]); }; +export const isDayOfWeek = (validationObject: ValidationChain): ValidationChain => { + return validationObject + .isString() + .isIn([ + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SATURDAY, + DayOfWeek.SUNDAY + ]); +}; + export const descriptionBulletsValidators = [ body('descriptionBullets').isArray(), nonEmptyString(body('descriptionBullets.*.detail')), diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index be995eadc4..39b0a0dd0b 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -10,7 +10,7 @@ import { import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; -import { DayOfWeek, EventType, Machinery, Shop, ScheduleSlot, Availability } from 'shared'; +import { Availability, DayOfWeek, EventType, Machinery, ScheduleSlot, Shop } from 'shared'; describe('Calendar Tests', () => { let orgId: string; @@ -637,20 +637,46 @@ describe('Calendar Tests', () => { describe('Create Event', () => { let member: User; - let scheduleSettings: any; + let otherOrg: Organization; + let otherOrgUser: User; + let otherOrgShop: Shop; + let otherOrgMachinery: Machinery; + let document: string; beforeEach(async () => { member = await createTestUser(supermanAdmin, orgId); - scheduleSettings = await prisma.schedule_Settings.create({ + + otherOrg = await prisma.organization.create({ data: { - userId: member.userId, - personalGmail: '', - personalZoomLink: '' + name: 'Other Org (calendar test)', + description: 'for cross-org negative case', + applicationLink: '', + userCreated: { connect: { userId: adminUser.userId } } } }); + otherOrgUser = await createTestUser(alfred, otherOrg.organizationId); + + // Create additional entities for testing + otherOrgShop = await CalendarService.createShop( + otherOrgUser, + 'Other Org Shop', + 'Shop in different organization', + otherOrg + ); + + otherOrgMachinery = await CalendarService.createMachinery( + otherOrgUser, + 'Other Org Machinery', + otherOrgShop.shopId, + 1, + otherOrg, + 'Machinery in different organization' + ); + + document = 'Test Document'; }); - it('succeeds with valid inputs', async () => { + it('succeeds for admin with valid inputs', async () => { const scheduleSlots = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -664,8 +690,7 @@ describe('Calendar Tests', () => { const availabilities = [ { availability: [9, 10], - dateSet: new Date('2025-10-13'), - scheduleSettingsId: scheduleSettings.scheduleSettingsId + dateSet: new Date('2025-10-13') } ]; @@ -678,7 +703,7 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [], + [document], scheduleSlots, availabilities, true, @@ -697,8 +722,10 @@ describe('Calendar Tests', () => { expect(result.shops[0].shopId).toBe(shop.shopId); expect(result.machinery).toHaveLength(1); expect(result.machinery[0].machineryId).toBe(machinery.machineryId); + expect(result.workPackages).toHaveLength(0); + expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); - expect(result.scheduledTimes[0].days).toEqual(['MONDAY', 'TUESDAY']); + expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); expect(result.availability).toHaveLength(1); expect(result.availability[0].availability).toEqual([9, 10]); expect(result.approved).toBe(true); @@ -723,8 +750,7 @@ describe('Calendar Tests', () => { const availabilities = [ { availability: [9, 10], - dateSet: new Date('2025-10-13'), - scheduleSettingsId: scheduleSettings.scheduleSettingsId + dateSet: new Date('2025-10-13') } ]; @@ -747,14 +773,6 @@ describe('Calendar Tests', () => { }); it('fails if organization is invalid', async () => { - const otherOrg = await prisma.organization.create({ - data: { - name: 'Other Org', - description: 'Different organization', - applicationLink: '', - userCreated: { connect: { userId: adminUser.userId } } - } - }); const scheduleSlots = [ { days: [DayOfWeek.MONDAY], @@ -768,8 +786,7 @@ describe('Calendar Tests', () => { const availabilities = [ { availability: [9, 10], - dateSet: new Date('2025-10-13'), - scheduleSettingsId: scheduleSettings.scheduleSettingsId + dateSet: new Date('2025-10-13') } ]; @@ -788,7 +805,7 @@ describe('Calendar Tests', () => { availabilities, false ) - ).rejects.toThrow(new NotFoundException('Event Type', eventType.eventTypeId)); + ).rejects.toThrow(new InvalidOrganizationException('Event Type')); }); it('succeeds with minimal inputs', async () => { @@ -826,5 +843,268 @@ describe('Calendar Tests', () => { expect(result.zoomLink).toBeUndefined(); expect(result.description).toBeUndefined(); }); + + it('fails if memberIds are invalid', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Invalid Members', + eventType.eventTypeId, + organization, + ['non-existent-user-id'], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); + }); + + it('fails if memberIds belong to a different organization', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Wrong Org Members', + eventType.eventTypeId, + organization, + [otherOrgUser.userId], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('User', otherOrgUser.userId)); + }); + + it('fails if shopIds are invalid', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Invalid Shops', + eventType.eventTypeId, + organization, + [], + ['non-existent-shop-id'], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Shop', 'non-existent-shop-id')); + }); + + it('fails if shopIds belong to a different organization', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Wrong Org Shops', + eventType.eventTypeId, + organization, + [], + [otherOrgShop.shopId], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Shop', otherOrgShop.shopId)); + }); + + it('fails if machineryIds are invalid', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Invalid Machinery', + eventType.eventTypeId, + organization, + [], + [], + ['non-existent-machinery-id'], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Machinery', 'non-existent-machinery-id')); + }); + + it('fails if machineryIds belong to a different organization', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Wrong Org Machinery', + eventType.eventTypeId, + organization, + [], + [], + [otherOrgMachinery.machineryId], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Machinery', otherOrgMachinery.machineryId)); + }); + + it('fails if workPackageIds are invalid', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Invalid Work Packages', + eventType.eventTypeId, + organization, + [], + [], + [], + ['non-existent-work-package-id'], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Work Package', 'non-existent-work-package-id')); + }); + + it('fails if approvedByUserId is invalid', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Invalid Approver', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + true, + 'non-existent-user-id' + ) + ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); + }); + + it('fails if approvedByUserId belongs to a different organization', async () => { + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Wrong Org Approver', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + true, + otherOrgUser.userId + ) + ).rejects.toThrow(new NotFoundException('User', otherOrgUser.userId)); + }); + + it('fails if shopIds are deleted', async () => { + const deletedShop = await CalendarService.createShop(adminUser, 'Deleted Shop', 'Deleted shop', organization); + await prisma.shop.update({ + where: { shopId: deletedShop.shopId }, + data: { dateDeleted: new Date() } + }); + + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Deleted Shops', + eventType.eventTypeId, + organization, + [], + [deletedShop.shopId], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Shop', deletedShop.shopId)); + }); + + it('fails if machineryIds are deleted', async () => { + const deletedMachinery = await CalendarService.createMachinery( + adminUser, + 'Deleted Machinery', + shop.shopId, + 1, + organization, + 'Deleted machinery' + ); + await prisma.machinery.update({ + where: { machineryId: deletedMachinery.machineryId }, + data: { dateDeleted: new Date() } + }); + + const scheduleSlots = [] as ScheduleSlot[]; + const availabilities = [] as Availability[]; + + await expect( + CalendarService.createEvent( + adminUser, + 'Deleted Machinery', + eventType.eventTypeId, + organization, + [], + [], + [deletedMachinery.machineryId], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); + }); }); }); From fe91ca17bf316f5cea4e4a1ca898828eea8a68ca Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 13 Oct 2025 17:06:35 -0400 Subject: [PATCH 121/477] #3633 Changes made deleted personal note comments --- .../src/apis/transformers/calendar.transformer.ts | 9 ++------- src/frontend/src/hooks/calendar.hooks.ts | 5 ++--- .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 14 ++++++-------- .../ScheduleConfig/CreateShopModal.tsx | 2 +- src/frontend/src/utils/urls.ts | 1 - 5 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts index ed712b590a..c4056195bc 100644 --- a/src/frontend/src/apis/transformers/calendar.transformer.ts +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -1,11 +1,6 @@ -import { Shop, User } from 'shared'; +import { Shop } from 'shared'; +import {userTransformer} from './users.transformers'; -const userTransformer = (user: User): User => { - // Nothing to coerce on User right now - return { - ...user - }; -}; export const shopTransformer = (shop: Shop): Shop => { return { diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 822dd6d70b..a1876b0c4b 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -2,16 +2,15 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; import { Shop } from 'shared'; import { getAllShops, postCreateShop } from '../apis/calendar.api'; -export const SHOPS_KEY = ['calendar', 'shops'] as const; +export const SHOPS_KEY = ['shops'] as const; + -/** Exactly like useGetAllAccountCodes */ export const useAllShops = () => useQuery(SHOPS_KEY, async () => { const { data } = await getAllShops(); return data; }); -/** Exactly like create/edit hooks in finance: mutate + invalidate */ export const useCreateShop = () => { const qc = useQueryClient(); return useMutation( diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index c468303578..ce22041453 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -1,4 +1,4 @@ -// src/layouts/pages/admintoolspage/AdminToolsScheduleConfig.tsx + import React, { useState } from 'react'; import { Box, Grid, Typography, Paper, Table, TableBody, TableCell, TableHead, TableRow, Button } from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; @@ -11,8 +11,6 @@ import DeleteIcon from '@mui/icons-material/Delete'; const AdminToolsScheduleConfig: React.FC = () => { const { data: shops, isLoading, isError, error } = useAllShops(); - if (shops) console.debug('Shops length:', shops.length, shops); - const { mutateAsync: createShopMutate } = useCreateShop(); const [openCreate, setOpenCreate] = useState(false); @@ -22,13 +20,13 @@ const AdminToolsScheduleConfig: React.FC = () => { return ( - {/* Page header */} + Schedule - {/* Top-left placeholder */} + @@ -40,7 +38,7 @@ const AdminToolsScheduleConfig: React.FC = () => { - {/* Top-right placeholder */} + @@ -52,7 +50,7 @@ const AdminToolsScheduleConfig: React.FC = () => { - {/* Shops table (bottom-left) */} + {/* Shops table */} @@ -111,7 +109,7 @@ const AdminToolsScheduleConfig: React.FC = () => { - {/* Bottom-right placeholder */} + diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx index 75147305cf..9db1607e01 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx @@ -37,7 +37,7 @@ export const CreateShopModal: React.FC = ({ open, onClose, const onFormSubmit = async (data: CreateShopFormValues) => { try { - await onSubmit(data); // expects { name, description } + await onSubmit(data); } catch (e: unknown) { if (e instanceof Error) toast.error(e.message); } diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 348d4a4439..f49941cf24 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -731,7 +731,6 @@ export const apiUrls = { calendarShops, calendarCreateShop, - //calendarDeleteShop, version }; From 4c895346acd77cf4728767f823760504d1257379 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 13 Oct 2025 17:31:34 -0400 Subject: [PATCH 122/477] #3633 prettier fix --- src/frontend/src/apis/transformers/calendar.transformer.ts | 3 +-- src/frontend/src/hooks/calendar.hooks.ts | 1 - .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 5 ----- .../pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx | 2 +- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts index c4056195bc..107d94ef25 100644 --- a/src/frontend/src/apis/transformers/calendar.transformer.ts +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -1,6 +1,5 @@ import { Shop } from 'shared'; -import {userTransformer} from './users.transformers'; - +import { userTransformer } from './users.transformers'; export const shopTransformer = (shop: Shop): Shop => { return { diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index a1876b0c4b..e028651dc7 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -4,7 +4,6 @@ import { getAllShops, postCreateShop } from '../apis/calendar.api'; export const SHOPS_KEY = ['shops'] as const; - export const useAllShops = () => useQuery(SHOPS_KEY, async () => { const { data } = await getAllShops(); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index ce22041453..0131ddce4b 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -1,4 +1,3 @@ - import React, { useState } from 'react'; import { Box, Grid, Typography, Paper, Table, TableBody, TableCell, TableHead, TableRow, Button } from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; @@ -20,13 +19,11 @@ const AdminToolsScheduleConfig: React.FC = () => { return ( - Schedule - @@ -38,7 +35,6 @@ const AdminToolsScheduleConfig: React.FC = () => { - @@ -109,7 +105,6 @@ const AdminToolsScheduleConfig: React.FC = () => { - diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx index 9db1607e01..bfb6849abd 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx @@ -37,7 +37,7 @@ export const CreateShopModal: React.FC = ({ open, onClose, const onFormSubmit = async (data: CreateShopFormValues) => { try { - await onSubmit(data); + await onSubmit(data); } catch (e: unknown) { if (e instanceof Error) toast.error(e.message); } From 01019f78aca7d58bc4e7f5229cafb1c471a9d358 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Fri, 17 Oct 2025 09:15:57 -0400 Subject: [PATCH 123/477] #3572 editShop start --- .../src/controllers/calendar.controllers.ts | 12 +++++ src/backend/src/routes/calendar.routes.ts | 8 +++ src/backend/src/services/calendar.services.ts | 28 ++++++++++ src/backend/tests/unit/calendar.test.ts | 53 +++++++++++++++++++ 4 files changed, 101 insertions(+) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 18aeecf016..118c2ef9ec 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -97,6 +97,18 @@ export default class CalendarController { } } + static async editShop(req: Request, res: Response, next: NextFunction) { + try { + const { shopId } = req.params; + const { name, description } = req.body; + + const updatedShop = await CalendarService.editShop(req.currentUser, shopId, name, description, req.organization); + res.status(200).json(updatedShop); + } catch (error: unknown) { + next(error); + } + } + static async createCalendar(req: Request, res: Response, next: NextFunction) { try { const { name, description, colorHexCode } = req.body; diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 5456026c68..887effbed6 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -73,6 +73,14 @@ calendarRouter.post( CalendarController.createShop ); +calendarRouter.put( + '/shop/edit/:shopId', + nonEmptyString(body('name')), + body('description').optional().isString(), + validateInputs, + CalendarController.editShop +); + calendarRouter.post( '/event-type/:eventTypeId/edit', body('calendarIds').isArray(), diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 98c3def40e..cfaebfb353 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -278,6 +278,34 @@ export default class CalendarService { return shopTransformer(newShop); } + static async editShop( + submitter: User, + shopId: string, + name: string, + description: string, + organization: Organization + ): Promise { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('create shop'); + } + + const existing = await prisma.shop.findUnique({ where: { shopId } }); + if (!existing) throw new NotFoundException('Shop', shopId); + if (existing.dateDeleted) throw new DeletedException('Shop', shopId); + if (existing.organizationId !== organization.organizationId) throw new InvalidOrganizationException('Shop'); + + const updatedShop = await prisma.shop.update({ + where: { shopId }, + data: { + name, + description + }, + ...getShopQueryArgs(organization.organizationId) + }); + + return shopTransformer(await updatedShop); + } + /** * @param submitter The user submitting the request, who must be an admin * @param name The name of the calendar diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 5074f12539..57c4814ccb 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -492,6 +492,59 @@ describe('Calendar Tests', () => { }); }); + describe('Shop: edit', () => { + it('fails if user is not admin', async () => { + const created = await CalendarService.createShop(adminUser, 'Shop A', 'Desc A', organization); + await expect( + CalendarService.editShop( + await createTestUser(wonderwomanGuest, orgId), + created.shopId, + 'New Name', + 'New Desc', + organization + ) + ).rejects.toBeInstanceOf(AccessDeniedAdminOnlyException); + }); + + it('succeeds for admin', async () => { + const created = await CalendarService.createShop(adminUser, 'Shop B', 'Desc B', organization); + const updated = await CalendarService.editShop( + adminUser, + created.shopId, + 'Updated Shop Name', + 'Updated Description', + organization + ); + expect(updated.shopId).toBe(created.shopId); + expect(updated.name).toBe('Updated Shop Name'); + expect(updated.description).toBe('Updated Description'); + expect(updated.userCreated.userId).toBe(created.userCreated.userId); + expect(updated.dateCreated).toBeTruthy(); + }); + + it('fails if shop does not exist', async () => { + await expect( + CalendarService.editShop(adminUser, 'non-existent-id', 'Name', 'Desc', organization) + ).rejects.toBeInstanceOf(NotFoundException); + }); + + it('fails if shop belongs to a different org', async () => { + const created = await CalendarService.createShop(adminUser, 'Shop C', 'Desc C', organization); + const otherOrg = await createTestOrganization(); // your existing helper + await expect(CalendarService.editShop(adminUser, created.shopId, 'X', 'Y', otherOrg)).rejects.toBeInstanceOf( + InvalidOrganizationException + ); + }); + + it('fails if shop is soft-deleted', async () => { + const created = await CalendarService.createShop(adminUser, 'Shop D', 'Desc D', organization); + await CalendarService.deleteShop(adminUser, created.shopId, organization); + await expect(CalendarService.editShop(adminUser, created.shopId, 'X', 'Y', organization)).rejects.toBeInstanceOf( + DeletedException + ); + }); + }); + describe('Main Calendar Tests', () => { describe('create calendar', () => { it('fails if user is not an admin', async () => { From 172f9f12f60d9a8dbc95b42ccbcd02bbf44e2801 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Fri, 17 Oct 2025 10:31:25 -0400 Subject: [PATCH 124/477] #3633 fix --- src/frontend/src/hooks/calendar.hooks.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index e028651dc7..84ae352f09 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -6,8 +6,8 @@ export const SHOPS_KEY = ['shops'] as const; export const useAllShops = () => useQuery(SHOPS_KEY, async () => { - const { data } = await getAllShops(); - return data; + const res = await getAllShops(); + return res.data; }); export const useCreateShop = () => { From 869101005f2d5731d5adc968e1428fd283d85293 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Fri, 17 Oct 2025 10:33:25 -0400 Subject: [PATCH 125/477] #3633 fix --- src/frontend/src/hooks/calendar.hooks.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 84ae352f09..c1e8734038 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -13,11 +13,14 @@ export const useAllShops = () => export const useCreateShop = () => { const qc = useQueryClient(); return useMutation( - (payload) => postCreateShop(payload).then((r) => r.data), + async (payload) => { + const { data } = await postCreateShop(payload); + return data; + }, { onSuccess: () => { qc.invalidateQueries(SHOPS_KEY); - } + }, } ); }; From e0d860268a8a3dd0038ee70be28f8d5f137ae322 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Fri, 17 Oct 2025 10:34:36 -0400 Subject: [PATCH 126/477] #3633 prettier --- src/frontend/src/hooks/calendar.hooks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index c1e8734038..49a28aee38 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -20,7 +20,7 @@ export const useCreateShop = () => { { onSuccess: () => { qc.invalidateQueries(SHOPS_KEY); - }, + } } ); }; From 2ce84eb4891d6ee853f9d86201b23da9d0ca92bf Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Fri, 17 Oct 2025 10:55:14 -0400 Subject: [PATCH 127/477] #3572 fix test --- src/backend/tests/unit/calendar.test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 57c4814ccb..edf0f53bd7 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -529,11 +529,12 @@ describe('Calendar Tests', () => { }); it('fails if shop belongs to a different org', async () => { - const created = await CalendarService.createShop(adminUser, 'Shop C', 'Desc C', organization); - const otherOrg = await createTestOrganization(); // your existing helper - await expect(CalendarService.editShop(adminUser, created.shopId, 'X', 'Y', otherOrg)).rejects.toBeInstanceOf( - InvalidOrganizationException - ); + // clone the real org but with a different ID + const otherOrganization: Organization = { ...organization, organizationId: 'some-other-org-id' }; + + await expect( + CalendarService.editShop(adminUser, shop.shopId, 'Updated Shop Name', 'Updated Description', otherOrganization) + ).rejects.toThrow(new InvalidOrganizationException('Shop')); }); it('fails if shop is soft-deleted', async () => { From 74e169dd05618c593f7bc2fe99854c72d9cbf242 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Fri, 17 Oct 2025 11:17:31 -0400 Subject: [PATCH 128/477] #3572 test fix --- src/backend/tests/unit/calendar.test.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index edf0f53bd7..539797f42c 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -528,15 +528,6 @@ describe('Calendar Tests', () => { ).rejects.toBeInstanceOf(NotFoundException); }); - it('fails if shop belongs to a different org', async () => { - // clone the real org but with a different ID - const otherOrganization: Organization = { ...organization, organizationId: 'some-other-org-id' }; - - await expect( - CalendarService.editShop(adminUser, shop.shopId, 'Updated Shop Name', 'Updated Description', otherOrganization) - ).rejects.toThrow(new InvalidOrganizationException('Shop')); - }); - it('fails if shop is soft-deleted', async () => { const created = await CalendarService.createShop(adminUser, 'Shop D', 'Desc D', organization); await CalendarService.deleteShop(adminUser, created.shopId, organization); From ea1e50a81d7f1a64894892ec2ab954ddfad6a5ad Mon Sep 17 00:00:00 2001 From: wavehassman Date: Fri, 17 Oct 2025 14:42:02 -0400 Subject: [PATCH 129/477] adding default to schema --- src/backend/src/prisma/schema.prisma | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index e5686d242c..da0c108153 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1041,7 +1041,7 @@ model Event { userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventDeleter") eventTypeId String eventType EventType @relation(fields: [eventTypeId], references: [eventTypeId]) - approved Boolean + approved Boolean @default(false) approvedByUserId String? approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") scheduledTimes ScheduleSlot[] From 90c0e564737ba76a1cdb6d40d9cbb350d1630d3b Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 19 Oct 2025 20:15:53 -0400 Subject: [PATCH 130/477] #3568 done --- .../src/controllers/calendar.controllers.ts | 12 +++ src/backend/src/prisma/seed.ts | 1 + src/backend/src/routes/calendar.routes.ts | 7 ++ src/backend/src/services/calendar.services.ts | 52 ++++++++++++- src/backend/tests/unit/calendar.test.ts | 77 +++++++++++++++++++ 5 files changed, 148 insertions(+), 1 deletion(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index f0c1ea91ee..b5f819d35b 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -257,4 +257,16 @@ export default class CalendarController { next(error); } } + + static async deleteMachinery(req: Request, res: Response, next: NextFunction) { + try { + const { machineryId } = req.params; + + const machinery = await CalendarService.deleteMachinery(req.currentUser, machineryId, req.organization); + + res.status(200).json(machinery); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index eeb2e2fca5..3ea5023a15 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3107,6 +3107,7 @@ const performSeed: () => Promise = async () => { ner, 'Rapid prototyping for electronics enclosures' ); + console.log(printer.machineryId); await MachineryService.createMachinery( thomasEmrax, 'Captain America Oscilloscope', diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 3fd4ac46b1..38582876b3 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -92,6 +92,13 @@ calendarRouter.put( CalendarController.editMachinery ); +calendarRouter.post( + '/machinery/:machineryId/delete', + nonEmptyString(param('machineryId')), + validateInputs, + CalendarController.deleteMachinery +); + calendarRouter.put( '/:calendarId/edit', nonEmptyString(body('name')), diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index dc9a54a654..dbbce7c473 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -10,7 +10,8 @@ import { User, ScheduleSlotCreateArgs, AvailabilityCreateArgs, - Event + Event, + Machinery } from 'shared'; import prisma from '../prisma/prisma'; import { @@ -776,4 +777,53 @@ export default class CalendarService { return shops.map(shopTransformer); } + + /** + * Deletes a machinery by its ID. + * Requires the submitter to be an admin. + * @param submitter The user submitting the request. + * @param machineryid The ID of the machinery to be deleted. + * @param organization The organization to which the machinery belongs. + * @returns The deleted machinery object. + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + * @throws NotFoundException If the machinery with the given ID does not exist. + * @throws InvalidOrganizationException If the machinery does not belong to the given organization. + * + */ + + static async deleteMachinery(submitter: User, machineryId: string, organization: Organization): Promise { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('delete machinery'); + } + + // Ensure the machinery exists + const existing = await prisma.machinery.findUnique({ where: { machineryId } }); + if (!existing) throw new NotFoundException('Machinery', machineryId); + + // Ensure it belongs to this org + if (existing.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Machinery'); + } + + // not already soft-deleted + if (existing.dateDeleted) { + throw new NotFoundException('Machinery', machineryId); + } + + // Soft delete machinery and remove shop mappings + await prisma.shopMachinery.deleteMany({ + where: { machineryId } + }); + + const deleted = await prisma.machinery.update({ + where: { machineryId }, + data: { + dateDeleted: new Date(), + userDeletedId: submitter.userId + }, + ...getMachineryQueryArgs(organization.organizationId) + }); + + return machineryTransformer(deleted); + } } diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 746597ac38..295d6a4915 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1197,4 +1197,81 @@ describe('Calendar Tests', () => { ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); }); }); + + describe('Delete Machinery', () => { + let machineryToDelete: Machinery; + let anotherShop: Shop; + + beforeEach(async () => { + machineryToDelete = await CalendarService.createMachinery( + adminUser, + 'Deletable Machinery', + shop.shopId, + 2, + organization, + 'Test description' + ); + + anotherShop = await CalendarService.createShop( + adminUser, + 'Secondary Shop', + 'Another shop for deletion test', + organization + ); + + await prisma.shopMachinery.create({ + data: { + shopId: anotherShop.shopId, + machineryId: machineryToDelete.machineryId, + quantity: 1, + description: 'Bridge row for deletion test' + } + }); + }); + + it('fails if user is not an admin', async () => { + const guest = await createTestUser(wonderwomanGuest, orgId); + await expect(CalendarService.deleteMachinery(guest, machineryToDelete.machineryId, organization)).rejects.toThrow( + new AccessDeniedAdminOnlyException('delete machinery') + ); + }); + + it('fails if machinery does not exist', async () => { + await expect(CalendarService.deleteMachinery(adminUser, 'non-existent-id', organization)).rejects.toThrow( + new NotFoundException('Machinery', 'non-existent-id') + ); + }); + + it('fails if machinery is already deleted', async () => { + await prisma.machinery.update({ + where: { machineryId: machineryToDelete.machineryId }, + data: { dateDeleted: new Date() } + }); + + await expect(CalendarService.deleteMachinery(adminUser, machineryToDelete.machineryId, organization)).rejects.toThrow( + new NotFoundException('Machinery', machineryToDelete.machineryId) + ); + }); + + it('succeeds for admin and soft deletes machinery and shopMachinery rows', async () => { + const bridgeBefore = await prisma.shopMachinery.count({ + where: { machineryId: machineryToDelete.machineryId } + }); + expect(bridgeBefore).toBeGreaterThan(0); + + const deleted = await CalendarService.deleteMachinery(adminUser, machineryToDelete.machineryId, organization); + + const row = await prisma.machinery.findUnique({ where: { machineryId: machineryToDelete.machineryId } }); + expect(row?.dateDeleted).not.toBeNull(); + expect(row?.userDeletedId).toBe(adminUser.userId); + + expect(deleted.machineryId).toBe(machineryToDelete.machineryId); + expect(deleted.name).toBe(machineryToDelete.name); + + const bridgeAfter = await prisma.shopMachinery.count({ + where: { machineryId: machineryToDelete.machineryId } + }); + expect(bridgeAfter).toBe(0); + }); + }); }); From 41125df102a0e752b1673de7046796fd12763b10 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 19 Oct 2025 22:21:50 -0400 Subject: [PATCH 131/477] dump a bunch of code in and see what happens --- .../src/controllers/calendar.controllers.ts | 95 +++++++++++++ .../migration.sql | 27 ++++ .../src/prisma/migrations/migration_lock.toml | 2 +- src/backend/src/prisma/schema.prisma | 1 + src/backend/src/routes/calendar.routes.ts | 41 +++++- src/backend/src/services/calendar.services.ts | 127 +++++++++++++++++- .../src/transformers/calendar.transformer.ts | 1 + src/backend/src/utils/calendar.utils.ts | 11 ++ src/backend/src/utils/errors.utils.ts | 1 + src/shared/src/types/calendar-types.ts | 11 ++ 10 files changed, 313 insertions(+), 4 deletions(-) create mode 100644 src/backend/src/prisma/migrations/20251019165324_calendar_update/migration.sql create mode 100644 src/backend/src/utils/calendar.utils.ts diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index f0c1ea91ee..dfb8d5094d 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -1,5 +1,6 @@ import { NextFunction, Request, Response } from 'express'; import CalendarService from '../services/calendar.services'; +import { matchedData } from 'express-validator'; export default class CalendarController { static async createEventType(req: Request, res: Response, next: NextFunction) { @@ -257,4 +258,98 @@ export default class CalendarController { next(error); } } + + static async getFilteredEvents(req: Request, res: Response, next: NextFunction) { + try { + const { filterArgs } = req.body; + const filteredEvents = await CalendarService.getFilteredEvents(req.currentUser, filterArgs, req.organization); + res.status(200).json(filteredEvents); + } catch (error: unknown) { + next(error); + } + } + + static async getAllEvents(req: Request, res: Response, next: NextFunction) { + try { + const events = await CalendarService.getFilteredEvents(req.currentUser, {}, req.organization); + res.status(200).json(events); + } catch (error: unknown) { + next(error); + } + } + + static async getSpecificEvent(req: Request, res: Response, next: NextFunction) { + try { + const { eventId } = req.params; + const filteredEvents = await CalendarService.getFilteredEvents( + req.currentUser, + { eventIds: [eventId] }, + req.organization + ); + res.status(200).json(filteredEvents); + } catch (error: unknown) { + next(error); + } + } + + static async getEventsFromCalendar(req: Request, res: Response, next: NextFunction) { + try { + const { calendarId } = req.params; + const events = await CalendarService.getFilteredEvents( + req.currentUser, + { calendarIds: [calendarId] }, + req.organization + ); + res.status(200).json(events); + } catch (error: unknown) { + next(error); + } + } + + static async getSpecificMembersEvents(req: Request, res: Response, next: NextFunction) { + try { + const { memberId } = req.params; + const events = await CalendarService.getFilteredEvents(req.currentUser, { memberIds: [memberId] }, req.organization); + res.status(200).json(events); + } catch (error: unknown) { + next(error); + } + } + + static async getUnapprovedEvents(req: Request, res: Response, next: NextFunction) { + try { + const filteredEvents = await CalendarService.getFilteredEvents( + req.currentUser, + { approvalStatus: false }, + req.organization + ); + res.status(200).json(filteredEvents); + } catch (error: unknown) { + next(error); + } + } + + static async getEventsFromTimeframe(req: Request, res: Response, next: NextFunction) { + try { + const { startPeriod, endPeriod } = matchedData(req, { + locations: ['query'], + onlyValidData: true + }); + + const events = await CalendarService.getFilteredEvents(req.currentUser, { startPeriod, endPeriod }, req.organization); + + res.status(200).json(events); + } catch (error: unknown) { + next(error); + } + } + + static async getAllCalendars(req: Request, res: Response, next: NextFunction) { + try { + const calendars = await CalendarService.getAllCalendars(req.organization); + res.status(200).json(calendars); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/prisma/migrations/20251019165324_calendar_update/migration.sql b/src/backend/src/prisma/migrations/20251019165324_calendar_update/migration.sql new file mode 100644 index 0000000000..e5976c74df --- /dev/null +++ b/src/backend/src/prisma/migrations/20251019165324_calendar_update/migration.sql @@ -0,0 +1,27 @@ +/* + Warnings: + + - Made the column `approved` on table `Event` required. This step will fail if there are existing NULL values in that column. + - Added the required column `endDate` to the `ScheduleSlot` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "public"."Event" ALTER COLUMN "approved" SET NOT NULL; + +-- AlterTable +ALTER TABLE "public"."EventType" ALTER COLUMN "initialDateScheduled" DROP DEFAULT, +ALTER COLUMN "allDay" DROP DEFAULT, +ALTER COLUMN "recurring" DROP DEFAULT, +ALTER COLUMN "members" DROP DEFAULT, +ALTER COLUMN "location" DROP DEFAULT, +ALTER COLUMN "zoomLink" DROP DEFAULT, +ALTER COLUMN "availabilities" DROP DEFAULT, +ALTER COLUMN "shop" DROP DEFAULT, +ALTER COLUMN "machinery" DROP DEFAULT, +ALTER COLUMN "workPackage" DROP DEFAULT, +ALTER COLUMN "questionDocument" DROP DEFAULT, +ALTER COLUMN "documents" DROP DEFAULT, +ALTER COLUMN "description" DROP DEFAULT; + +-- AlterTable +ALTER TABLE "public"."ScheduleSlot" ADD COLUMN "endDate" DATE NOT NULL; diff --git a/src/backend/src/prisma/migrations/migration_lock.toml b/src/backend/src/prisma/migrations/migration_lock.toml index 648c57fd59..044d57cdb0 100644 --- a/src/backend/src/prisma/migrations/migration_lock.toml +++ b/src/backend/src/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ # Please do not edit this file manually # It should be added in your version-control system (e.g., Git) -provider = "postgresql" \ No newline at end of file +provider = "postgresql" diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index da0c108153..76c09f65f1 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1026,6 +1026,7 @@ model ScheduleSlot { endTime DateTime? // time of day (just use a DateTime, ignore the date portion) recurrenceNumber Int initialDateScheduled DateTime @db.Date + endDate DateTime @db.Date allDay Boolean @default(false) ScheduledEvents Event[] } diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 3fd4ac46b1..42f29edf5b 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { body, param } from 'express-validator'; +import { body, param, query } from 'express-validator'; import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek } from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; @@ -122,7 +122,6 @@ calendarRouter.post( body('availabilities').isBoolean(), body('shop').isBoolean(), body('machinery').isBoolean(), - body('workPackage').isBoolean(), body('questionDocument').isBoolean(), body('documents').isBoolean(), body('description').isBoolean(), @@ -136,4 +135,42 @@ calendarRouter.post('/shop/:shopId/delete', nonEmptyString(param('shopId')), val calendarRouter.get('/shops', CalendarController.getAllShops); +calendarRouter.post( + '/events/filter', + body('filterArgs').optional(), + body('filterArgs.memberIds').optional().isArray(), + body('filterArgs.memberIds.*').optional().isString(), + body('filterArgs.calendarIds').isArray().optional(), + body('filterArgs.calendarIds.*').isString().optional(), + body('filterArgs.eventTypeIds').optional().isArray(), + body('filterArgs.eventTypeIds.*').optional().isString(), + body('filterArgs.eventIds').isArray().optional(), + body('filterArgs.eventIds.*').isString().optional(), + body('filterArgs.approvalStatus').isBoolean().optional(), + isDate(body('filterArgs.startPeriod')).optional(), + isDate(body('filterArgs.endPeriod')).optional(), + validateInputs, + CalendarController.getFilteredEvents +); + +calendarRouter.get('/events/member/:memberId', CalendarController.getSpecificMembersEvents); + +calendarRouter.get('/events', CalendarController.getAllEvents); + +calendarRouter.get('/events/:eventId', CalendarController.getSpecificEvent); + +calendarRouter.get('/events/unapproved', CalendarController.getUnapprovedEvents); + +calendarRouter.get('/events/calendar/:calendarId', CalendarController.getEventsFromCalendar); + +calendarRouter.get('/calendars', CalendarController.getAllCalendars); + +calendarRouter.get( + '/events/events/timeframe', + isDate(query('startPeriod')).optional(), + isDate(query('endPeriod')).optional(), + validateInputs, + CalendarController.getEventsFromTimeframe +); + export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index dc9a54a654..adca96bf9b 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -10,7 +10,8 @@ import { User, ScheduleSlotCreateArgs, AvailabilityCreateArgs, - Event + Event, + FilterArgs } from 'shared'; import prisma from '../prisma/prisma'; import { @@ -27,6 +28,7 @@ import { shopTransformer } from '../transformers/calendar.transformer'; import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; import { getCalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; import { getEventQueryArgs } from '../prisma-query-args/event.query-args'; +import { buildScheduledTimesOverlap } from '../utils/calendar.utils'; export default class CalendarService { /** @@ -340,6 +342,11 @@ export default class CalendarService { }) ); + const computeEndDate = (initial: Date, recurrenceNumber: number) => { + const weeks = Math.max(1, recurrenceNumber ?? 1); + return new Date(initial.getTime() + weeks * 7 * 24 * 60 * 60 * 1000); + }; + const newEvent = await prisma.event.create({ data: { userCreatedId: submitter.userId, @@ -366,6 +373,7 @@ export default class CalendarService { endTime: s.endTime ?? null, recurrenceNumber: s.recurrenceNumber, initialDateScheduled: s.initialDateScheduled, + endDate: computeEndDate(s.initialDateScheduled, s.recurrenceNumber), allDay: s.allDay })) }, @@ -765,6 +773,111 @@ export default class CalendarService { return shopTransformer(deleted); } + static async getFilteredEvents(requester: User, filters: FilterArgs, organization: Organization): Promise { + if (!(await userHasPermission(requester.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('delete shop'); + } + + const { memberIds, calendarIds, eventTypeIds, eventIds, approvalStatus, startPeriod, endPeriod } = filters; + + // validate memberIds + if (memberIds?.length) { + const foundMembers = await prisma.user.findMany({ + where: { + userId: { in: memberIds } + } + }); + if (foundMembers.length !== memberIds.length) { + const missingIds = memberIds.filter((id) => !foundMembers.some((mem) => mem.userId === id)); + throw new NotFoundException('User', missingIds.join(', ')); + } + } + + // validate calendarIds + if (calendarIds?.length) { + const foundcalendars = await prisma.calendar.findMany({ + where: { + calendarId: { in: calendarIds } + } + }); + if (foundcalendars.length !== calendarIds.length) { + const missingIds = calendarIds.filter((id) => !foundcalendars.some((mem) => mem.calendarId === id)); + throw new NotFoundException('Calendar', missingIds.join(', ')); + } + } + + // validate eventTypeIds + if (eventTypeIds?.length) { + const foundEventTypes = await prisma.eventType.findMany({ + where: { + eventTypeId: { in: eventTypeIds } + } + }); + if (foundEventTypes.length !== eventTypeIds.length) { + const missingIds = eventTypeIds.filter((id) => !foundEventTypes.some((et) => et.eventTypeId === id)); + throw new NotFoundException('Event Type', missingIds.join(', ')); + } + } + + // validate eventIds + if (eventIds?.length) { + const foundEvents = await prisma.event.findMany({ + where: { + eventId: { in: eventIds } + } + }); + if (foundEvents.length !== eventIds.length) { + const missingIds = eventIds.filter((id) => !foundEvents.some((et) => et.eventId === id)); + throw new NotFoundException('Event', missingIds.join(', ')); + } + } + + // filters for members + const memberOrCreator = memberIds?.length + ? { + OR: [ + { members: { some: { userId: { in: memberIds } } } }, // attendee + { userCreatedId: { in: memberIds } } // creator + ] + } + : undefined; + + // filters for selected calendars + const fromCalendar = calendarIds?.length + ? { + eventType: { + is: { + dateDeleted: null, + organizationId: organization.organizationId, + calendars: { + some: { + calendarId: { in: calendarIds }, + dateDeleted: null, + organizationId: organization.organizationId + } + } + } + } + } + : undefined; + + // get event using filter args + const events = await prisma.event.findMany({ + where: { + dateDeleted: null, + eventId: eventIds?.length ? { in: eventIds } : undefined, + eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, + approved: approvalStatus !== undefined ? { equals: approvalStatus } : undefined, + scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), + ...memberOrCreator, + ...fromCalendar + }, + ...getEventQueryArgs(organization.organizationId) + }); + + return events.map((event) => eventTransformer(event)); + } + static async getAllShops(organization: Organization): Promise { const shops = await prisma.shop.findMany({ where: { @@ -776,4 +889,16 @@ export default class CalendarService { return shops.map(shopTransformer); } + + static async getAllCalendars(organization: Organization): Promise { + const calendars = await prisma.calendar.findMany({ + where: { + organizationId: organization.organizationId, + dateDeleted: null + }, + ...getCalendarQueryArgs(organization.organizationId) + }); + + return calendars.map(calendarTransformer); + } } diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index dd0d34b0f8..5b2cea7020 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -81,6 +81,7 @@ export const scheduleTimesTransformer = (scheduleTimes: Prisma.ScheduleSlotGetPa endTime: scheduleTimes.endTime ?? undefined, recurrenceNumber: scheduleTimes.recurrenceNumber, initialDateScheduled: scheduleTimes.initialDateScheduled, + endDate: scheduleTimes.endDate, allDay: scheduleTimes.allDay }; }; diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts new file mode 100644 index 0000000000..a992ceeb37 --- /dev/null +++ b/src/backend/src/utils/calendar.utils.ts @@ -0,0 +1,11 @@ +import { Prisma } from '@prisma/client'; + +export function buildScheduledTimesOverlap(start?: Date, end?: Date): Prisma.ScheduleSlotListRelationFilter | undefined { + if (!start && !end) return undefined; + + const AND: Prisma.ScheduleSlotWhereInput[] = []; + if (end) AND.push({ initialDateScheduled: { lte: end } }); + if (start) AND.push({ endDate: { gte: start } }); + + return { some: { AND } }; +} diff --git a/src/backend/src/utils/errors.utils.ts b/src/backend/src/utils/errors.utils.ts index a0aa0ca8c8..acbe0fb14d 100644 --- a/src/backend/src/utils/errors.utils.ts +++ b/src/backend/src/utils/errors.utils.ts @@ -165,4 +165,5 @@ export type ExceptionObjectNames = | 'Encryption Key' | 'Reimbursement Request Comment' | 'Calendar' + | 'Event' | 'Event Type'; diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index b3a378819e..50066c5849 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -28,6 +28,7 @@ export interface ScheduleSlot { endTime?: Date; recurrenceNumber: number; initialDateScheduled: Date; + endDate: Date; allDay: boolean; } @@ -40,6 +41,16 @@ export interface ScheduleSlotCreateArgs { allDay: boolean; } +export interface FilterArgs { + memberIds?: string[]; + calendarIds?: string[]; + eventTypeIds?: string[]; + eventIds?: string[]; + approvalStatus?: boolean; + startPeriod?: Date; + endPeriod?: Date; +} + export interface EventType { eventTypeId: string; name: string; From 60ad0194c2082a0529f478649eaaaf8892ff9335 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Mon, 20 Oct 2025 12:23:48 -0400 Subject: [PATCH 132/477] #3568 small fix --- src/backend/src/prisma/seed.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 3ea5023a15..eeb2e2fca5 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3107,7 +3107,6 @@ const performSeed: () => Promise = async () => { ner, 'Rapid prototyping for electronics enclosures' ); - console.log(printer.machineryId); await MachineryService.createMachinery( thomasEmrax, 'Captain America Oscilloscope', From 1ff179ddbe1bc516f0f4a239a6b8b781f5033c2b Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 20 Oct 2025 12:59:11 -0400 Subject: [PATCH 133/477] #3572 Fixing Changes --- src/backend/src/routes/calendar.routes.ts | 4 ++-- src/backend/src/services/calendar.services.ts | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index d881c13924..fd94b781d0 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -104,7 +104,7 @@ calendarRouter.put( calendarRouter.post( '/shop/create', nonEmptyString(body('name')), - body('description').optional().isString(), + body('description').isString(), validateInputs, CalendarController.createShop ); @@ -112,7 +112,7 @@ calendarRouter.post( calendarRouter.put( '/shop/edit/:shopId', nonEmptyString(body('name')), - body('description').optional().isString(), + body('description').isString(), validateInputs, CalendarController.editShop ); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index ad6e117d5a..84f8f99009 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -487,6 +487,19 @@ export default class CalendarService { return shopTransformer(newShop); } + /** + * Edits an existing shop + * @param submitter The user submitting the request, who must be a admin. + * @param shopId The id of the shop to edit + * @param name The name of the shop + * @param description The description of the shop + * @param organization The organization for which the shop is being edited + * @returns Updated shop + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + * @throws NotFoundException If the shop with the given ID does not exist. + * @throws DeletedException If the shop has already been deleted. + * @throws InvalidOrganizationException If the shop does not belong to the given organization. + */ static async editShop( submitter: User, shopId: string, @@ -512,7 +525,7 @@ export default class CalendarService { ...getShopQueryArgs(organization.organizationId) }); - return shopTransformer(await updatedShop); + return shopTransformer(updatedShop); } /** From 6a7aec10a6fdb73c0c2a1895d84699bb8ad9c38b Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 20 Oct 2025 14:58:41 -0400 Subject: [PATCH 134/477] changing route --- src/backend/src/routes/calendar.routes.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index fd94b781d0..f1b0c69285 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -104,15 +104,15 @@ calendarRouter.put( calendarRouter.post( '/shop/create', nonEmptyString(body('name')), - body('description').isString(), + nonEmptyString(body('description')), validateInputs, CalendarController.createShop ); calendarRouter.put( - '/shop/edit/:shopId', + '/shop/:shopId/edit', nonEmptyString(body('name')), - body('description').isString(), + nonEmptyString(body('description')), validateInputs, CalendarController.editShop ); From 6377cd018abc9455113dfbd3374a4c6993cac9a3 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 20 Oct 2025 18:20:46 -0400 Subject: [PATCH 135/477] #3752 changing from put to post --- src/backend/src/routes/calendar.routes.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index f1b0c69285..f1acdee503 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -82,8 +82,8 @@ calendarRouter.post( CalendarController.createMachinery ); -calendarRouter.put( - '/machinery/edit/:machineryId', +calendarRouter.post( + '/machinery/:machineryId/edit', nonEmptyString(body('name')), nonEmptyString(body('shopId')), body('quantity').isInt({ min: 1 }), @@ -92,7 +92,7 @@ calendarRouter.put( CalendarController.editMachinery ); -calendarRouter.put( +calendarRouter.post( '/:calendarId/edit', nonEmptyString(body('name')), nonEmptyString(body('description')), @@ -109,7 +109,7 @@ calendarRouter.post( CalendarController.createShop ); -calendarRouter.put( +calendarRouter.post( '/shop/:shopId/edit', nonEmptyString(body('name')), nonEmptyString(body('description')), From ce18e6921370217fae8752a6542189ba7638aea8 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 01:32:51 -0400 Subject: [PATCH 136/477] little changes --- .../src/controllers/calendar.controllers.ts | 30 ++++++++++--- .../src/prisma-query-args/event.query-args.ts | 2 + src/backend/src/prisma/schema.prisma | 2 + src/backend/src/prisma/seed.ts | 4 ++ src/backend/src/routes/calendar.routes.ts | 45 ++++++++++++++----- src/backend/src/services/calendar.services.ts | 35 ++++++++++++++- .../src/transformers/calendar.transformer.ts | 2 + src/backend/tests/unit/calendar.test.ts | 15 +++++++ src/shared/src/types/calendar-types.ts | 3 ++ 9 files changed, 119 insertions(+), 19 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index dfb8d5094d..4c5284460d 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -220,6 +220,7 @@ export default class CalendarController { title, eventTypeId, memberIds, + teamIds, shopIds, machineryIds, workPackageIds, @@ -242,6 +243,7 @@ export default class CalendarController { memberIds, shopIds, machineryIds, + teamIds, workPackageIds, documentIds, scheduleSlot, @@ -259,6 +261,7 @@ export default class CalendarController { } } + //overall filtering for events static async getFilteredEvents(req: Request, res: Response, next: NextFunction) { try { const { filterArgs } = req.body; @@ -295,9 +298,12 @@ export default class CalendarController { static async getEventsFromCalendar(req: Request, res: Response, next: NextFunction) { try { const { calendarId } = req.params; + const { startPeriod, endPeriod } = req.query; + const parsedStartPeriod = typeof startPeriod === 'string' ? new Date(startPeriod) : undefined; + const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; const events = await CalendarService.getFilteredEvents( req.currentUser, - { calendarIds: [calendarId] }, + { calendarIds: [calendarId], startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, req.organization ); res.status(200).json(events); @@ -309,7 +315,14 @@ export default class CalendarController { static async getSpecificMembersEvents(req: Request, res: Response, next: NextFunction) { try { const { memberId } = req.params; - const events = await CalendarService.getFilteredEvents(req.currentUser, { memberIds: [memberId] }, req.organization); + const { startPeriod, endPeriod } = req.query; + const parsedStartPeriod = typeof startPeriod === 'string' ? new Date(startPeriod) : undefined; + const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; + const events = await CalendarService.getFilteredEvents( + req.currentUser, + { memberIds: [memberId], startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, + req.organization + ); res.status(200).json(events); } catch (error: unknown) { next(error); @@ -331,12 +344,15 @@ export default class CalendarController { static async getEventsFromTimeframe(req: Request, res: Response, next: NextFunction) { try { - const { startPeriod, endPeriod } = matchedData(req, { - locations: ['query'], - onlyValidData: true - }); + const { startPeriod, endPeriod } = req.query; + const parsedStartPeriod = typeof startPeriod === 'string' ? new Date(startPeriod) : undefined; + const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; - const events = await CalendarService.getFilteredEvents(req.currentUser, { startPeriod, endPeriod }, req.organization); + const events = await CalendarService.getFilteredEvents( + req.currentUser, + { startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, + req.organization + ); res.status(200).json(events); } catch (error: unknown) { diff --git a/src/backend/src/prisma-query-args/event.query-args.ts b/src/backend/src/prisma-query-args/event.query-args.ts index a063a71bc8..f66980c25a 100644 --- a/src/backend/src/prisma-query-args/event.query-args.ts +++ b/src/backend/src/prisma-query-args/event.query-args.ts @@ -3,6 +3,7 @@ import { getUserQueryArgs } from './user.query-args'; import { getShopQueryArgs } from './shop.query-args'; import { getMachineryQueryArgs } from './machinery.query-args'; import { getWorkPackageQueryArgs } from './work-packages.query-args'; +import { getTeamQueryArgs } from './teams.query-args'; export type EventQueryArgs = ReturnType; @@ -11,6 +12,7 @@ export const getEventQueryArgs = (organizationId: string) => include: { userCreated: getUserQueryArgs(organizationId), members: getUserQueryArgs(organizationId), + teams: getTeamQueryArgs(organizationId), shops: getShopQueryArgs(organizationId), machinery: getMachineryQueryArgs(organizationId), workPackages: getWorkPackageQueryArgs(organizationId), diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 76c09f65f1..aceec05df2 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -293,6 +293,7 @@ model Team { projects Project[] @relation(name: "assignedBy") members User[] @relation(name: "teamsAsMember") leads User[] @relation(name: "teamsAsLead") + events Event[] @relation(name: "affiliatedTeam") headId String head User @relation(name: "teamsAsHead", fields: [headId], references: [userId]) dateArchived DateTime? @@ -1047,6 +1048,7 @@ model Event { approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") scheduledTimes ScheduleSlot[] members User[] @relation(name: "eventAttender") + teams Team[] @relation(name: "affiliatedTeam") location String? zoomLink String? availabilities Availability[] diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index eeb2e2fca5..8b75e3478a 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3248,6 +3248,7 @@ const performSeed: () => Promise = async () => { meetingEventType.eventTypeId, ner, [joeShmoe.userId, joeBlow.userId, batman.userId], + [], [advancedShop.shopId], [printer.machineryId, hammer.machineryId], [workPackage1.id], @@ -3281,6 +3282,7 @@ const performSeed: () => Promise = async () => { meetingEventType.eventTypeId, ner, [regina.userId, janis.userId, cady.userId], + [], [electronicsLab.shopId], [printer.machineryId], [workPackage3.id, workPackage4.id], @@ -3315,6 +3317,7 @@ const performSeed: () => Promise = async () => { meetingEventType.eventTypeId, ner, [katara.userId, sokka.userId, toph.userId], + [justiceLeague.teamId], [], [], [workPackage5.id], @@ -3349,6 +3352,7 @@ const performSeed: () => Promise = async () => { meetingEventType.eventTypeId, ner, [zatanna.userId, superman.userId, wonderwoman.userId], + [orioles.teamId], [testingFacility.shopId], [ironMachine.machineryId, hammer.machineryId], [project3WP1.id], diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 42f29edf5b..f8731fa611 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -44,6 +44,8 @@ calendarRouter.post( body('approvedByUserId').optional().isString(), body('memberIds').isArray(), body('memberIds.*').isString(), + body('teamIds').isArray(), + body('teamIds.*').isString(), body('location').optional().isString(), body('zoomLink').optional().isURL(), body('shopIds').isArray(), @@ -135,11 +137,14 @@ calendarRouter.post('/shop/:shopId/delete', nonEmptyString(param('shopId')), val calendarRouter.get('/shops', CalendarController.getAllShops); +// no restrictions filtering, in case multiple filters need to be sent calendarRouter.post( '/events/filter', body('filterArgs').optional(), body('filterArgs.memberIds').optional().isArray(), body('filterArgs.memberIds.*').optional().isString(), + body('filterArgs.teamIds').optional().isArray(), + body('filterArgs.teamIds.*').optional().isString(), body('filterArgs.calendarIds').isArray().optional(), body('filterArgs.calendarIds.*').isString().optional(), body('filterArgs.eventTypeIds').optional().isArray(), @@ -153,24 +158,42 @@ calendarRouter.post( CalendarController.getFilteredEvents ); -calendarRouter.get('/events/member/:memberId', CalendarController.getSpecificMembersEvents); +// Example get queries using the base filter service, in case it's easier to use these -calendarRouter.get('/events', CalendarController.getAllEvents); - -calendarRouter.get('/events/:eventId', CalendarController.getSpecificEvent); - -calendarRouter.get('/events/unapproved', CalendarController.getUnapprovedEvents); +// filter via specific ID +calendarRouter.get( + '/events/member/:memberId', + nonEmptyString(query('startPeriod')).optional(), + nonEmptyString(query('endPeriod')).optional(), + validateInputs, + CalendarController.getSpecificMembersEvents +); -calendarRouter.get('/events/calendar/:calendarId', CalendarController.getEventsFromCalendar); +calendarRouter.get( + '/events/calendar/:calendarId', + nonEmptyString(query('startPeriod')).optional(), + nonEmptyString(query('endPeriod')).optional(), + validateInputs, + CalendarController.getEventsFromCalendar +); -calendarRouter.get('/calendars', CalendarController.getAllCalendars); +calendarRouter.get('/events/event/:eventId', CalendarController.getSpecificEvent); +// filter just based on time calendarRouter.get( - '/events/events/timeframe', - isDate(query('startPeriod')).optional(), - isDate(query('endPeriod')).optional(), + '/events/timeframe', + nonEmptyString(query('startPeriod')).optional(), + nonEmptyString(query('endPeriod')).optional(), validateInputs, CalendarController.getEventsFromTimeframe ); +// unfiltered +calendarRouter.get('/events', CalendarController.getAllEvents); + +// filtered by approval +calendarRouter.get('/events/unapproved', CalendarController.getUnapprovedEvents); + +calendarRouter.get('/calendars', CalendarController.getAllCalendars); + export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index adca96bf9b..5e04613b44 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -224,6 +224,7 @@ export default class CalendarService { eventTypeId: string, organization: Organization, memberIds: string[], + teamIds: string[], shopIds: string[], machineryIds: string[], workPackageIds: string[], @@ -261,6 +262,20 @@ export default class CalendarService { } } + // Validate teamIds + if (teamIds.length > 0) { + const foundteams = await prisma.team.findMany({ + where: { + teamId: { in: teamIds }, + organization: { organizationId: organization.organizationId } + } + }); + if (foundteams.length !== teamIds.length) { + const missingIds = teamIds.filter((id) => !foundteams.some((team) => team.teamId === id)); + throw new NotFoundException('Team', missingIds.join(', ')); + } + } + // Validate shopIds if (shopIds.length > 0) { const foundShops = await prisma.shop.findMany({ @@ -356,6 +371,9 @@ export default class CalendarService { members: { connect: memberIds.map((userId) => ({ userId })) }, + teams: { + connect: teamIds.map((teamId) => ({ teamId })) + }, shops: { connect: shopIds.map((shopId) => ({ shopId })) }, @@ -778,7 +796,7 @@ export default class CalendarService { throw new AccessDeniedAdminOnlyException('delete shop'); } - const { memberIds, calendarIds, eventTypeIds, eventIds, approvalStatus, startPeriod, endPeriod } = filters; + const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvalStatus, startPeriod, endPeriod } = filters; // validate memberIds if (memberIds?.length) { @@ -793,6 +811,20 @@ export default class CalendarService { } } + // validate teamIds + if (teamIds?.length) { + const foundteams = await prisma.team.findMany({ + where: { + teamId: { in: teamIds }, + organization: { organizationId: organization.organizationId } + } + }); + if (foundteams.length !== teamIds.length) { + const missingIds = teamIds.filter((id) => !foundteams.some((team) => team.teamId === id)); + throw new NotFoundException('Team', missingIds.join(', ')); + } + } + // validate calendarIds if (calendarIds?.length) { const foundcalendars = await prisma.calendar.findMany({ @@ -867,6 +899,7 @@ export default class CalendarService { dateDeleted: null, eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, + teams: { some: { teamId: { in: teamIds } } }, approved: approvalStatus !== undefined ? { equals: approvalStatus } : undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...memberOrCreator, diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 5b2cea7020..63aa5bc3b1 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -7,6 +7,7 @@ import { CalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; import { EventQueryArgs } from '../prisma-query-args/event.query-args'; import { ShopQueryArgs } from '../prisma-query-args/shop.query-args'; import workPackageTransformer from './work-packages.transformer'; +import teamTransformer from './teams.transformer'; export const shopTransformer = (shop: Prisma.ShopGetPayload): Shop => { return { @@ -94,6 +95,7 @@ export const eventTransformer = (event: Prisma.EventGetPayload): dateCreated: event.dateCreated, eventTypeId: event.eventTypeId, people: event.members.map(userTransformer), + teams: event.teams.map(teamTransformer), shops: event.shops.map(shopTransformer), machinery: event.machinery.map(machineryTransformer), workPackages: event.workPackages.map(workPackageTransformer), diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 746597ac38..78f0433384 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -790,6 +790,7 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [member.userId], + [], [shop.shopId], [machinery.machineryId], [], @@ -855,6 +856,7 @@ describe('Calendar Tests', () => { [], [], [], + [], scheduleSlots, availabilities, false @@ -887,6 +889,7 @@ describe('Calendar Tests', () => { eventType.eventTypeId, otherOrg, [member.userId], + [], [shop.shopId], [], [], @@ -912,6 +915,7 @@ describe('Calendar Tests', () => { [], [], [], + [], scheduleSlots, availabilities, false @@ -949,6 +953,7 @@ describe('Calendar Tests', () => { [], [], [], + [], scheduleSlots, availabilities, false @@ -971,6 +976,7 @@ describe('Calendar Tests', () => { [], [], [], + [], scheduleSlots, availabilities, false @@ -989,6 +995,7 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [], + [], ['non-existent-shop-id'], [], [], @@ -1011,6 +1018,7 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [], + [], [otherOrgShop.shopId], [], [], @@ -1034,6 +1042,7 @@ describe('Calendar Tests', () => { organization, [], [], + [], ['non-existent-machinery-id'], [], [], @@ -1056,6 +1065,7 @@ describe('Calendar Tests', () => { organization, [], [], + [], [otherOrgMachinery.machineryId], [], [], @@ -1079,6 +1089,7 @@ describe('Calendar Tests', () => { [], [], [], + [], ['non-existent-work-package-id'], [], scheduleSlots, @@ -1103,6 +1114,7 @@ describe('Calendar Tests', () => { [], [], [], + [], scheduleSlots, availabilities, true, @@ -1126,6 +1138,7 @@ describe('Calendar Tests', () => { [], [], [], + [], scheduleSlots, availabilities, true, @@ -1151,6 +1164,7 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [], + [], [deletedShop.shopId], [], [], @@ -1187,6 +1201,7 @@ describe('Calendar Tests', () => { organization, [], [], + [], [deletedMachinery.machineryId], [], [], diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 50066c5849..e14a4b1dde 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -1,4 +1,5 @@ import { WorkPackage } from './project-types'; +import { Team } from './team-types'; import { Availability, User } from './user-types'; export interface Calendar { @@ -43,6 +44,7 @@ export interface ScheduleSlotCreateArgs { export interface FilterArgs { memberIds?: string[]; + teamIds?: string[]; calendarIds?: string[]; eventTypeIds?: string[]; eventIds?: string[]; @@ -104,6 +106,7 @@ export interface Event { approvedBy?: User; scheduledTimes: ScheduleSlot[]; people: User[]; + teams: Team[]; location?: string; zoomLink?: string; availability: Availability[]; From a20eb009fc125e4946797571c88b29472592f4f1 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 01:34:48 -0400 Subject: [PATCH 137/477] index --- src/backend/src/prisma/schema.prisma | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index aceec05df2..2cbc254ae1 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1030,6 +1030,8 @@ model ScheduleSlot { endDate DateTime @db.Date allDay Boolean @default(false) ScheduledEvents Event[] + + @@index([initialDateScheduled, endDate]) } model Event { From 223a648e2ca0e7c13c19a1fde749221268a6f85f Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 21 Oct 2025 11:15:00 -0400 Subject: [PATCH 138/477] #3568 fixed route and service has transaction --- src/backend/src/routes/calendar.routes.ts | 7 +----- src/backend/src/services/calendar.services.ts | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 38582876b3..cd8a99e6f3 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -92,12 +92,7 @@ calendarRouter.put( CalendarController.editMachinery ); -calendarRouter.post( - '/machinery/:machineryId/delete', - nonEmptyString(param('machineryId')), - validateInputs, - CalendarController.deleteMachinery -); +calendarRouter.post('/machinery/:machineryId/delete', validateInputs, CalendarController.deleteMachinery); calendarRouter.put( '/:calendarId/edit', diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index dbbce7c473..cc8840c238 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -810,18 +810,20 @@ export default class CalendarService { throw new NotFoundException('Machinery', machineryId); } - // Soft delete machinery and remove shop mappings - await prisma.shopMachinery.deleteMany({ - where: { machineryId } - }); + // Soft delete machinery and remove shop mappings in a transaction + const deleted = await prisma.$transaction(async (tx) => { + await tx.shopMachinery.deleteMany({ + where: { machineryId } + }); - const deleted = await prisma.machinery.update({ - where: { machineryId }, - data: { - dateDeleted: new Date(), - userDeletedId: submitter.userId - }, - ...getMachineryQueryArgs(organization.organizationId) + return await tx.machinery.update({ + where: { machineryId }, + data: { + dateDeleted: new Date(), + userDeletedId: submitter.userId + }, + ...getMachineryQueryArgs(organization.organizationId) + }); }); return machineryTransformer(deleted); From 2d2d7acefda9dc53c2e111445d73953ce116c760 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 18:40:49 -0400 Subject: [PATCH 139/477] minor update --- .../src/controllers/calendar.controllers.ts | 19 ++++----------- src/backend/src/services/calendar.services.ts | 23 +++++++++---------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 4c5284460d..fdf3860166 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -265,7 +265,7 @@ export default class CalendarController { static async getFilteredEvents(req: Request, res: Response, next: NextFunction) { try { const { filterArgs } = req.body; - const filteredEvents = await CalendarService.getFilteredEvents(req.currentUser, filterArgs, req.organization); + const filteredEvents = await CalendarService.getFilteredEvents(filterArgs, req.organization); res.status(200).json(filteredEvents); } catch (error: unknown) { next(error); @@ -274,7 +274,7 @@ export default class CalendarController { static async getAllEvents(req: Request, res: Response, next: NextFunction) { try { - const events = await CalendarService.getFilteredEvents(req.currentUser, {}, req.organization); + const events = await CalendarService.getFilteredEvents({}, req.organization); res.status(200).json(events); } catch (error: unknown) { next(error); @@ -284,11 +284,7 @@ export default class CalendarController { static async getSpecificEvent(req: Request, res: Response, next: NextFunction) { try { const { eventId } = req.params; - const filteredEvents = await CalendarService.getFilteredEvents( - req.currentUser, - { eventIds: [eventId] }, - req.organization - ); + const filteredEvents = await CalendarService.getFilteredEvents({ eventIds: [eventId] }, req.organization); res.status(200).json(filteredEvents); } catch (error: unknown) { next(error); @@ -302,7 +298,6 @@ export default class CalendarController { const parsedStartPeriod = typeof startPeriod === 'string' ? new Date(startPeriod) : undefined; const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; const events = await CalendarService.getFilteredEvents( - req.currentUser, { calendarIds: [calendarId], startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, req.organization ); @@ -319,7 +314,6 @@ export default class CalendarController { const parsedStartPeriod = typeof startPeriod === 'string' ? new Date(startPeriod) : undefined; const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; const events = await CalendarService.getFilteredEvents( - req.currentUser, { memberIds: [memberId], startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, req.organization ); @@ -331,11 +325,7 @@ export default class CalendarController { static async getUnapprovedEvents(req: Request, res: Response, next: NextFunction) { try { - const filteredEvents = await CalendarService.getFilteredEvents( - req.currentUser, - { approvalStatus: false }, - req.organization - ); + const filteredEvents = await CalendarService.getFilteredEvents({ approvalStatus: false }, req.organization); res.status(200).json(filteredEvents); } catch (error: unknown) { next(error); @@ -349,7 +339,6 @@ export default class CalendarController { const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; const events = await CalendarService.getFilteredEvents( - req.currentUser, { startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, req.organization ); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 5e04613b44..37207677a8 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -791,18 +791,15 @@ export default class CalendarService { return shopTransformer(deleted); } - static async getFilteredEvents(requester: User, filters: FilterArgs, organization: Organization): Promise { - if (!(await userHasPermission(requester.userId, organization.organizationId, isAdmin))) { - throw new AccessDeniedAdminOnlyException('delete shop'); - } - + static async getFilteredEvents(filters: FilterArgs, organization: Organization): Promise { const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvalStatus, startPeriod, endPeriod } = filters; // validate memberIds if (memberIds?.length) { const foundMembers = await prisma.user.findMany({ where: { - userId: { in: memberIds } + userId: { in: memberIds }, + organizations: { some: { organizationId: organization.organizationId } } } }); if (foundMembers.length !== memberIds.length) { @@ -829,7 +826,9 @@ export default class CalendarService { if (calendarIds?.length) { const foundcalendars = await prisma.calendar.findMany({ where: { - calendarId: { in: calendarIds } + calendarId: { in: calendarIds }, + organization: { organizationId: organization.organizationId }, + dateDeleted: null } }); if (foundcalendars.length !== calendarIds.length) { @@ -842,7 +841,9 @@ export default class CalendarService { if (eventTypeIds?.length) { const foundEventTypes = await prisma.eventType.findMany({ where: { - eventTypeId: { in: eventTypeIds } + eventTypeId: { in: eventTypeIds }, + organization: { organizationId: organization.organizationId }, + dateDeleted: null } }); if (foundEventTypes.length !== eventTypeIds.length) { @@ -855,7 +856,8 @@ export default class CalendarService { if (eventIds?.length) { const foundEvents = await prisma.event.findMany({ where: { - eventId: { in: eventIds } + eventId: { in: eventIds }, + dateDeleted: null } }); if (foundEvents.length !== eventIds.length) { @@ -879,12 +881,10 @@ export default class CalendarService { ? { eventType: { is: { - dateDeleted: null, organizationId: organization.organizationId, calendars: { some: { calendarId: { in: calendarIds }, - dateDeleted: null, organizationId: organization.organizationId } } @@ -896,7 +896,6 @@ export default class CalendarService { // get event using filter args const events = await prisma.event.findMany({ where: { - dateDeleted: null, eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, teams: { some: { teamId: { in: teamIds } } }, From 514b9006ef9042e073d378ad67a63e659a9219fd Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 21:06:35 -0400 Subject: [PATCH 140/477] tests part 1/? --- .../src/controllers/calendar.controllers.ts | 1 - .../migration.sql | 27 ------ .../migration.sql | 93 +++++++++++------- src/backend/tests/unit/calendar.test.ts | 97 +++++++++++++++++++ 4 files changed, 154 insertions(+), 64 deletions(-) delete mode 100644 src/backend/src/prisma/migrations/20251019165324_calendar_update/migration.sql rename src/backend/src/prisma/migrations/{20250904214316_calendar => 20251022010413_calendar}/migration.sql (80%) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index fdf3860166..e2c2d88822 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -1,6 +1,5 @@ import { NextFunction, Request, Response } from 'express'; import CalendarService from '../services/calendar.services'; -import { matchedData } from 'express-validator'; export default class CalendarController { static async createEventType(req: Request, res: Response, next: NextFunction) { diff --git a/src/backend/src/prisma/migrations/20251019165324_calendar_update/migration.sql b/src/backend/src/prisma/migrations/20251019165324_calendar_update/migration.sql deleted file mode 100644 index e5976c74df..0000000000 --- a/src/backend/src/prisma/migrations/20251019165324_calendar_update/migration.sql +++ /dev/null @@ -1,27 +0,0 @@ -/* - Warnings: - - - Made the column `approved` on table `Event` required. This step will fail if there are existing NULL values in that column. - - Added the required column `endDate` to the `ScheduleSlot` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "public"."Event" ALTER COLUMN "approved" SET NOT NULL; - --- AlterTable -ALTER TABLE "public"."EventType" ALTER COLUMN "initialDateScheduled" DROP DEFAULT, -ALTER COLUMN "allDay" DROP DEFAULT, -ALTER COLUMN "recurring" DROP DEFAULT, -ALTER COLUMN "members" DROP DEFAULT, -ALTER COLUMN "location" DROP DEFAULT, -ALTER COLUMN "zoomLink" DROP DEFAULT, -ALTER COLUMN "availabilities" DROP DEFAULT, -ALTER COLUMN "shop" DROP DEFAULT, -ALTER COLUMN "machinery" DROP DEFAULT, -ALTER COLUMN "workPackage" DROP DEFAULT, -ALTER COLUMN "questionDocument" DROP DEFAULT, -ALTER COLUMN "documents" DROP DEFAULT, -ALTER COLUMN "description" DROP DEFAULT; - --- AlterTable -ALTER TABLE "public"."ScheduleSlot" ADD COLUMN "endDate" DATE NOT NULL; diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20251022010413_calendar/migration.sql similarity index 80% rename from src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql rename to src/backend/src/prisma/migrations/20251022010413_calendar/migration.sql index 816c214a91..2804446255 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251022010413_calendar/migration.sql @@ -50,6 +50,7 @@ CREATE TABLE "public"."ScheduleSlot" ( "endTime" TIMESTAMP(3), "recurrenceNumber" INTEGER NOT NULL, "initialDateScheduled" DATE NOT NULL, + "endDate" DATE NOT NULL, "allDay" BOOLEAN NOT NULL DEFAULT false, CONSTRAINT "ScheduleSlot_pkey" PRIMARY KEY ("scheduleSlotId") @@ -64,7 +65,7 @@ CREATE TABLE "public"."Event" ( "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, "eventTypeId" TEXT NOT NULL, - "approved" BOOLEAN DEFAULT FALSE, + "approved" BOOLEAN NOT NULL DEFAULT false, "approvedByUserId" TEXT, "location" TEXT, "zoomLink" TEXT, @@ -98,19 +99,19 @@ CREATE TABLE "public"."EventType" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, - "initialDateScheduled" BOOLEAN NOT NULL DEFAULT FALSE, - "allDay" BOOLEAN NOT NULL DEFAULT FALSE, - "recurring" BOOLEAN NOT NULL DEFAULT FALSE, - "members" BOOLEAN NOT NULL DEFAULT FALSE, - "location" BOOLEAN NOT NULL DEFAULT FALSE, - "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, - "availabilities" BOOLEAN NOT NULL DEFAULT FALSE, - "shop" BOOLEAN NOT NULL DEFAULT FALSE, - "machinery" BOOLEAN NOT NULL DEFAULT FALSE, - "workPackage" BOOLEAN NOT NULL DEFAULT FALSE, - "questionDocument" BOOLEAN NOT NULL DEFAULT FALSE, - "documents" BOOLEAN NOT NULL DEFAULT FALSE, - "description" BOOLEAN NOT NULL DEFAULT FALSE, + "initialDateScheduled" BOOLEAN NOT NULL, + "allDay" BOOLEAN NOT NULL, + "recurring" BOOLEAN NOT NULL, + "members" BOOLEAN NOT NULL, + "location" BOOLEAN NOT NULL, + "zoomLink" BOOLEAN NOT NULL, + "availabilities" BOOLEAN NOT NULL, + "shop" BOOLEAN NOT NULL, + "machinery" BOOLEAN NOT NULL, + "workPackage" BOOLEAN NOT NULL, + "questionDocument" BOOLEAN NOT NULL, + "documents" BOOLEAN NOT NULL, + "description" BOOLEAN NOT NULL, "organizationId" TEXT NOT NULL, CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") @@ -132,6 +133,14 @@ CREATE TABLE "public"."_eventAttender" ( CONSTRAINT "_eventAttender_AB_pkey" PRIMARY KEY ("A","B") ); +-- CreateTable +CREATE TABLE "public"."_affiliatedTeam" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_affiliatedTeam_AB_pkey" PRIMARY KEY ("A","B") +); + -- CreateTable CREATE TABLE "public"."_EventToShop" ( "A" TEXT NOT NULL, @@ -168,52 +177,46 @@ CREATE TABLE "public"."_CalendarToEventType" ( CREATE UNIQUE INDEX "Shop_name_key" ON "public"."Shop"("name"); -- CreateIndex -CREATE INDEX "ShopMachinery_machineryId_idx" ON "public"."ShopMachinery"("machineryId"); +CREATE UNIQUE INDEX "Shop_name_organizationId_key" ON "public"."Shop"("name", "organizationId"); -- CreateIndex -CREATE UNIQUE INDEX "ShopMachinery_shopId_machineryId_key" ON "public"."ShopMachinery"("shopId", "machineryId"); +CREATE UNIQUE INDEX "Machinery_name_organizationId_key" ON "public"."Machinery"("name", "organizationId"); -- CreateIndex -CREATE INDEX "_EventToScheduleSlot_B_index" ON "public"."_EventToScheduleSlot"("B"); +CREATE INDEX "ShopMachinery_machineryId_idx" ON "public"."ShopMachinery"("machineryId"); -- CreateIndex -CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); +CREATE UNIQUE INDEX "ShopMachinery_shopId_machineryId_key" ON "public"."ShopMachinery"("shopId", "machineryId"); -- CreateIndex -CREATE INDEX "_EventToShop_B_index" ON "public"."_EventToShop"("B"); +CREATE INDEX "ScheduleSlot_initialDateScheduled_endDate_idx" ON "public"."ScheduleSlot"("initialDateScheduled", "endDate"); -- CreateIndex -CREATE INDEX "_EventToMachinery_B_index" ON "public"."_EventToMachinery"("B"); +CREATE UNIQUE INDEX "Calendar_name_organizationId_key" ON "public"."Calendar"("name", "organizationId"); -- CreateIndex -CREATE INDEX "_EventToWork_Package_B_index" ON "public"."_EventToWork_Package"("B"); +CREATE UNIQUE INDEX "EventType_name_organizationId_key" ON "public"."EventType"("name", "organizationId"); -- CreateIndex -CREATE INDEX "_CalendarToEventType_B_index" ON "public"."_CalendarToEventType"("B"); +CREATE INDEX "_EventToScheduleSlot_B_index" ON "public"."_EventToScheduleSlot"("B"); -- CreateIndex -CREATE UNIQUE INDEX "Calendar_name_organizationId_key" ON "Calendar"("name", "organizationId"); +CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); -- CreateIndex -CREATE UNIQUE INDEX "EventType_name_organizationId_key" ON "EventType"("name", "organizationId"); +CREATE INDEX "_affiliatedTeam_B_index" ON "public"."_affiliatedTeam"("B"); -- CreateIndex -CREATE UNIQUE INDEX "Machinery_name_organizationId_key" ON "Machinery"("name", "organizationId"); +CREATE INDEX "_EventToShop_B_index" ON "public"."_EventToShop"("B"); -- CreateIndex -CREATE UNIQUE INDEX "Shop_name_organizationId_key" ON "Shop"("name", "organizationId"); - --- AddForeignKey -ALTER TABLE "Shop" ADD CONSTRAINT "Shop_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; +CREATE INDEX "_EventToMachinery_B_index" ON "public"."_EventToMachinery"("B"); --- AddForeignKey -ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; +-- CreateIndex +CREATE INDEX "_EventToWork_Package_B_index" ON "public"."_EventToWork_Package"("B"); --- AddForeignKey -ALTER TABLE "EventType" ADD CONSTRAINT "EventType_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; +-- CreateIndex +CREATE INDEX "_CalendarToEventType_B_index" ON "public"."_CalendarToEventType"("B"); -- AddForeignKey ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; @@ -221,12 +224,18 @@ ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY -- AddForeignKey ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."ShopMachinery" ADD CONSTRAINT "ShopMachinery_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("shopId") ON DELETE RESTRICT ON UPDATE CASCADE; @@ -251,12 +260,18 @@ ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOR -- AddForeignKey ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; @@ -272,6 +287,12 @@ ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOR -- AddForeignKey ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "public"."_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Team"("teamId") ON DELETE CASCADE ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."_EventToShop" ADD CONSTRAINT "_EventToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 78f0433384..84241e18b1 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1212,4 +1212,101 @@ describe('Calendar Tests', () => { ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); }); }); + + describe('Get Events', () => { + it('Succeeds and gets all events', async () => { + const member = await createTestUser(supermanAdmin, orgId); + + const otherOrg = await prisma.organization.create({ + data: { + name: 'Other Org (calendar test)', + description: 'for cross-org negative case', + applicationLink: '', + userCreated: { connect: { userId: adminUser.userId } } + } + }); + const otherOrgUser = await createTestUser(alfred, otherOrg.organizationId); + + // Create additional entities for testing + const otherOrgShop = await CalendarService.createShop( + otherOrgUser, + 'Other Org Shop', + 'Shop in different organization', + otherOrg + ); + + const otherOrgMachinery = await CalendarService.createMachinery( + otherOrgUser, + 'Other Org Machinery', + otherOrgShop.shopId, + 1, + otherOrg, + 'Machinery in different organization' + ); + + const document = 'Test Document'; + + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; + const availabilities = [ + { + availability: [9, 10], + dateSet: new Date('2025-10-13') + } + ]; + + const event1 = await CalendarService.createEvent( + adminUser, + 'Team Sync', + eventType.eventTypeId, + organization, + [member.userId], + [], + [shop.shopId], + [machinery.machineryId], + [], + [document], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + + const event2 = await CalendarService.createEvent( + adminUser, + 'Team Sync', + eventType.eventTypeId, + organization, + [member.userId], + [], + [shop.shopId], + [], + [], + [], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + + const result = await CalendarService.getFilteredEvents({}, organization); + expect(result).toStrictEqual([event1, event2]); + }); + }); }); From 6dc90d2e5a2f73df44a708a2768c59aee95e8870 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 21:27:42 -0400 Subject: [PATCH 141/477] test failing? --- src/backend/tests/unit/calendar.test.ts | 43 ++++--------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 84241e18b1..19e7528778 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1215,37 +1215,6 @@ describe('Calendar Tests', () => { describe('Get Events', () => { it('Succeeds and gets all events', async () => { - const member = await createTestUser(supermanAdmin, orgId); - - const otherOrg = await prisma.organization.create({ - data: { - name: 'Other Org (calendar test)', - description: 'for cross-org negative case', - applicationLink: '', - userCreated: { connect: { userId: adminUser.userId } } - } - }); - const otherOrgUser = await createTestUser(alfred, otherOrg.organizationId); - - // Create additional entities for testing - const otherOrgShop = await CalendarService.createShop( - otherOrgUser, - 'Other Org Shop', - 'Shop in different organization', - otherOrg - ); - - const otherOrgMachinery = await CalendarService.createMachinery( - otherOrgUser, - 'Other Org Machinery', - otherOrgShop.shopId, - 1, - otherOrg, - 'Machinery in different organization' - ); - - const document = 'Test Document'; - const scheduleSlots = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -1268,12 +1237,12 @@ describe('Calendar Tests', () => { 'Team Sync', eventType.eventTypeId, organization, - [member.userId], [], - [shop.shopId], - [machinery.machineryId], [], - [document], + [], + [], + [], + [], scheduleSlots, availabilities, true, @@ -1289,9 +1258,9 @@ describe('Calendar Tests', () => { 'Team Sync', eventType.eventTypeId, organization, - [member.userId], [], - [shop.shopId], + [], + [], [], [], [], From d844657675bf7b78401be73f231c905f99f1103e Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 21:33:48 -0400 Subject: [PATCH 142/477] interesting --- src/backend/tests/unit/calendar.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 19e7528778..f2aaf2e2ed 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1275,7 +1275,7 @@ describe('Calendar Tests', () => { ); const result = await CalendarService.getFilteredEvents({}, organization); - expect(result).toStrictEqual([event1, event2]); + expect(result).toStrictEqual([]); }); }); }); From b4c8a2c5ac7c76a4c5754359f3415a2b928f2922 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 21:39:56 -0400 Subject: [PATCH 143/477] test3 --- src/backend/tests/unit/calendar.test.ts | 29 +++++-------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index f2aaf2e2ed..b31b4a73e3 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1215,6 +1215,10 @@ describe('Calendar Tests', () => { describe('Get Events', () => { it('Succeeds and gets all events', async () => { + const member = await createTestUser(supermanAdmin, orgId); + + const document = 'Test Document'; + const scheduleSlots = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -1232,28 +1236,7 @@ describe('Calendar Tests', () => { } ]; - const event1 = await CalendarService.createEvent( - adminUser, - 'Team Sync', - eventType.eventTypeId, - organization, - [], - [], - [], - [], - [], - [], - scheduleSlots, - availabilities, - true, - adminUser.userId, - 'https://example.com/questions.pdf', - 'Conference Room A', - 'https://zoom.us/j/123456789', - 'Weekly team synchronization meeting' - ); - - const event2 = await CalendarService.createEvent( + const event = await CalendarService.createEvent( adminUser, 'Team Sync', eventType.eventTypeId, @@ -1275,7 +1258,7 @@ describe('Calendar Tests', () => { ); const result = await CalendarService.getFilteredEvents({}, organization); - expect(result).toStrictEqual([]); + expect(result).toStrictEqual([event]); }); }); }); From b2e184c5671b771cd097233ead9a410bbc7a6eba Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 21:42:59 -0400 Subject: [PATCH 144/477] test4 --- src/backend/src/services/calendar.services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 37207677a8..31cb5c6fcc 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -898,7 +898,7 @@ export default class CalendarService { where: { eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, - teams: { some: { teamId: { in: teamIds } } }, + teams: teamIds?.length ? { some: { teamId: { in: teamIds } } } : undefined, approved: approvalStatus !== undefined ? { equals: approvalStatus } : undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...memberOrCreator, From 13916ca1e0c775de0b7010615e891b1b88cd37ac Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 22:06:14 -0400 Subject: [PATCH 145/477] test ? --- src/backend/tests/unit/calendar.test.ts | 52 ++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index b31b4a73e3..08a9877e1a 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1217,6 +1217,33 @@ describe('Calendar Tests', () => { it('Succeeds and gets all events', async () => { const member = await createTestUser(supermanAdmin, orgId); + const otherOrg = await prisma.organization.create({ + data: { + name: 'Other Org (calendar test)', + description: 'for cross-org negative case', + applicationLink: '', + userCreated: { connect: { userId: adminUser.userId } } + } + }); + const otherOrgUser = await createTestUser(alfred, otherOrg.organizationId); + + // Create additional entities for testing + const otherOrgShop = await CalendarService.createShop( + otherOrgUser, + 'Other Org Shop', + 'Shop in different organization', + otherOrg + ); + + const otherOrgMachinery = await CalendarService.createMachinery( + otherOrgUser, + 'Other Org Machinery', + otherOrgShop.shopId, + 1, + otherOrg, + 'Machinery in different organization' + ); + const document = 'Test Document'; const scheduleSlots = [ @@ -1236,14 +1263,35 @@ describe('Calendar Tests', () => { } ]; - const event = await CalendarService.createEvent( + const event1 = await CalendarService.createEvent( adminUser, 'Team Sync', eventType.eventTypeId, organization, + [member.userId], [], + [shop.shopId], + [machinery.machineryId], [], + [document], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + + const event2 = await CalendarService.createEvent( + adminUser, + 'Awesome Meeting', + eventType.eventTypeId, + organization, + [member.userId], [], + [shop.shopId], [], [], [], @@ -1258,7 +1306,7 @@ describe('Calendar Tests', () => { ); const result = await CalendarService.getFilteredEvents({}, organization); - expect(result).toStrictEqual([event]); + expect(result).toStrictEqual([event1, event2]); }); }); }); From a77635d8f14e4fe7086848269839f8f4795d8780 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 23:14:56 -0400 Subject: [PATCH 146/477] more test --- src/backend/tests/unit/calendar.test.ts | 121 +++++++++++++++++++----- 1 file changed, 99 insertions(+), 22 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 08a9877e1a..f8ed71925a 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1217,33 +1217,74 @@ describe('Calendar Tests', () => { it('Succeeds and gets all events', async () => { const member = await createTestUser(supermanAdmin, orgId); - const otherOrg = await prisma.organization.create({ - data: { - name: 'Other Org (calendar test)', - description: 'for cross-org negative case', - applicationLink: '', - userCreated: { connect: { userId: adminUser.userId } } + const document = 'Test Document'; + + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false } - }); - const otherOrgUser = await createTestUser(alfred, otherOrg.organizationId); + ]; + const availabilities = [ + { + availability: [9, 10], + dateSet: new Date('2025-10-13') + } + ]; - // Create additional entities for testing - const otherOrgShop = await CalendarService.createShop( - otherOrgUser, - 'Other Org Shop', - 'Shop in different organization', - otherOrg + const event1 = await CalendarService.createEvent( + adminUser, + 'Team Sync', + eventType.eventTypeId, + organization, + [member.userId], + [], + [shop.shopId], + [machinery.machineryId], + [], + [document], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ); - const otherOrgMachinery = await CalendarService.createMachinery( - otherOrgUser, - 'Other Org Machinery', - otherOrgShop.shopId, - 1, - otherOrg, - 'Machinery in different organization' + const event2 = await CalendarService.createEvent( + adminUser, + 'Awesome Meeting', + eventType.eventTypeId, + organization, + [member.userId], + [], + [shop.shopId], + [], + [], + [], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ); + const result = await CalendarService.getFilteredEvents({}, organization); + expect(result).toStrictEqual([event1, event2]); + }); + + it('Succeeds and gets all events within a timeframe', async () => { + const member = await createTestUser(supermanAdmin, orgId); + const document = 'Test Document'; const scheduleSlots = [ @@ -1305,7 +1346,43 @@ describe('Calendar Tests', () => { 'Weekly team synchronization meeting' ); - const result = await CalendarService.getFilteredEvents({}, organization); + const scheduleSlots2 = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 5, + initialDateScheduled: new Date('2029-10-01'), + allDay: false + } + ]; + + // out of timeframe date + await CalendarService.createEvent( + adminUser, + 'Way too far in the future meeting', + eventType.eventTypeId, + organization, + [member.userId], + [], + [shop.shopId], + [], + [], + [], + scheduleSlots2, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + + const result = await CalendarService.getFilteredEvents( + { startPeriod: new Date('2025-10-01T09:00:00Z'), endPeriod: new Date('2025-11-01T09:00:00Z') }, + organization + ); expect(result).toStrictEqual([event1, event2]); }); }); From 6dbecfc395319d840a03865917a6f5c5feb7169d Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 23:24:37 -0400 Subject: [PATCH 147/477] some more testing --- src/backend/tests/unit/calendar.test.ts | 103 +++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index f8ed71925a..0dfdd57177 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1383,7 +1383,108 @@ describe('Calendar Tests', () => { { startPeriod: new Date('2025-10-01T09:00:00Z'), endPeriod: new Date('2025-11-01T09:00:00Z') }, organization ); - expect(result).toStrictEqual([event1, event2]); + expect(result).toStrictEqual([event2, event1]); + }); + + it('Succeeds and gets all events with matching members', async () => { + const member = await createTestUser(supermanAdmin, orgId); + + const document = 'Test Document'; + + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; + const availabilities = [ + { + availability: [9, 10], + dateSet: new Date('2025-10-13') + } + ]; + + const event1 = await CalendarService.createEvent( + adminUser, + 'Team Sync', + eventType.eventTypeId, + organization, + [member.userId], + [], + [shop.shopId], + [machinery.machineryId], + [], + [document], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + + await CalendarService.createEvent( + adminUser, + 'Awesome Meeting', + eventType.eventTypeId, + organization, + [], + [], + [shop.shopId], + [], + [], + [], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + + const scheduleSlots2 = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 5, + initialDateScheduled: new Date('2029-10-01'), + allDay: false + } + ]; + + // out of timeframe date + await CalendarService.createEvent( + adminUser, + 'Way too far in the future meeting', + eventType.eventTypeId, + organization, + [], + [], + [shop.shopId], + [], + [], + [], + scheduleSlots2, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + + const result = await CalendarService.getFilteredEvents({ memberIds: [member.userId] }, organization); + expect(result).toStrictEqual([event1]); }); }); }); From 4fa53e2144027cd25453c13d6df91a554b149d4f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 23:27:44 -0400 Subject: [PATCH 148/477] you guessed it, more messing with tests --- src/backend/tests/unit/calendar.test.ts | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 0dfdd57177..b7fed05dc2 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1325,27 +1325,6 @@ describe('Calendar Tests', () => { 'Weekly team synchronization meeting' ); - const event2 = await CalendarService.createEvent( - adminUser, - 'Awesome Meeting', - eventType.eventTypeId, - organization, - [member.userId], - [], - [shop.shopId], - [], - [], - [], - scheduleSlots, - availabilities, - true, - adminUser.userId, - 'https://example.com/questions.pdf', - 'Conference Room A', - 'https://zoom.us/j/123456789', - 'Weekly team synchronization meeting' - ); - const scheduleSlots2 = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -1383,7 +1362,7 @@ describe('Calendar Tests', () => { { startPeriod: new Date('2025-10-01T09:00:00Z'), endPeriod: new Date('2025-11-01T09:00:00Z') }, organization ); - expect(result).toStrictEqual([event2, event1]); + expect(result).toStrictEqual([event1]); }); it('Succeeds and gets all events with matching members', async () => { From 36dcfb4ac484ca328e77aae09a0a84498265fdbf Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 23:32:58 -0400 Subject: [PATCH 149/477] another test??? --- src/backend/src/services/calendar.services.ts | 1 + src/backend/tests/unit/calendar.test.ts | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 31cb5c6fcc..2cca56f94b 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -904,6 +904,7 @@ export default class CalendarService { ...memberOrCreator, ...fromCalendar }, + orderBy: { dateCreated: 'asc' }, ...getEventQueryArgs(organization.organizationId) }); diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index b7fed05dc2..26a3448451 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1325,6 +1325,27 @@ describe('Calendar Tests', () => { 'Weekly team synchronization meeting' ); + const event2 = await CalendarService.createEvent( + adminUser, + 'Awesome Meeting', + eventType.eventTypeId, + organization, + [member.userId], + [], + [shop.shopId], + [], + [], + [], + scheduleSlots, + availabilities, + true, + adminUser.userId, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' + ); + const scheduleSlots2 = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -1362,7 +1383,7 @@ describe('Calendar Tests', () => { { startPeriod: new Date('2025-10-01T09:00:00Z'), endPeriod: new Date('2025-11-01T09:00:00Z') }, organization ); - expect(result).toStrictEqual([event1]); + expect(result).toStrictEqual([event1, event2]); }); it('Succeeds and gets all events with matching members', async () => { From 5db5a9b5dc83ec0815a0b8a5f3d819d4a6c5525f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 21 Oct 2025 23:55:26 -0400 Subject: [PATCH 150/477] can you beleive it? more tests! --- src/backend/tests/unit/calendar.test.ts | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 26a3448451..8f24ea8b19 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1487,4 +1487,34 @@ describe('Calendar Tests', () => { expect(result).toStrictEqual([event1]); }); }); + + it('fails if memberIds do not exist', async () => { + await expect(CalendarService.getFilteredEvents({ memberIds: ['fakeId'] }, organization)).rejects.toThrow( + new NotFoundException('User', 'non-existent-user-id') + ); + }); + + it('fails if eventTypeIds do not exist', async () => { + await expect(CalendarService.getFilteredEvents({ eventTypeIds: ['fakeId'] }, organization)).rejects.toThrow( + new NotFoundException('Event Type', 'non-existent-event-type-id') + ); + }); + + it('fails if eventIds do not exist', async () => { + await expect(CalendarService.getFilteredEvents({ eventIds: ['fakeId'] }, organization)).rejects.toThrow( + new NotFoundException('Event', 'non-existent-event-id') + ); + }); + + it('fails if calendarIds do not exist', async () => { + await expect(CalendarService.getFilteredEvents({ calendarIds: ['fakeId'] }, organization)).rejects.toThrow( + new NotFoundException('Calendar', 'non-existent-calendar-id') + ); + }); + + it('fails if teamIds do not exist', async () => { + await expect(CalendarService.getFilteredEvents({ teamIds: ['fakeId'] }, organization)).rejects.toThrow( + new NotFoundException('Team', 'non-existent-team-id') + ); + }); }); From 19efbb85e8a20fa6cb58a1ca9bdbed6aaa915975 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 22 Oct 2025 00:01:46 -0400 Subject: [PATCH 151/477] oops --- src/backend/tests/unit/calendar.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 8f24ea8b19..125c55bbf2 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1490,31 +1490,31 @@ describe('Calendar Tests', () => { it('fails if memberIds do not exist', async () => { await expect(CalendarService.getFilteredEvents({ memberIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('User', 'non-existent-user-id') + new NotFoundException('User', 'fakeId') ); }); it('fails if eventTypeIds do not exist', async () => { await expect(CalendarService.getFilteredEvents({ eventTypeIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('Event Type', 'non-existent-event-type-id') + new NotFoundException('Event Type', 'fakeId') ); }); it('fails if eventIds do not exist', async () => { await expect(CalendarService.getFilteredEvents({ eventIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('Event', 'non-existent-event-id') + new NotFoundException('Event', 'fakeId') ); }); it('fails if calendarIds do not exist', async () => { await expect(CalendarService.getFilteredEvents({ calendarIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('Calendar', 'non-existent-calendar-id') + new NotFoundException('Calendar', 'fakeId') ); }); it('fails if teamIds do not exist', async () => { await expect(CalendarService.getFilteredEvents({ teamIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('Team', 'non-existent-team-id') + new NotFoundException('Team', 'fakeId') ); }); }); From 16b3ecc94dc0b1448b2117b3ecbf664a7d53a1ae Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 22 Oct 2025 00:13:16 -0400 Subject: [PATCH 152/477] comments --- src/backend/src/services/calendar.services.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 2cca56f94b..2e3fa74e95 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -791,6 +791,15 @@ export default class CalendarService { return shopTransformer(deleted); } + /** + * Gets all events that match the given filter arguments + * + * @param filters Filters for the events you want to get, which include member IDs, team IDs, event IDs, event type IDs, approval status, and date ranges + * + * @returns The all events that match all of the given filter arguments. + * + * @throws NotFoundException If the given event type Ids, member IDs, team IDs, or event IDs are not found. + */ static async getFilteredEvents(filters: FilterArgs, organization: Organization): Promise { const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvalStatus, startPeriod, endPeriod } = filters; From 9ca8cc059be83a98aa220912fce9cd92f65a97ee Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 22 Oct 2025 02:03:47 -0400 Subject: [PATCH 153/477] update --- src/backend/src/services/calendar.services.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 2e3fa74e95..27075cf0d0 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -905,6 +905,7 @@ export default class CalendarService { // get event using filter args const events = await prisma.event.findMany({ where: { + dateDeleted: null, eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, teams: teamIds?.length ? { some: { teamId: { in: teamIds } } } : undefined, @@ -913,8 +914,8 @@ export default class CalendarService { ...memberOrCreator, ...fromCalendar }, - orderBy: { dateCreated: 'asc' }, - ...getEventQueryArgs(organization.organizationId) + ...getEventQueryArgs(organization.organizationId), + orderBy: { dateCreated: 'asc' } }); return events.map((event) => eventTransformer(event)); From 7f63d2aa7135fc46dd2273dec2529d11caa9ccbf Mon Sep 17 00:00:00 2001 From: wavehassman Date: Wed, 22 Oct 2025 09:28:08 -0400 Subject: [PATCH 154/477] #3568 delete validate inputs --- src/backend/src/routes/calendar.routes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index cd8a99e6f3..710407b1d1 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -92,7 +92,7 @@ calendarRouter.put( CalendarController.editMachinery ); -calendarRouter.post('/machinery/:machineryId/delete', validateInputs, CalendarController.deleteMachinery); +calendarRouter.post('/machinery/:machineryId/delete', CalendarController.deleteMachinery); calendarRouter.put( '/:calendarId/edit', From 2513acdee446ffba1496ab76fa1e6752676cd56a Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 25 Oct 2025 20:06:35 -0400 Subject: [PATCH 155/477] #3634 Added machinery create/edit modal with table in admin schedule --- .../src/controllers/calendar.controllers.ts | 9 ++ src/backend/src/routes/calendar.routes.ts | 2 + src/backend/src/services/calendar.services.ts | 12 ++ src/frontend/src/apis/calendar.api.ts | 26 +++- src/frontend/src/hooks/calendar.hooks.ts | 45 +++++- .../AdminToolsScheduleConfig.tsx | 134 +++++++++++++++-- .../Machinery/CreateMachineryModal.tsx | 134 +++++++++++++++++ .../Machinery/EditMachineryModal.tsx | 139 ++++++++++++++++++ .../{ => Shop}/CreateShopModal.tsx | 6 +- src/frontend/src/utils/urls.ts | 6 + 10 files changed, 496 insertions(+), 17 deletions(-) create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx rename src/frontend/src/pages/AdminToolsPage/ScheduleConfig/{ => Shop}/CreateShopModal.tsx (92%) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index fa3d76ecad..f86735f9ea 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -106,6 +106,15 @@ export default class CalendarController { } } + static async getAllMachinery(req: Request, res: Response, next: NextFunction) { + try { + const machinery = await CalendarService.getAllMachinery(req.organization); + res.status(200).json(machinery); + } catch (error: unknown) { + next(error); + } + } + static async editShop(req: Request, res: Response, next: NextFunction) { try { const { shopId } = req.params; diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 2c67e7bf3f..3941dd4443 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -146,4 +146,6 @@ calendarRouter.post('/shop/:shopId/delete', nonEmptyString(param('shopId')), val calendarRouter.get('/shops', CalendarController.getAllShops); +calendarRouter.get('/machinery', CalendarController.getAllMachinery); + export default calendarRouter; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 7fad961bd2..abf5736132 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -819,6 +819,18 @@ export default class CalendarService { return shops.map(shopTransformer); } + static async getAllMachinery(organization: Organization): Promise { + const machinery = await prisma.machinery.findMany({ + where: { + organizationId: organization.organizationId, + dateDeleted: null + }, + ...getMachineryQueryArgs(organization.organizationId) + }); + + return machinery.map(machineryTransformer); + } + /** * Deletes a machinery by its ID. * Requires the submitter to be an admin. diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 84919e0437..59c29b5819 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,6 +1,6 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; -import { Shop } from 'shared'; +import { Shop, Machinery } from 'shared'; export const getAllShops = () => { return axios.get(apiUrls.calendarShops(), { @@ -13,3 +13,27 @@ export const postCreateShop = (payload: { name: string; description: string }) = transformResponse: (data) => JSON.parse(data) as Shop }); }; + +export const getAllMachinery = () => { + return axios.get(apiUrls.calendarMachinery(), { + transformResponse: (data) => JSON.parse(data) as Machinery[] + }); +}; + +export const postCreateMachinery = (payload: { name: string; shopId: string; quantity: number; description?: string }) => { + return axios.post(apiUrls.calendarCreateMachinery(), payload, { + transformResponse: (data) => JSON.parse(data) as Machinery + }); +}; + +export const postEditMachinery = (payload: { + machineryId: string; + name: string; + shopId: string; + quantity: number; + description?: string; +}) => { + return axios.post(apiUrls.calendarEditMachinery(payload.machineryId), payload, { + transformResponse: (data) => JSON.parse(data) as Machinery + }); +}; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 49a28aee38..a24ff9f4d2 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,8 +1,9 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop } from 'shared'; -import { getAllShops, postCreateShop } from '../apis/calendar.api'; +import { Shop, Machinery } from 'shared'; +import { getAllShops, postCreateShop, getAllMachinery, postCreateMachinery, postEditMachinery } from '../apis/calendar.api'; export const SHOPS_KEY = ['shops'] as const; +export const MACHINERY_KEY = ['machinery'] as const; export const useAllShops = () => useQuery(SHOPS_KEY, async () => { @@ -24,3 +25,43 @@ export const useCreateShop = () => { } ); }; + +export const useAllMachines = () => + useQuery(MACHINERY_KEY, async () => { + const res = await getAllMachinery(); + return res.data; + }); + +export const useCreateMachinery = () => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + const { data } = await postCreateMachinery(payload); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries(MACHINERY_KEY); + } + } + ); +}; + +export const useEditMachinery = () => { + const qc = useQueryClient(); + return useMutation< + Machinery, + Error, + { machineryId: string; name: string; shopId: string; quantity: number; description?: string } + >( + async (payload) => { + const { data } = await postEditMachinery(payload); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries(MACHINERY_KEY); + } + } + ); +}; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 0131ddce4b..a6b4e1774b 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -2,20 +2,34 @@ import React, { useState } from 'react'; import { Box, Grid, Typography, Paper, Table, TableBody, TableCell, TableHead, TableRow, Button } from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; -import { useAllShops, useCreateShop } from '../../../hooks/calendar.hooks'; -import CreateShopModal from './CreateShopModal'; +import { + useAllShops, + useAllMachines, + useCreateShop, + useCreateMachinery, + useEditMachinery +} from '../../../hooks/calendar.hooks'; +import CreateShopModal from './Shop/CreateShopModal'; import { IconButton, Tooltip } from '@mui/material'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; +import CreateMachineryModal from './Machinery/CreateMachineryModal'; +import { EditMachineryModal } from './Machinery/EditMachineryModal'; const AdminToolsScheduleConfig: React.FC = () => { - const { data: shops, isLoading, isError, error } = useAllShops(); + const { data: shops, isLoading: shopsLoading, isError: shopsError, error: shopsErrorMsg } = useAllShops(); + const { data: machines, isLoading: machinesLoading, isError: machinesError, error: machinesErrorMsg } = useAllMachines(); const { mutateAsync: createShopMutate } = useCreateShop(); + const { mutateAsync: createMachineryMutate } = useCreateMachinery(); + const { mutateAsync: editMachineryMutate } = useEditMachinery(); const [openCreate, setOpenCreate] = useState(false); + const [openCreateMachinery, setOpenCreateMachinery] = useState(false); + const [editMachineryId, setEditMachineryId] = useState(null); - if (isLoading) return ; - if (isError) return ; + if (shopsLoading || machinesLoading) return ; + if (shopsError) return ; + if (machinesError) return ; return ( @@ -105,14 +119,76 @@ const AdminToolsScheduleConfig: React.FC = () => { + {/*Machinery Table */} - - Machinery - - - ... - + + Machinery + + + + + + Name + Shop + + # of Machines + + + Actions + + + + + {!machines || !Array.isArray(machines) || machines.length === 0 ? ( + + + No machinery yet. + + + ) : ( + machines.map((machine) => { + let shopName = '—'; + let machineQuantity = '—'; + if (machine.shops && machine.shops.length > 0) { + shopName = machine.shops[0].shop.name; + machineQuantity = machine.shops[0].quantity.toString(); + } + + return ( + + {machine.name} + {shopName} + + {machineQuantity} + + + + + + setEditMachineryId(machine.machineryId)}> + + + + + + + + + + + + + + + + ); + }) + )} + +
@@ -126,6 +202,42 @@ const AdminToolsScheduleConfig: React.FC = () => { setOpenCreate(false); }} /> + + {/* Create Machine Modal */} + setOpenCreateMachinery(false)} + onSubmit={async ({ shopId, machineName, quantity }) => { + await createMachineryMutate({ name: machineName, shopId, quantity }); + setOpenCreateMachinery(false); + }} + /> + + {/* Edit Machine Modal */} + {editMachineryId && + machines && + (() => { + const selectedMachine = machines.find((m) => m.machineryId === editMachineryId); + if (!selectedMachine) return null; + + return ( + setEditMachineryId(null)} + initialValues={{ + name: selectedMachine.name, + shopId: selectedMachine.shops?.[0]?.shop?.shopId || '', + quantity: selectedMachine.shops?.[0]?.quantity || 1 + }} + onSubmit={async ({ name, shopId, quantity }) => { + // Closes the edit modal while updating the machinery so there's no flicker of input values + const machineryId = editMachineryId; + setEditMachineryId(null); + await editMachineryMutate({ machineryId, name, shopId, quantity }); + }} + /> + ); + })()}
); }; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx new file mode 100644 index 0000000000..8511194f68 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx @@ -0,0 +1,134 @@ +import { Box, FormControl, FormHelperText, Typography, MenuItem, Select, SelectChangeEvent } from '@mui/material'; +import NERFormModal from '../../../../components/NERFormModal'; +import ReactHookTextField from '../../../../components/ReactHookTextField'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { useAllShops } from '../../../../hooks/calendar.hooks'; +import { useForm, Controller } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import LoadingIndicator from '../../../../components/LoadingIndicator'; + +export interface CreateMachineFormValues { + shopId: string; + machineName: string; + quantity: number; +} + +const schema = yup.object({ + shopId: yup.string().required('Shop is required'), + machineName: yup.string().required('Machine Name is required'), + quantity: yup.number().required('Quantity is required').min(1, 'Quantity must be at least 1') +}); + +interface CreateMachineryModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: CreateMachineFormValues) => Promise | unknown; +} + +export const CreateMachineryModal: React.FC = ({ open, onClose, onSubmit }) => { + const toast = useToast(); + const { isLoading, data: shops } = useAllShops(); + + const { + handleSubmit, + control, + reset, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { shopId: '', machineName: '', quantity: 1 } + }); + + const onFormSubmit = async (data: CreateMachineFormValues) => { + try { + await onSubmit(data); + } catch (e: unknown) { + if (e instanceof Error) toast.error(e.message); + } + onClose(); + reset({ shopId: '', machineName: '', quantity: 1 }); + }; + + if (isLoading || !shops) return ; + + return ( + reset({ shopId: '', machineName: '', quantity: 1 })} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="create-machinery-form" + showCloseButton + > + + + + Shop:* + + ( + + )} + /> + {errors.shopId?.message} + + + + + Machine:* + + + {errors.machineName?.message} + + + + + # of Machines:* + + ( + + )} + /> + {errors.quantity?.message} + + + + ); +}; + +export default CreateMachineryModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx new file mode 100644 index 0000000000..f1a3a18bef --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx @@ -0,0 +1,139 @@ +import { Box, FormControl, FormHelperText, Typography, MenuItem, Select, SelectChangeEvent } from '@mui/material'; +import NERFormModal from '../../../../components/NERFormModal'; +import ReactHookTextField from '../../../../components/ReactHookTextField'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { useAllShops } from '../../../../hooks/calendar.hooks'; +import { useForm, Controller } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import LoadingIndicator from '../../../../components/LoadingIndicator'; +import { useEffect } from 'react'; + +export interface EditMachineFormValues { + name: string; + shopId: string; + quantity: number; +} + +const schema = yup.object({ + shopId: yup.string().required('Shop is required'), + name: yup.string().required('Machine Name is required'), + quantity: yup.number().required('Quantity is required').min(1, 'Quantity must be at least 1') +}); + +interface EditMachineryModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: EditMachineFormValues) => Promise | unknown; + initialValues?: EditMachineFormValues; +} + +export const EditMachineryModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { + const toast = useToast(); + const { isLoading, data: shops } = useAllShops(); + + const { + handleSubmit, + control, + reset, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: initialValues || { shopId: '', name: '', quantity: 1 } + }); + + useEffect(() => { + if (initialValues) { + reset(initialValues); + } + }, [initialValues, reset]); + + const onFormSubmit = async (data: EditMachineFormValues) => { + try { + await onSubmit(data); + } catch (e: unknown) { + if (e instanceof Error) toast.error(e.message); + } + onClose(); + }; + + if (isLoading || !shops) return ; + + return ( + reset(initialValues || { shopId: '', name: '', quantity: 1 })} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="edit-machinery-form" + showCloseButton + > + + + + Shop:* + + ( + + )} + /> + {errors.shopId?.message} + + + + + Machine:* + + + {errors.name?.message} + + + + + # of Machines:* + + ( + + )} + /> + {errors.quantity?.message} + + + + ); +}; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/CreateShopModal.tsx similarity index 92% rename from src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx rename to src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/CreateShopModal.tsx index bfb6849abd..a086acb654 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/CreateShopModal.tsx @@ -1,7 +1,7 @@ import { Box, FormControl, FormHelperText, Typography } from '@mui/material'; -import NERFormModal from '../../../components/NERFormModal'; -import ReactHookTextField from '../../../components/ReactHookTextField'; -import { useToast } from '../../../hooks/toasts.hooks'; +import NERFormModal from '../../../../components/NERFormModal'; +import ReactHookTextField from '../../../../components/ReactHookTextField'; +import { useToast } from '../../../../hooks/toasts.hooks'; import { useForm } from 'react-hook-form'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index f49941cf24..a7f6fbd475 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -433,6 +433,9 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; const calendarCreateShop = () => `${calendar()}/shop/create`; +const calendarMachinery = () => `${calendar()}/machinery`; +const calendarCreateMachinery = () => `${calendar()}/machinery/create`; +const calendarEditMachinery = (machineryId: string) => `${calendar()}/machinery/${machineryId}/edit`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -731,6 +734,9 @@ export const apiUrls = { calendarShops, calendarCreateShop, + calendarMachinery, + calendarCreateMachinery, + calendarEditMachinery, version }; From 4243fc4f54b5dc271f20617209d5c69f83fa3021 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 25 Oct 2025 20:14:19 -0400 Subject: [PATCH 156/477] #3634 minor naming consistency with other machinery modals --- .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 6 +++--- .../ScheduleConfig/Machinery/EditMachineryModal.tsx | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index a6b4e1774b..01df63d5b7 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -225,15 +225,15 @@ const AdminToolsScheduleConfig: React.FC = () => { open={true} onClose={() => setEditMachineryId(null)} initialValues={{ - name: selectedMachine.name, + machineName: selectedMachine.name, shopId: selectedMachine.shops?.[0]?.shop?.shopId || '', quantity: selectedMachine.shops?.[0]?.quantity || 1 }} - onSubmit={async ({ name, shopId, quantity }) => { + onSubmit={async ({ machineName, shopId, quantity }) => { // Closes the edit modal while updating the machinery so there's no flicker of input values const machineryId = editMachineryId; setEditMachineryId(null); - await editMachineryMutate({ machineryId, name, shopId, quantity }); + await editMachineryMutate({ machineryId, name: machineName, shopId, quantity }); }} /> ); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx index f1a3a18bef..64e33b340d 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx @@ -10,14 +10,14 @@ import LoadingIndicator from '../../../../components/LoadingIndicator'; import { useEffect } from 'react'; export interface EditMachineFormValues { - name: string; + machineName: string; shopId: string; quantity: number; } const schema = yup.object({ shopId: yup.string().required('Shop is required'), - name: yup.string().required('Machine Name is required'), + machineName: yup.string().required('Machine Name is required'), quantity: yup.number().required('Quantity is required').min(1, 'Quantity must be at least 1') }); @@ -39,7 +39,7 @@ export const EditMachineryModal: React.FC = ({ open, on formState: { errors } } = useForm({ resolver: yupResolver(schema), - defaultValues: initialValues || { shopId: '', name: '', quantity: 1 } + defaultValues: initialValues || { shopId: '', machineName: '', quantity: 1 } }); useEffect(() => { @@ -64,7 +64,7 @@ export const EditMachineryModal: React.FC = ({ open, on open={open} onHide={onClose} title="Edit Machine" - reset={() => reset(initialValues || { shopId: '', name: '', quantity: 1 })} + reset={() => reset(initialValues || { shopId: '', machineName: '', quantity: 1 })} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} formId="edit-machinery-form" @@ -105,7 +105,7 @@ export const EditMachineryModal: React.FC = ({ open, on Machine:*
- {errors.name?.message} + {errors.machineName?.message} From 35436629bb15676dc16577b5f30fdc272f6eb8c9 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 26 Oct 2025 17:28:56 -0400 Subject: [PATCH 157/477] updates --- src/backend/src/controllers/calendar.controllers.ts | 9 +++++++++ src/backend/src/routes/calendar.routes.ts | 2 ++ src/backend/src/services/calendar.services.ts | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index e2c2d88822..aef1671616 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -331,6 +331,15 @@ export default class CalendarController { } } + static async getApprovedEvents(req: Request, res: Response, next: NextFunction) { + try { + const filteredEvents = await CalendarService.getFilteredEvents({ approvalStatus: true }, req.organization); + res.status(200).json(filteredEvents); + } catch (error: unknown) { + next(error); + } + } + static async getEventsFromTimeframe(req: Request, res: Response, next: NextFunction) { try { const { startPeriod, endPeriod } = req.query; diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index f8731fa611..74ac53689c 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -124,6 +124,7 @@ calendarRouter.post( body('availabilities').isBoolean(), body('shop').isBoolean(), body('machinery').isBoolean(), + body('workPackage').isBoolean(), body('questionDocument').isBoolean(), body('documents').isBoolean(), body('description').isBoolean(), @@ -193,6 +194,7 @@ calendarRouter.get('/events', CalendarController.getAllEvents); // filtered by approval calendarRouter.get('/events/unapproved', CalendarController.getUnapprovedEvents); +calendarRouter.get('/events/approved', CalendarController.getApprovedEvents); calendarRouter.get('/calendars', CalendarController.getAllCalendars); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 27075cf0d0..fc20096a31 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -918,7 +918,7 @@ export default class CalendarService { orderBy: { dateCreated: 'asc' } }); - return events.map((event) => eventTransformer(event)); + return events.map(eventTransformer); } static async getAllShops(organization: Organization): Promise { From a54b13aaa98569b8f8dc43ddd01794c4fb693521 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 26 Oct 2025 17:36:20 -0400 Subject: [PATCH 158/477] ??? brackets vanished? --- src/backend/src/controllers/calendar.controllers.ts | 5 +++++ src/backend/src/services/calendar.services.ts | 1 + 2 files changed, 6 insertions(+) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index e2752e6940..4769ccfb36 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -373,6 +373,11 @@ export default class CalendarController { try { const calendars = await CalendarService.getAllCalendars(req.organization); res.status(200).json(calendars); + } catch (error: unknown) { + next(error); + } + } + static async deleteMachinery(req: Request, res: Response, next: NextFunction) { try { const { machineryId } = req.params; diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 17e4ca5a3e..ef2ea6086f 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -985,6 +985,7 @@ export default class CalendarService { }); return calendars.map(calendarTransformer); + } /** * Deletes a machinery by its ID. * Requires the submitter to be an admin. From f954e7e7ba1ac6be774cbee6d6af523caeba2b22 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 26 Oct 2025 17:41:14 -0400 Subject: [PATCH 159/477] merge issue (skill issue) --- src/backend/src/services/calendar.services.ts | 2 +- src/backend/tests/unit/calendar.test.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index ef2ea6086f..2476f61b2e 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -11,7 +11,7 @@ import { ScheduleSlotCreateArgs, AvailabilityCreateArgs, Event, - FilterArgs + FilterArgs, Machinery } from 'shared'; import prisma from '../prisma/prisma'; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index f58a0825cc..51fea53db7 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1561,6 +1561,8 @@ describe('Calendar Tests', () => { await expect(CalendarService.getFilteredEvents({ teamIds: ['fakeId'] }, organization)).rejects.toThrow( new NotFoundException('Team', 'fakeId') ); + }); + describe('Delete Machinery', () => { let machineryToDelete: Machinery; let anotherShop: Shop; From c8c4cdff37b2eaac9f8ac3b8941577e818464059 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 26 Oct 2025 19:54:49 -0400 Subject: [PATCH 160/477] #3569 done --- .../src/controllers/calendar.controllers.ts | 72 +++ src/backend/src/routes/calendar.routes.ts | 40 ++ src/backend/src/services/calendar.services.ts | 304 +++++++++ src/backend/src/utils/errors.utils.ts | 3 +- src/backend/tests/unit/calendar.test.ts | 607 +++++++++++++++++- 5 files changed, 1024 insertions(+), 2 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index fa3d76ecad..f9aa5da9d6 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -213,6 +213,18 @@ export default class CalendarController { } } + static async deleteEventType(req: Request, res: Response, next: NextFunction) { + try { + const { eventTypeId } = req.params; + + const deletedEventType = await CalendarService.deleteEventType(req.currentUser, eventTypeId, req.organization); + + res.status(200).json(deletedEventType); + } catch (error: unknown) { + next(error); + } + } + static async deleteShop(req: Request, res: Response, next: NextFunction) { try { const { shopId } = req.params; @@ -270,6 +282,66 @@ export default class CalendarController { } } + static async editEvent(req: Request, res: Response, next: NextFunction) { + try { + const { eventId } = req.params; + + const { + title, + eventTypeId, + memberIds, + shopIds, + machineryIds, + workPackageIds, + documentIds, + scheduleSlot, + availability, + approved, + approvedByUserId, + questionDocument, + location, + zoomLink, + description + } = req.body; + + const event = await CalendarService.editEvent( + req.currentUser, + eventId, + title, + eventTypeId, + req.organization, + memberIds, + shopIds, + machineryIds, + workPackageIds, + documentIds, + scheduleSlot, + availability, + approved, + approvedByUserId, + questionDocument, + location, + zoomLink, + description + ); + res.status(200).json(event); + } catch (error: unknown) { + next(error); + } + } + + static async deleteEvent(req: Request, res: Response, next: NextFunction) { + try { + const { eventId } = req.params; + + const event = await CalendarService.deleteEvent(req.currentUser, eventId, req.organization); + + res.status(200).json(event); + } catch (error: unknown) { + next(error); + } + } + static async deleteMachinery(req: Request, res: Response, next: NextFunction) { try { const { machineryId } = req.params; diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 2c67e7bf3f..6c8b609438 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -72,6 +72,44 @@ calendarRouter.post( CalendarController.createEvent ); +calendarRouter.post( + '/event/:eventId/edit', + nonEmptyString(body('title')), + body('eventTypeId').isString(), + body('approved').isBoolean(), + body('approvedByUserId').optional().isString(), + body('memberIds').isArray(), + body('memberIds.*').isString(), + body('location').optional().isString(), + body('zoomLink').optional().isURL(), + body('shopIds').isArray(), + body('shopIds.*').isString(), + body('machineryIds').isArray(), + body('machineryIds.*').isString(), + body('workPackageIds').isArray(), + body('workPackageIds.*').isString(), + body('documentIds').isArray(), + body('documentIds.*').isString(), + body('questionDocument').optional().isString(), + body('description').optional().isString(), + body('scheduleSlot').isArray(), + body('scheduleSlot.*.daysOfWeek').isArray(), + isDayOfWeek(body('scheduleSlot.*.daysOfWeek.*')), + isDate(body('scheduleSlot.*.startTime')).optional(), + isDate(body('scheduleSlot.*.endTime')).optional(), + intMinZero(body('scheduleSlot.*.recurrenceNumber')), + isDate(body('scheduleSlot.*.initialDateScheduled')), + body('scheduleSlot.*.allDay').isBoolean(), + body('availability').isArray(), + body('availability.*.availability').isArray(), + intMinZero(body('availability.*.availability.*')), + isDate(body('availability.*.dateSet')), + validateInputs, + CalendarController.editEvent +); + +calendarRouter.post('/event/:eventId/delete', CalendarController.deleteEvent); + calendarRouter.post( '/machinery/create', nonEmptyString(body('name')), @@ -140,6 +178,8 @@ calendarRouter.post( CalendarController.editEventType ); +calendarRouter.post('/event-type/:eventTypeId/delete', CalendarController.deleteEventType); + calendarRouter.post('/:calendarId/delete', CalendarController.deleteCalendar); calendarRouter.post('/shop/:shopId/delete', nonEmptyString(param('shopId')), validateInputs, CalendarController.deleteShop); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 7fad961bd2..b692d621b5 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -388,6 +388,273 @@ export default class CalendarService { return eventTransformer(newEvent); } + /** + * Edits an event. + * + * @param submitter The user submitting the request, who must be an admin. + * @param eventId The id of the event to edit. + * @param title The title of the event. + * @param eventTypeId The event type id the event is associated with. + * @param organization The organization for which the event type is being created. + * @param memberIds An array of member ids that are invited to the event. + * @param shopIds An array of shops associated with the event. + * @param machineryIds An array of machinery associated with the event. + * @param workPackageIds An array of work packages associated with the event. + * @param documentIds An array of documents associated with the event. + * @param scheduleSlots An array of schedule slots associated with the event. + * @param availabilities An array of availabilities associated with the event. + * @param approved Determines if the event has been approved. + * @param approvedByUserId The ID of the approving user. + * @param questionDocument The link to the question document. + * @param location Location of the event. + * @param zoomLink Zoom Link if the event is online. + * @param description Describes the event. + * + * @returns The edited event. + * + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + * @throws NotFoundException If the given event type, member IDs, shop IDs, machinery IDs, work package IDs, document IDs, or approvedByUserId are not found. + * @throws InvalidOrganizationException If the given event type, members, shops, machinery, work packages, or approvedByUserId are not part of the same organization. + */ + static async editEvent( + submitter: User, + eventId: string, + title: string, + eventTypeId: string, + organization: Organization, + memberIds: string[], + shopIds: string[], + machineryIds: string[], + workPackageIds: string[], + documentIds: string[], + scheduleSlot: ScheduleSlotCreateArgs[], + availability: AvailabilityCreateArgs[], + approved: boolean, + approvedByUserId?: string, + questionDocument?: string, + location?: string, + zoomLink?: string, + description?: string + ): Promise { + // validate eventId + const foundEvent = await prisma.event.findUnique({ + where: { eventId } + }); + + if (!foundEvent) throw new NotFoundException('Event', eventId); + if (foundEvent.dateDeleted) throw new DeletedException('Event', eventId); + + // Validate eventTypeId + const foundEventType = await prisma.eventType.findUnique({ + where: { eventTypeId } + }); + if (!foundEventType) throw new NotFoundException('Event Type', eventTypeId); + if (foundEventType.dateDeleted) throw new DeletedException('Event Type', eventTypeId); + if (foundEventType.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Event Type'); + } + + // Validate memberIds + if (memberIds.length > 0) { + const foundMembers = await prisma.user.findMany({ + where: { + userId: { in: memberIds }, + organizations: { some: { organizationId: organization.organizationId } } + } + }); + if (foundMembers.length !== memberIds.length) { + const missingIds = memberIds.filter((id) => !foundMembers.some((user) => user.userId === id)); + throw new NotFoundException('User', missingIds.join(', ')); + } + } + + // Validate shopIds + if (shopIds.length > 0) { + const foundShops = await prisma.shop.findMany({ + where: { + shopId: { in: shopIds }, + organizationId: organization.organizationId, + dateDeleted: null + } + }); + if (foundShops.length !== shopIds.length) { + const missingIds = shopIds.filter((id) => !foundShops.some((shop) => shop.shopId === id)); + throw new NotFoundException('Shop', missingIds.join(', ')); + } + } + + // Validate machineryIds + if (machineryIds.length > 0) { + const foundMachinery = await prisma.machinery.findMany({ + where: { + machineryId: { in: machineryIds }, + organizationId: organization.organizationId, + dateDeleted: null + } + }); + if (foundMachinery.length !== machineryIds.length) { + const missingIds = machineryIds.filter((id) => !foundMachinery.some((m) => m.machineryId === id)); + throw new NotFoundException('Machinery', missingIds.join(', ')); + } + } + + // Validate workPackageIds + if (workPackageIds.length > 0) { + const foundWorkPackages = await prisma.work_Package.findMany({ + where: { + workPackageId: { in: workPackageIds } + } + }); + if (foundWorkPackages.length !== workPackageIds.length) { + const missingIds = workPackageIds.filter((id) => !foundWorkPackages.some((wp) => wp.workPackageId === id)); + throw new NotFoundException('Work Package', missingIds.join(', ')); + } + } + + // Validate approvedByUserId + if (approvedByUserId) { + const foundApprovedByUser = await prisma.user.findUnique({ + where: { + userId: approvedByUserId, + organizations: { some: { organizationId: organization.organizationId } } + } + }); + if (!foundApprovedByUser) { + throw new NotFoundException('User', approvedByUserId); + } + } + + // Ensure each availability has a scheduleSettingsId + const availabilitiesWithScheduleSettings = await Promise.all( + availability.map(async (availability) => { + let scheduleSettings = await prisma.schedule_Settings.findUnique({ + where: { userId: submitter.userId } + }); + + if (!scheduleSettings) { + scheduleSettings = await prisma.schedule_Settings.create({ + data: { + userId: submitter.userId, + personalGmail: '', + personalZoomLink: '' + } + }); + } + + return { + availability: availability.availability, + dateSet: availability.dateSet, + scheduleSettingsId: scheduleSettings.drScheduleSettingsId + }; + }) + ); + + // Use transaction for the update + const updatedEvent = await prisma.$transaction(async (tx) => { + await tx.scheduleSlot.deleteMany({ + where: { + ScheduledEvents: { + some: { + eventId + } + } + } + }); + + await tx.availability.deleteMany({ + where: { + event: { + eventId + } + } + }); + + // Update the event with new data + return await tx.event.update({ + where: { eventId }, + data: { + userCreatedId: submitter.userId, + dateCreated: new Date(), + title, + eventTypeId, + members: { + set: memberIds.map((userId) => ({ userId })) + }, + shops: { + set: shopIds.map((shopId) => ({ shopId })) + }, + machinery: { + set: machineryIds.map((machineryId) => ({ machineryId })) + }, + workPackages: { + set: workPackageIds.map((workPackageId) => ({ workPackageId })) + }, + documentIds, + scheduledTimes: { + create: scheduleSlot.map((s) => ({ + days: s.days, + startTime: s.startTime ?? null, + endTime: s.endTime ?? null, + recurrenceNumber: s.recurrenceNumber, + initialDateScheduled: s.initialDateScheduled, + allDay: s.allDay + })) + }, + availabilities: { + createMany: { + data: availabilitiesWithScheduleSettings + } + }, + approved, + approvedByUserId, + location, + zoomLink, + questionDocument, + description + }, + ...getEventQueryArgs(organization.organizationId) + }); + }); + + return eventTransformer(updatedEvent); + } + + /** + * Delete event in the database + * @param submitter The user submitting the request, who must be an admin. + * @param eventId The id of the given event. + * @param organization The organization for which the event is being deleted. + * + * @returns The deleted event. + * + * @throws NotFoundException If the given eventId is not found. + * @throws InvalidOrganizationException If the given eventId is not part of the same organization. + * @throws DeletedException If the event has already been deleted. + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + */ + static async deleteEvent(submitter: User, eventId: string, organization: Organization): Promise { + const event = await prisma.event.findUnique({ + where: { eventId } + }); + + if (!event) throw new NotFoundException('Event', eventId); + if (event.dateDeleted) throw new DeletedException('Event', eventId); + + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); + + if (!hasPermission) { + throw new AccessDeniedException('Only admins can delete events!'); + } + + const deletedEvent = await prisma.event.update({ + where: { eventId }, + data: { dateDeleted: new Date(), userDeletedId: submitter.userId }, + ...getEventQueryArgs(organization.organizationId) + }); + + return eventTransformer(deletedEvent); + } + /** * Edits an existing machinery and its associated shop machinery. * @@ -761,6 +1028,43 @@ export default class CalendarService { return eventTypeTransformer(updatedEventType); } + /** + * Delete event type in the database + * @param submitter The user submitting the request, who must be an admin. + * @param eventTypeId The id of the given event type. + * @param organization The organization for which the event type is being deleted. + * + * @returns The deleted event type. + * + * @throws NotFoundException If the given event type is not found. + * @throws InvalidOrganizationException If the given eventTypeId is not part of the same organization. + * @throws DeletedException If the event type has already been deleted. + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + */ + static async deleteEventType(submitter: User, eventTypeId: string, organization: Organization): Promise { + const eventType = await prisma.eventType.findUnique({ + where: { eventTypeId } + }); + + if (!eventType) throw new NotFoundException('Event Type', eventTypeId); + if (eventType.dateDeleted) throw new DeletedException('Event Type', eventTypeId); + if (eventType.organizationId !== organization.organizationId) throw new InvalidOrganizationException('Event Type'); + + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); + + if (!hasPermission) { + throw new AccessDeniedException('Only admins can delete event types!'); + } + + const deletedEventType = await prisma.eventType.update({ + where: { eventTypeId }, + data: { dateDeleted: new Date(), userDeletedId: submitter.userId }, + ...getEventTypeQueryArgs(organization.organizationId) + }); + + return eventTypeTransformer(deletedEventType); + } + /** * Deletes a shop by its ID. * Requires the submitter to be head or above. diff --git a/src/backend/src/utils/errors.utils.ts b/src/backend/src/utils/errors.utils.ts index a0aa0ca8c8..7266ffdd5f 100644 --- a/src/backend/src/utils/errors.utils.ts +++ b/src/backend/src/utils/errors.utils.ts @@ -165,4 +165,5 @@ export type ExceptionObjectNames = | 'Encryption Key' | 'Reimbursement Request Comment' | 'Calendar' - | 'Event Type'; + | 'Event Type' + | 'Event'; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 70f1a23c9a..397bc81748 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -10,7 +10,17 @@ import { import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; -import { Availability, DayOfWeek, EventType, Machinery, ScheduleSlot, Shop } from 'shared'; +import { + Availability, + AvailabilityCreateArgs, + DayOfWeek, + EventType, + Machinery, + ScheduleSlot, + ScheduleSlotCreateArgs, + Shop, + Event +} from 'shared'; describe('Calendar Tests', () => { let orgId: string; @@ -1319,4 +1329,599 @@ describe('Calendar Tests', () => { expect(bridgeAfter).toBe(0); }); }); + + describe('Edit Event', () => { + let event: Event; + let member: User; + let scheduleSlots: ScheduleSlotCreateArgs[]; + let availabilities: AvailabilityCreateArgs[]; + + beforeEach(async () => { + member = await createTestUser(supermanAdmin, orgId); + scheduleSlots = [ + { + days: [DayOfWeek.MONDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; + availabilities = [ + { + availability: [9, 10], + dateSet: new Date('2025-10-13') + } + ]; + + event = await CalendarService.createEvent( + adminUser, + 'Original Event', + eventType.eventTypeId, + organization, + [member.userId], + [shop.shopId], + [machinery.machineryId], + [], + ['doc1'], + scheduleSlots, + availabilities, + false + ); + }); + + it('fails if event does not exist', async () => { + await expect( + CalendarService.editEvent( + adminUser, + 'non-existent-id', + 'Updated Title', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Event', 'non-existent-id')); + }); + + it('fails if event is already deleted', async () => { + await prisma.event.update({ + where: { eventId: event.eventId }, + data: { dateDeleted: new Date() } + }); + + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new DeletedException('Event', event.eventId)); + }); + + it('fails if eventTypeId does not exist', async () => { + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + 'non-existent-event-type-id', + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Event Type', 'non-existent-event-type-id')); + }); + + it('fails if eventType is deleted', async () => { + await prisma.eventType.update({ + where: { eventTypeId: eventType.eventTypeId }, + data: { dateDeleted: new Date() } + }); + + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new DeletedException('Event Type', eventType.eventTypeId)); + }); + + it('fails if eventType belongs to different organization', async () => { + const otherOrg = await prisma.organization.create({ + data: { + name: 'Other Org (calendar test)', + description: 'for cross-org negative case', + applicationLink: '', + userCreated: { connect: { userId: adminUser.userId } } + } + }); + const AdminInOtherOrg = await createTestUser(alfred, otherOrg.organizationId); + + const otherEventType = await CalendarService.createEventType( + AdminInOtherOrg, + 'Other Org Event Type', + [], + otherOrg, + true, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true + ); + + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + otherEventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new InvalidOrganizationException('Event Type')); + }); + + it('fails if memberIds are invalid', async () => { + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + ['non-existent-user-id'], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); + }); + + it('fails if shopIds are invalid', async () => { + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + [], + ['non-existent-shop-id'], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Shop', 'non-existent-shop-id')); + }); + + it('fails if shopIds are deleted', async () => { + const deletedShop = await CalendarService.createShop(adminUser, 'Deleted Shop', 'Deleted', organization); + await prisma.shop.update({ + where: { shopId: deletedShop.shopId }, + data: { dateDeleted: new Date() } + }); + + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + [], + [deletedShop.shopId], + [], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Shop', deletedShop.shopId)); + }); + + it('fails if machineryIds are invalid', async () => { + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + [], + [], + ['non-existent-machinery-id'], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Machinery', 'non-existent-machinery-id')); + }); + + it('fails if machineryIds are deleted', async () => { + const deletedMachinery = await CalendarService.createMachinery( + adminUser, + 'Deleted Machinery', + shop.shopId, + 1, + organization + ); + await prisma.machinery.update({ + where: { machineryId: deletedMachinery.machineryId }, + data: { dateDeleted: new Date() } + }); + + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + [], + [], + [deletedMachinery.machineryId], + [], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); + }); + + it('fails if workPackageIds are invalid', async () => { + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + [], + [], + [], + ['non-existent-wp-id'], + [], + scheduleSlots, + availabilities, + false + ) + ).rejects.toThrow(new NotFoundException('Work Package', 'non-existent-wp-id')); + }); + + it('fails if approvedByUserId is invalid', async () => { + await expect( + CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Title', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + true, + 'non-existent-user-id' + ) + ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); + }); + + it('succeeds for admin and updates event', async () => { + const newMember = await createTestUser(alfred, orgId); + const newScheduleSlots: ScheduleSlotCreateArgs[] = [ + { + days: [DayOfWeek.WEDNESDAY], + startTime: new Date('2025-10-15T14:00:00Z'), + endTime: new Date('2025-10-15T15:00:00Z'), + recurrenceNumber: 2, + initialDateScheduled: new Date('2025-10-15'), + allDay: true + } + ]; + const newAvailabilities: AvailabilityCreateArgs[] = [ + { + availability: [14, 15], + dateSet: new Date('2025-10-15') + } + ]; + + const result = await CalendarService.editEvent( + adminUser, + event.eventId, + 'Updated Event Title', + eventType.eventTypeId, + organization, + [newMember.userId], + [], + [], + [], + ['doc2', 'doc3'], + newScheduleSlots, + newAvailabilities, + true, + adminUser.userId, + 'https://updated.com/questions.pdf', + 'Updated Location', + 'https://zoom.us/updated', + 'Updated description' + ); + + expect(result.eventId).toBe(event.eventId); + expect(result.title).toBe('Updated Event Title'); + expect(result.people).toHaveLength(1); + expect(result.people[0].userId).toBe(newMember.userId); + expect(result.documentIds).toEqual(['doc2', 'doc3']); + expect(result.approved).toBe(true); + expect(result.approvedBy!.userId).toBe(adminUser.userId); + expect(result.questionDocument).toBe('https://updated.com/questions.pdf'); + expect(result.location).toBe('Updated Location'); + expect(result.zoomLink).toBe('https://zoom.us/updated'); + expect(result.description).toBe('Updated description'); + }); + + it('succeeds and updates with minimal fields', async () => { + const result = await CalendarService.editEvent( + adminUser, + event.eventId, + 'Minimal Update', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + [], + [], + false + ); + + expect(result.eventId).toBe(event.eventId); + expect(result.title).toBe('Minimal Update'); + expect(result.people).toHaveLength(0); + expect(result.shops).toHaveLength(0); + expect(result.machinery).toHaveLength(0); + expect(result.workPackages).toHaveLength(0); + expect(result.documentIds).toHaveLength(0); + expect(result.approved).toBe(false); + }); + }); + + describe('Delete Event', () => { + let event: Event; + + beforeEach(async () => { + const scheduleSlots: ScheduleSlotCreateArgs[] = [ + { + days: [DayOfWeek.MONDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; + const availabilities: AvailabilityCreateArgs[] = [ + { + availability: [9, 10], + dateSet: new Date('2025-10-13') + } + ]; + + event = await CalendarService.createEvent( + adminUser, + 'Event to Delete', + eventType.eventTypeId, + organization, + [], + [], + [], + [], + [], + scheduleSlots, + availabilities, + false + ); + }); + + it('fails if user is not an admin', async () => { + const guest = await createTestUser(wonderwomanGuest, orgId); + await expect(CalendarService.deleteEvent(guest, event.eventId, organization)).rejects.toThrow( + new AccessDeniedException('Only admins can delete events!') + ); + }); + + it('fails if event does not exist', async () => { + await expect(CalendarService.deleteEvent(adminUser, 'non-existent-id', organization)).rejects.toThrow( + new NotFoundException('Event', 'non-existent-id') + ); + }); + + it('fails if event is already deleted', async () => { + await prisma.event.update({ + where: { eventId: event.eventId }, + data: { dateDeleted: new Date() } + }); + + await expect(CalendarService.deleteEvent(adminUser, event.eventId, organization)).rejects.toThrow( + new DeletedException('Event', event.eventId) + ); + }); + + it('succeeds for admin and soft deletes event', async () => { + const result = await CalendarService.deleteEvent(adminUser, event.eventId, organization); + + expect(result.eventId).toBe(event.eventId); + expect(result.title).toBe('Event to Delete'); + + const deletedEvent = await prisma.event.findUnique({ + where: { eventId: event.eventId } + }); + expect(deletedEvent?.dateDeleted).not.toBeNull(); + expect(deletedEvent?.userDeletedId).toBe(adminUser.userId); + }); + }); + + describe('Delete EventType', () => { + let eventTypeToDelete: EventType; + + beforeEach(async () => { + eventTypeToDelete = await CalendarService.createEventType( + adminUser, + 'EventType to Delete', + [calendar.calendarId], + organization, + true, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true + ); + }); + + it('fails if user is not an admin', async () => { + const guest = await createTestUser(wonderwomanGuest, orgId); + await expect(CalendarService.deleteEventType(guest, eventTypeToDelete.eventTypeId, organization)).rejects.toThrow( + new AccessDeniedException('Only admins can delete event types!') + ); + }); + + it('fails if event type does not exist', async () => { + await expect(CalendarService.deleteEventType(adminUser, 'non-existent-id', organization)).rejects.toThrow( + new NotFoundException('Event Type', 'non-existent-id') + ); + }); + + it('fails if event type is already deleted', async () => { + await prisma.eventType.update({ + where: { eventTypeId: eventTypeToDelete.eventTypeId }, + data: { dateDeleted: new Date() } + }); + + await expect(CalendarService.deleteEventType(adminUser, eventTypeToDelete.eventTypeId, organization)).rejects.toThrow( + new DeletedException('Event Type', eventTypeToDelete.eventTypeId) + ); + }); + + it('fails if event type belongs to different organization', async () => { + const otherOrg = await prisma.organization.create({ + data: { + name: 'Other Org (calendar test)', + description: 'for cross-org negative case', + applicationLink: '', + userCreated: { connect: { userId: adminUser.userId } } + } + }); + const AdminInOtherOrg = await createTestUser(alfred, otherOrg.organizationId); + + const otherOrgEventType = await CalendarService.createEventType( + AdminInOtherOrg, + 'Other Org Event Type', + [], + otherOrg, + true, + false, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + true + ); + + await expect(CalendarService.deleteEventType(adminUser, otherOrgEventType.eventTypeId, organization)).rejects.toThrow( + new InvalidOrganizationException('Event Type') + ); + }); + + it('succeeds for admin and soft deletes event type', async () => { + const result = await CalendarService.deleteEventType(adminUser, eventTypeToDelete.eventTypeId, organization); + + expect(result.eventTypeId).toBe(eventTypeToDelete.eventTypeId); + expect(result.name).toBe('EventType to Delete'); + + const deletedEventType = await prisma.eventType.findUnique({ + where: { eventTypeId: eventTypeToDelete.eventTypeId } + }); + expect(deletedEventType?.dateDeleted).not.toBeNull(); + expect(deletedEventType?.userDeletedId).toBe(adminUser.userId); + }); + }); }); From fe30abc5848dec4f4f3d9fad55e72677bb2f76d1 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 26 Oct 2025 20:32:47 -0400 Subject: [PATCH 161/477] #3569 fix route --- src/backend/src/routes/calendar.routes.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 6c8b609438..d6f90d4200 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -57,8 +57,8 @@ calendarRouter.post( body('questionDocument').optional().isString(), body('description').optional().isString(), body('scheduleSlot').isArray(), - body('scheduleSlot.*.daysOfWeek').isArray(), - isDayOfWeek(body('scheduleSlot.*.daysOfWeek.*')), + body('scheduleSlot.*.days').isArray(), + isDayOfWeek(body('scheduleSlot.*.days.*')), isDate(body('scheduleSlot.*.startTime')).optional(), isDate(body('scheduleSlot.*.endTime')).optional(), intMinZero(body('scheduleSlot.*.recurrenceNumber')), @@ -93,8 +93,8 @@ calendarRouter.post( body('questionDocument').optional().isString(), body('description').optional().isString(), body('scheduleSlot').isArray(), - body('scheduleSlot.*.daysOfWeek').isArray(), - isDayOfWeek(body('scheduleSlot.*.daysOfWeek.*')), + body('scheduleSlot.*.days').isArray(), + isDayOfWeek(body('scheduleSlot.*.days.*')), isDate(body('scheduleSlot.*.startTime')).optional(), isDate(body('scheduleSlot.*.endTime')).optional(), intMinZero(body('scheduleSlot.*.recurrenceNumber')), From 4d3aa5bae40b11c19e028a68e11a59f942dec885 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 26 Oct 2025 23:06:31 -0400 Subject: [PATCH 162/477] #3634 removed description fields and update frontend data populating --- .../src/controllers/calendar.controllers.ts | 16 ++++--------- src/backend/src/routes/calendar.routes.ts | 2 -- src/backend/src/services/calendar.services.ts | 23 +++++-------------- src/frontend/src/apis/calendar.api.ts | 10 ++------ src/frontend/src/hooks/calendar.hooks.ts | 8 ++----- .../AdminToolsScheduleConfig.tsx | 8 ++++--- .../Machinery/CreateMachineryModal.tsx | 3 ++- .../Machinery/EditMachineryModal.tsx | 3 ++- .../ScheduleConfig/Shop/CreateShopModal.tsx | 3 ++- 9 files changed, 25 insertions(+), 51 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index f86735f9ea..4ef6eb38da 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -49,16 +49,9 @@ export default class CalendarController { static async createMachinery(req: Request, res: Response, next: NextFunction) { try { - const { name, shopId, quantity, description } = req.body; + const { name, shopId, quantity } = req.body; - const machinery = await CalendarService.createMachinery( - req.currentUser, - name, - shopId, - quantity, - req.organization, - description - ); + const machinery = await CalendarService.createMachinery(req.currentUser, name, shopId, quantity, req.organization); res.status(200).json(machinery); } catch (error: unknown) { next(error); @@ -68,7 +61,7 @@ export default class CalendarController { static async editMachinery(req: Request, res: Response, next: NextFunction) { try { const { machineryId } = req.params; - const { name, shopId, quantity, description } = req.body; + const { name, shopId, quantity } = req.body; const machinery = await CalendarService.editMachinery( req.currentUser, @@ -76,8 +69,7 @@ export default class CalendarController { name, shopId, quantity, - req.organization, - description + req.organization ); res.status(200).json(machinery); } catch (error: unknown) { diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 3941dd4443..fc80bfec34 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -77,7 +77,6 @@ calendarRouter.post( nonEmptyString(body('name')), nonEmptyString(body('shopId')), body('quantity').isInt({ min: 1 }), - body('description').optional().isString(), validateInputs, CalendarController.createMachinery ); @@ -87,7 +86,6 @@ calendarRouter.post( nonEmptyString(body('name')), nonEmptyString(body('shopId')), body('quantity').isInt({ min: 1 }), - body('description').optional().isString(), validateInputs, CalendarController.editMachinery ); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index abf5736132..9ccb2e0c25 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -134,23 +134,16 @@ export default class CalendarService { * * @param submitter The user submitting the request, who must be an admin. * @param name The name of the machinery. - * @param shopMachineryData Array of shop machinery data containing shopId, quantity, and optional description. + * @param shopId The shop ID to associate with the machinery. + * @param quantity The quantity of machinery in the shop. * @param organization The organization for which the machinery is being created. - * @param description The description of the machinery (optional). * * @returns The created machinery object with associated shop machinery. * * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. * @throws NotFoundException If the shop with the given shopId does not exist. */ - static async createMachinery( - submitter: User, - name: string, - shopId: string, - quantity: number, - organization: Organization, - description?: string - ) { + static async createMachinery(submitter: User, name: string, shopId: string, quantity: number, organization: Organization) { // Check if user is admin if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create machinery'); @@ -178,8 +171,7 @@ export default class CalendarService { create: [ { shopId, - quantity, - description + quantity } ] } @@ -397,7 +389,6 @@ export default class CalendarService { * @param shopId The shop ID to associate with the machinery. * @param quantity The quantity of machinery in the shop. * @param organization The organization for which the machinery is being edited. - * @param description The description of the machinery (optional). * * @returns The updated machinery object with associated shop machinery. * @@ -411,8 +402,7 @@ export default class CalendarService { name: string, shopId: string, quantity: number, - organization: Organization, - description?: string + organization: Organization ) { // Check if user is head or above if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead))) { @@ -454,8 +444,7 @@ export default class CalendarService { updateMany: { where: { shopId }, data: { - quantity, - description + quantity } } } diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 59c29b5819..cdd1a60772 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -20,19 +20,13 @@ export const getAllMachinery = () => { }); }; -export const postCreateMachinery = (payload: { name: string; shopId: string; quantity: number; description?: string }) => { +export const postCreateMachinery = (payload: { name: string; shopId: string; quantity: number }) => { return axios.post(apiUrls.calendarCreateMachinery(), payload, { transformResponse: (data) => JSON.parse(data) as Machinery }); }; -export const postEditMachinery = (payload: { - machineryId: string; - name: string; - shopId: string; - quantity: number; - description?: string; -}) => { +export const postEditMachinery = (payload: { machineryId: string; name: string; shopId: string; quantity: number }) => { return axios.post(apiUrls.calendarEditMachinery(payload.machineryId), payload, { transformResponse: (data) => JSON.parse(data) as Machinery }); diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index a24ff9f4d2..81e0cf964d 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -34,7 +34,7 @@ export const useAllMachines = () => export const useCreateMachinery = () => { const qc = useQueryClient(); - return useMutation( + return useMutation( async (payload) => { const { data } = await postCreateMachinery(payload); return data; @@ -49,11 +49,7 @@ export const useCreateMachinery = () => { export const useEditMachinery = () => { const qc = useQueryClient(); - return useMutation< - Machinery, - Error, - { machineryId: string; name: string; shopId: string; quantity: number; description?: string } - >( + return useMutation( async (payload) => { const { data } = await postEditMachinery(payload); return data; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 01df63d5b7..16fd41415d 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -198,8 +198,9 @@ const AdminToolsScheduleConfig: React.FC = () => { open={openCreate} onClose={() => setOpenCreate(false)} onSubmit={async ({ name, description }) => { - await createShopMutate({ name, description }); + const result = await createShopMutate({ name, description }); setOpenCreate(false); + return result; }} /> @@ -208,8 +209,9 @@ const AdminToolsScheduleConfig: React.FC = () => { open={openCreateMachinery} onClose={() => setOpenCreateMachinery(false)} onSubmit={async ({ shopId, machineName, quantity }) => { - await createMachineryMutate({ name: machineName, shopId, quantity }); + const result = await createMachineryMutate({ name: machineName, shopId, quantity }); setOpenCreateMachinery(false); + return result; }} /> @@ -233,7 +235,7 @@ const AdminToolsScheduleConfig: React.FC = () => { // Closes the edit modal while updating the machinery so there's no flicker of input values const machineryId = editMachineryId; setEditMachineryId(null); - await editMachineryMutate({ machineryId, name: machineName, shopId, quantity }); + return await editMachineryMutate({ machineryId, name: machineName, shopId, quantity }); }} /> ); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx index 8511194f68..bf1c3c4633 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx @@ -7,6 +7,7 @@ import { useForm, Controller } from 'react-hook-form'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; import LoadingIndicator from '../../../../components/LoadingIndicator'; +import { Machinery } from 'shared'; export interface CreateMachineFormValues { shopId: string; @@ -23,7 +24,7 @@ const schema = yup.object({ interface CreateMachineryModalProps { open: boolean; onClose: () => void; - onSubmit: (data: CreateMachineFormValues) => Promise | unknown; + onSubmit: (data: CreateMachineFormValues) => Promise; } export const CreateMachineryModal: React.FC = ({ open, onClose, onSubmit }) => { diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx index 64e33b340d..24bc7120e2 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx @@ -8,6 +8,7 @@ import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; import LoadingIndicator from '../../../../components/LoadingIndicator'; import { useEffect } from 'react'; +import { Machinery } from 'shared'; export interface EditMachineFormValues { machineName: string; @@ -24,7 +25,7 @@ const schema = yup.object({ interface EditMachineryModalProps { open: boolean; onClose: () => void; - onSubmit: (data: EditMachineFormValues) => Promise | unknown; + onSubmit: (data: EditMachineFormValues) => Promise; initialValues?: EditMachineFormValues; } diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/CreateShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/CreateShopModal.tsx index a086acb654..389478fe06 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/CreateShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/CreateShopModal.tsx @@ -5,6 +5,7 @@ import { useToast } from '../../../../hooks/toasts.hooks'; import { useForm } from 'react-hook-form'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; +import { Shop } from 'shared'; export interface CreateShopFormValues { name: string; @@ -19,7 +20,7 @@ const schema = yup.object({ interface CreateShopModalProps { open: boolean; onClose: () => void; - onSubmit: (data: CreateShopFormValues) => Promise | unknown; + onSubmit: (data: CreateShopFormValues) => Promise; } export const CreateShopModal: React.FC = ({ open, onClose, onSubmit }) => { From 103fd8ad8628800c45632787d9bf7354a5eacc7f Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 26 Oct 2025 23:27:34 -0400 Subject: [PATCH 163/477] #3634 Updated tests without description field, and adjusted editMachinery payload sending to backend via seperated params --- src/backend/src/services/calendar.services.ts | 3 +- src/backend/tests/unit/calendar.test.ts | 39 +++++-------------- src/frontend/src/apis/calendar.api.ts | 3 +- .../Machinery/EditMachineryModal.tsx | 2 +- 4 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 9ccb2e0c25..a048826a8e 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -442,8 +442,9 @@ export default class CalendarService { name, shops: { updateMany: { - where: { shopId }, + where: {}, data: { + shopId, quantity } } diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 70f1a23c9a..b0637842e9 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -46,14 +46,7 @@ describe('Calendar Tests', () => { ); ({ shopId } = shop); - machinery = await CalendarService.createMachinery( - adminUser, - 'Original Machinery Name', - shop.shopId, - 1, - organization, - 'Original description' - ); + machinery = await CalendarService.createMachinery(adminUser, 'Original Machinery Name', shop.shopId, 1, organization); eventType = await CalendarService.createEventType( adminUser, 'Team Meeting', @@ -337,8 +330,7 @@ describe('Calendar Tests', () => { 'Updated Machinery Name', shop.shopId, 2, - organization, - 'Updated description' + organization ) ).rejects.toThrow(new AccessDeniedException('Only heads and above can edit machinery')); }); @@ -353,8 +345,7 @@ describe('Calendar Tests', () => { 'Updated Machinery Name', shop.shopId, 2, - organization, - 'Updated description' + organization ) ).rejects.toThrow(new NotFoundException('Machinery', nonExistentId)); }); @@ -369,8 +360,7 @@ describe('Calendar Tests', () => { 'Updated Machinery Name', nonExistentShopId, 2, - organization, - 'Updated description' + organization ) ).rejects.toThrow(new NotFoundException('Shop', nonExistentShopId)); }); @@ -382,14 +372,12 @@ describe('Calendar Tests', () => { 'Updated Machinery Name', shop.shopId, 3, - organization, - 'Updated description' + organization ); expect(result.name).toEqual('Updated Machinery Name'); expect(result.shops).toHaveLength(1); expect(result.shops[0].quantity).toBe(3); - expect(result.shops[0].description).toBe('Updated description'); expect(result.shops[0].shop.name).toBe('Precision Manufacturing Lab'); }); @@ -400,14 +388,12 @@ describe('Calendar Tests', () => { 'Admin Updated Machinery', shop.shopId, 5, - organization, - 'Admin updated description' + organization ); expect(result.name).toEqual('Admin Updated Machinery'); expect(result.shops).toHaveLength(1); expect(result.shops[0].quantity).toBe(5); - expect(result.shops[0].description).toBe('Admin updated description'); expect(result.shops[0].shop.name).toBe('Precision Manufacturing Lab'); }); @@ -418,14 +404,12 @@ describe('Calendar Tests', () => { 'No Description Machinery', shop.shopId, 2, - organization, - undefined + organization ); expect(result.name).toEqual('No Description Machinery'); expect(result.shops).toHaveLength(1); expect(result.shops[0].quantity).toBe(2); - expect(result.shops[0].description).toBe('Original description'); // Original description should remain unchanged }); }); @@ -804,8 +788,7 @@ describe('Calendar Tests', () => { 'Other Org Machinery', otherOrgShop.shopId, 1, - otherOrg, - 'Machinery in different organization' + otherOrg ); document = 'Test Document'; @@ -1213,8 +1196,7 @@ describe('Calendar Tests', () => { 'Deleted Machinery', shop.shopId, 1, - organization, - 'Deleted machinery' + organization ); await prisma.machinery.update({ where: { machineryId: deletedMachinery.machineryId }, @@ -1253,8 +1235,7 @@ describe('Calendar Tests', () => { 'Deletable Machinery', shop.shopId, 2, - organization, - 'Test description' + organization ); anotherShop = await CalendarService.createShop( diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index cdd1a60772..606ff15f6b 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -27,7 +27,8 @@ export const postCreateMachinery = (payload: { name: string; shopId: string; qua }; export const postEditMachinery = (payload: { machineryId: string; name: string; shopId: string; quantity: number }) => { - return axios.post(apiUrls.calendarEditMachinery(payload.machineryId), payload, { + const { machineryId, ...body } = payload; + return axios.post(apiUrls.calendarEditMachinery(machineryId), body, { transformResponse: (data) => JSON.parse(data) as Machinery }); }; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx index 24bc7120e2..82a7a46053 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx @@ -105,7 +105,7 @@ export const EditMachineryModal: React.FC = ({ open, on Machine:* - + {errors.machineName?.message} From 9617525263d6676ba5a613794558c89218501ba6 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 26 Oct 2025 23:32:44 -0400 Subject: [PATCH 164/477] #3634 Updated seed to remove description inputs --- src/backend/src/prisma/seed.ts | 48 +++++----------------------------- 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index eeb2e2fca5..ea865834e2 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3083,54 +3083,18 @@ const performSeed: () => Promise = async () => { }); // Create machineries and assign to shops - const ironMachine = await MachineryService.createMachinery( - thomasEmrax, - 'Iron Man CNC Mill', - advancedShop.shopId, - 1, - ner, - 'High-precision CNC milling operations' - ); - const hammer = await MachineryService.createMachinery( - thomasEmrax, - 'Thor Hammer Lathe', - advancedShop.shopId, - 2, - ner, - 'High-precision turning operations' - ); + const ironMachine = await MachineryService.createMachinery(thomasEmrax, 'Iron Man CNC Mill', advancedShop.shopId, 1, ner); + const hammer = await MachineryService.createMachinery(thomasEmrax, 'Thor Hammer Lathe', advancedShop.shopId, 2, ner); const printer = await MachineryService.createMachinery( thomasEmrax, 'Spider-Man 3D Printer', electronicsLab.shopId, 1, - ner, - 'Rapid prototyping for electronics enclosures' - ); - await MachineryService.createMachinery( - thomasEmrax, - 'Captain America Oscilloscope', - electronicsLab.shopId, - 3, - ner, - 'High-speed signal analysis' - ); - await MachineryService.createMachinery( - thomasEmrax, - 'Hulk Dynamometer', - testingFacility.shopId, - 1, - ner, - 'Engine and motor testing' - ); - await MachineryService.createMachinery( - thomasEmrax, - 'Black Widow Thermal Camera', - testingFacility.shopId, - 2, - ner, - 'Thermal imaging and analysis' + ner ); + await MachineryService.createMachinery(thomasEmrax, 'Captain America Oscilloscope', electronicsLab.shopId, 3, ner); + await MachineryService.createMachinery(thomasEmrax, 'Hulk Dynamometer', testingFacility.shopId, 1, ner); + await MachineryService.createMachinery(thomasEmrax, 'Black Widow Thermal Camera', testingFacility.shopId, 2, ner); // various calendars for testing const calendar = await CalendarService.createCalendar( From daf94efc3d30a688445e15d985ca043d0415d9d0 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 27 Oct 2025 00:00:28 -0400 Subject: [PATCH 165/477] #3634 Abstracted edit and create machinery modal to follow other modal abstractions similarly --- src/frontend/src/apis/calendar.api.ts | 24 ++- src/frontend/src/hooks/calendar.hooks.ts | 13 +- .../AdminToolsScheduleConfig.tsx | 40 +---- .../Machinery/CreateMachineryModal.tsx | 131 +------------- .../Machinery/EditMachineryModal.tsx | 143 ++------------- .../Machinery/MachineryFormModal.tsx | 164 ++++++++++++++++++ src/frontend/src/utils/form.ts | 4 +- 7 files changed, 219 insertions(+), 300 deletions(-) create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 606ff15f6b..c972694d74 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -20,15 +20,27 @@ export const getAllMachinery = () => { }); }; -export const postCreateMachinery = (payload: { name: string; shopId: string; quantity: number }) => { - return axios.post(apiUrls.calendarCreateMachinery(), payload, { - transformResponse: (data) => JSON.parse(data) as Machinery - }); +export const postCreateMachinery = async (payload: { machineName: string; shopId: string; quantity: number }) => { + const { machineName, ...rest } = payload; + const { data } = await axios.post( + apiUrls.calendarCreateMachinery(), + { name: machineName, ...rest }, + { + transformResponse: (data) => JSON.parse(data) as Machinery + } + ); + return data; }; -export const postEditMachinery = (payload: { machineryId: string; name: string; shopId: string; quantity: number }) => { +export const postEditMachinery = async (payload: { + machineryId: string; + name: string; + shopId: string; + quantity: number; +}) => { const { machineryId, ...body } = payload; - return axios.post(apiUrls.calendarEditMachinery(machineryId), body, { + const { data } = await axios.post(apiUrls.calendarEditMachinery(machineryId), body, { transformResponse: (data) => JSON.parse(data) as Machinery }); + return data; }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 81e0cf964d..7eb5796127 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -34,10 +34,9 @@ export const useAllMachines = () => export const useCreateMachinery = () => { const qc = useQueryClient(); - return useMutation( + return useMutation( async (payload) => { - const { data } = await postCreateMachinery(payload); - return data; + return await postCreateMachinery(payload); }, { onSuccess: () => { @@ -47,12 +46,12 @@ export const useCreateMachinery = () => { ); }; -export const useEditMachinery = () => { +export const useEditMachinery = (machineryId: string) => { const qc = useQueryClient(); - return useMutation( + return useMutation( async (payload) => { - const { data } = await postEditMachinery(payload); - return data; + const { machineName, shopId, quantity } = payload; + return await postEditMachinery({ machineryId, name: machineName, shopId, quantity }); }, { onSuccess: () => { diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 16fd41415d..9140340ac5 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -2,26 +2,18 @@ import React, { useState } from 'react'; import { Box, Grid, Typography, Paper, Table, TableBody, TableCell, TableHead, TableRow, Button } from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; -import { - useAllShops, - useAllMachines, - useCreateShop, - useCreateMachinery, - useEditMachinery -} from '../../../hooks/calendar.hooks'; +import { useAllShops, useAllMachines, useCreateShop } from '../../../hooks/calendar.hooks'; import CreateShopModal from './Shop/CreateShopModal'; import { IconButton, Tooltip } from '@mui/material'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import CreateMachineryModal from './Machinery/CreateMachineryModal'; -import { EditMachineryModal } from './Machinery/EditMachineryModal'; +import EditMachineryModal from './Machinery/EditMachineryModal'; const AdminToolsScheduleConfig: React.FC = () => { const { data: shops, isLoading: shopsLoading, isError: shopsError, error: shopsErrorMsg } = useAllShops(); const { data: machines, isLoading: machinesLoading, isError: machinesError, error: machinesErrorMsg } = useAllMachines(); const { mutateAsync: createShopMutate } = useCreateShop(); - const { mutateAsync: createMachineryMutate } = useCreateMachinery(); - const { mutateAsync: editMachineryMutate } = useEditMachinery(); const [openCreate, setOpenCreate] = useState(false); const [openCreateMachinery, setOpenCreateMachinery] = useState(false); @@ -205,15 +197,7 @@ const AdminToolsScheduleConfig: React.FC = () => { /> {/* Create Machine Modal */} - setOpenCreateMachinery(false)} - onSubmit={async ({ shopId, machineName, quantity }) => { - const result = await createMachineryMutate({ name: machineName, shopId, quantity }); - setOpenCreateMachinery(false); - return result; - }} - /> + setOpenCreateMachinery(false)} /> {/* Edit Machine Modal */} {editMachineryId && @@ -222,23 +206,7 @@ const AdminToolsScheduleConfig: React.FC = () => { const selectedMachine = machines.find((m) => m.machineryId === editMachineryId); if (!selectedMachine) return null; - return ( - setEditMachineryId(null)} - initialValues={{ - machineName: selectedMachine.name, - shopId: selectedMachine.shops?.[0]?.shop?.shopId || '', - quantity: selectedMachine.shops?.[0]?.quantity || 1 - }} - onSubmit={async ({ machineName, shopId, quantity }) => { - // Closes the edit modal while updating the machinery so there's no flicker of input values - const machineryId = editMachineryId; - setEditMachineryId(null); - return await editMachineryMutate({ machineryId, name: machineName, shopId, quantity }); - }} - /> - ); + return setEditMachineryId(null)} machinery={selectedMachine} />; })()}
); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx index bf1c3c4633..dddb1c70d3 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx @@ -1,135 +1,20 @@ -import { Box, FormControl, FormHelperText, Typography, MenuItem, Select, SelectChangeEvent } from '@mui/material'; -import NERFormModal from '../../../../components/NERFormModal'; -import ReactHookTextField from '../../../../components/ReactHookTextField'; -import { useToast } from '../../../../hooks/toasts.hooks'; -import { useAllShops } from '../../../../hooks/calendar.hooks'; -import { useForm, Controller } from 'react-hook-form'; -import * as yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; +import ErrorPage from '../../../ErrorPage'; import LoadingIndicator from '../../../../components/LoadingIndicator'; -import { Machinery } from 'shared'; - -export interface CreateMachineFormValues { - shopId: string; - machineName: string; - quantity: number; -} - -const schema = yup.object({ - shopId: yup.string().required('Shop is required'), - machineName: yup.string().required('Machine Name is required'), - quantity: yup.number().required('Quantity is required').min(1, 'Quantity must be at least 1') -}); +import { useCreateMachinery } from '../../../../hooks/calendar.hooks'; +import MachineryFormModal from './MachineryFormModal'; interface CreateMachineryModalProps { open: boolean; onClose: () => void; - onSubmit: (data: CreateMachineFormValues) => Promise; } -export const CreateMachineryModal: React.FC = ({ open, onClose, onSubmit }) => { - const toast = useToast(); - const { isLoading, data: shops } = useAllShops(); - - const { - handleSubmit, - control, - reset, - formState: { errors } - } = useForm({ - resolver: yupResolver(schema), - defaultValues: { shopId: '', machineName: '', quantity: 1 } - }); - - const onFormSubmit = async (data: CreateMachineFormValues) => { - try { - await onSubmit(data); - } catch (e: unknown) { - if (e instanceof Error) toast.error(e.message); - } - onClose(); - reset({ shopId: '', machineName: '', quantity: 1 }); - }; - - if (isLoading || !shops) return ; - - return ( - reset({ shopId: '', machineName: '', quantity: 1 })} - handleUseFormSubmit={handleSubmit} - onFormSubmit={onFormSubmit} - formId="create-machinery-form" - showCloseButton - > - - - - Shop:* - - ( - - )} - /> - {errors.shopId?.message} - +const CreateMachineryModal = ({ open, onClose }: CreateMachineryModalProps) => { + const { isLoading, isError, error, mutateAsync } = useCreateMachinery(); - - - Machine:* - - - {errors.machineName?.message} - + if (isError) return ; + if (isLoading) return ; - - - # of Machines:* - - ( - - )} - /> - {errors.quantity?.message} - - - - ); + return ; }; export default CreateMachineryModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx index 82a7a46053..878acdc8ef 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx @@ -1,140 +1,29 @@ -import { Box, FormControl, FormHelperText, Typography, MenuItem, Select, SelectChangeEvent } from '@mui/material'; -import NERFormModal from '../../../../components/NERFormModal'; -import ReactHookTextField from '../../../../components/ReactHookTextField'; -import { useToast } from '../../../../hooks/toasts.hooks'; -import { useAllShops } from '../../../../hooks/calendar.hooks'; -import { useForm, Controller } from 'react-hook-form'; -import * as yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; +import ErrorPage from '../../../ErrorPage'; import LoadingIndicator from '../../../../components/LoadingIndicator'; -import { useEffect } from 'react'; +import { useEditMachinery } from '../../../../hooks/calendar.hooks'; import { Machinery } from 'shared'; - -export interface EditMachineFormValues { - machineName: string; - shopId: string; - quantity: number; -} - -const schema = yup.object({ - shopId: yup.string().required('Shop is required'), - machineName: yup.string().required('Machine Name is required'), - quantity: yup.number().required('Quantity is required').min(1, 'Quantity must be at least 1') -}); +import MachineryFormModal from './MachineryFormModal'; +import { MachineryFormValues } from './MachineryFormModal'; interface EditMachineryModalProps { open: boolean; onClose: () => void; - onSubmit: (data: EditMachineFormValues) => Promise; - initialValues?: EditMachineFormValues; + machinery: Machinery; } -export const EditMachineryModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { - const toast = useToast(); - const { isLoading, data: shops } = useAllShops(); - - const { - handleSubmit, - control, - reset, - formState: { errors } - } = useForm({ - resolver: yupResolver(schema), - defaultValues: initialValues || { shopId: '', machineName: '', quantity: 1 } - }); +const EditMachineryModal = ({ open, onClose, machinery }: EditMachineryModalProps) => { + const { isLoading, isError, error, mutateAsync } = useEditMachinery(machinery.machineryId); - useEffect(() => { - if (initialValues) { - reset(initialValues); - } - }, [initialValues, reset]); - - const onFormSubmit = async (data: EditMachineFormValues) => { - try { - await onSubmit(data); - } catch (e: unknown) { - if (e instanceof Error) toast.error(e.message); - } - onClose(); + const machineryData: MachineryFormValues = { + shopId: machinery.shops?.[0]?.shop?.shopId || '', + machineName: machinery.name, + quantity: machinery.shops?.[0]?.quantity || 1 }; - if (isLoading || !shops) return ; - - return ( - reset(initialValues || { shopId: '', machineName: '', quantity: 1 })} - handleUseFormSubmit={handleSubmit} - onFormSubmit={onFormSubmit} - formId="edit-machinery-form" - showCloseButton - > - - - - Shop:* - - ( - - )} - /> - {errors.shopId?.message} - + if (isError) return ; + if (isLoading) return ; - - - Machine:* - - - {errors.machineName?.message} - - - - - # of Machines:* - - ( - - )} - /> - {errors.quantity?.message} - - - - ); + return ; }; + +export default EditMachineryModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx new file mode 100644 index 0000000000..43f160d0be --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx @@ -0,0 +1,164 @@ +import { Box, FormControl, FormHelperText, Typography, MenuItem, Select, SelectChangeEvent } from '@mui/material'; +import NERFormModal from '../../../../components/NERFormModal'; +import ReactHookTextField from '../../../../components/ReactHookTextField'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { useAllShops } from '../../../../hooks/calendar.hooks'; +import { useForm, Controller } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import LoadingIndicator from '../../../../components/LoadingIndicator'; +import { useEffect } from 'react'; +import { Machinery } from 'shared'; +import useFormPersist from 'react-hook-form-persist'; +import { FormStorageKey } from '../../../../utils/form'; + +export interface MachineryFormValues { + shopId: string; + machineName: string; + quantity: number; +} + +const schema = yup.object({ + shopId: yup.string().required('Shop is required'), + machineName: yup.string().required('Machine Name is required'), + quantity: yup.number().required('Quantity is required').min(1, 'Quantity must be at least 1') +}); + +interface MachineryFormModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: MachineryFormValues) => Promise; + initialValues?: MachineryFormValues; +} + +export const MachineryFormModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { + const toast = useToast(); + const { isLoading, data: shops } = useAllShops(); + + const defaultValues = { shopId: '', machineName: '', quantity: 1 }; + + const { + handleSubmit, + control, + reset, + formState: { errors }, + watch, + setValue + } = useForm({ + resolver: yupResolver(schema), + defaultValues: initialValues || defaultValues + }); + + const formStorageKey = initialValues ? FormStorageKey.EDIT_MACHINERY : FormStorageKey.CREATE_MACHINERY; + + useFormPersist(formStorageKey, { + watch, + setValue + }); + + useEffect(() => { + if (initialValues) { + reset(initialValues); + } + }, [initialValues, reset]); + + const onFormSubmit = async (data: MachineryFormValues) => { + try { + await onSubmit(data); + } catch (e: unknown) { + if (e instanceof Error) toast.error(e.message); + } + onClose(); + if (!initialValues) { + reset(defaultValues); + } + }; + + const handleCancel = () => { + reset(defaultValues); + sessionStorage.removeItem(formStorageKey); + onClose(); + }; + + if (isLoading || !shops) return ; + + return ( + reset(initialValues || defaultValues)} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId={initialValues ? 'edit-machinery-form' : 'create-machinery-form'} + showCloseButton + > + + + + Shop:* + + ( + + )} + /> + {errors.shopId?.message} + + + + + Machine:* + + + {errors.machineName?.message} + + + + + # of Machines:* + + ( + + )} + /> + {errors.quantity?.message} + + + + ); +}; + +export default MachineryFormModal; diff --git a/src/frontend/src/utils/form.ts b/src/frontend/src/utils/form.ts index bbfa4d1878..09be05e2d0 100644 --- a/src/frontend/src/utils/form.ts +++ b/src/frontend/src/utils/form.ts @@ -82,5 +82,7 @@ export enum FormStorageKey { CREATE_MILESTONE = 'CREATE_MILESTONE', EDIT_MILESTONE = 'EDIT_MILESTONE', CREATE_FAQ = 'CREATE_FAQ', - EDIT_FAQ = 'EDIT_FAQ' + EDIT_FAQ = 'EDIT_FAQ', + CREATE_MACHINERY = 'CREATE_MACHINERY', + EDIT_MACHINERY = 'EDIT_MACHINERY' } From 7e9bfe07bfd71856634c7e0947af435301fcfa99 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 27 Oct 2025 15:41:13 -0400 Subject: [PATCH 166/477] #3634 Added one more machinery test to make sure edit works --- src/backend/tests/unit/calendar.test.ts | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index b0637842e9..55b0f52b60 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -411,6 +411,34 @@ describe('Calendar Tests', () => { expect(result.shops).toHaveLength(1); expect(result.shops[0].quantity).toBe(2); }); + + it('Succeeds and updates machinery to a different shop', async () => { + // Create a newshop + const newShop = await CalendarService.createShop( + adminUser, + 'Electronics Lab', + 'Electronics testing facility', + organization + ); + + //Check that the machinery original shop is not the new shop before editing + expect(machinery.shops[0].shop.shopId).not.toBe(newShop.shopId); + + const result = await CalendarService.editMachinery( + adminUser, + machinery.machineryId, + 'Updated Shop to Electronics Lab', + newShop.shopId, + 5, + organization + ); + + expect(result.name).toEqual('Updated Shop to Electronics Lab'); + expect(result.shops).toHaveLength(1); + expect(result.shops[0].quantity).toBe(5); + expect(result.shops[0].shop.name).toBe('Electronics Lab'); + expect(result.shops[0].shop.shopId).toBe(newShop.shopId); + }); }); describe('Shop Tests', () => { From 7e2eed96968f1a83e766a1b2d7853b7ab1bab8e7 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 28 Oct 2025 14:22:26 -0400 Subject: [PATCH 167/477] #3569 fixed documentation --- src/backend/src/services/calendar.services.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index b692d621b5..475908da55 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -213,7 +213,6 @@ export default class CalendarService { * * @returns The created event. * - * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. * @throws NotFoundException If the given event type, member IDs, shop IDs, machinery IDs, work package IDs, document IDs, or approvedByUserId are not found. * @throws InvalidOrganizationException If the given event type, members, shops, machinery, work packages, or approvedByUserId are not part of the same organization. */ @@ -412,7 +411,6 @@ export default class CalendarService { * * @returns The edited event. * - * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. * @throws NotFoundException If the given event type, member IDs, shop IDs, machinery IDs, work package IDs, document IDs, or approvedByUserId are not found. * @throws InvalidOrganizationException If the given event type, members, shops, machinery, work packages, or approvedByUserId are not part of the same organization. */ From e59f57d7bf8804c338c70b3d4a5c7dbb88c0af77 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sat, 1 Nov 2025 10:22:34 -0400 Subject: [PATCH 168/477] #3569 event can be deleted by creator, schedule slots and availabilties are only updated if changed --- src/backend/src/services/calendar.services.ts | 119 +++++++++++++----- 1 file changed, 87 insertions(+), 32 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 475908da55..2983beb585 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -549,30 +549,98 @@ export default class CalendarService { // Use transaction for the update const updatedEvent = await prisma.$transaction(async (tx) => { - await tx.scheduleSlot.deleteMany({ - where: { - ScheduledEvents: { - some: { - eventId - } + // Fetch existing schedule slots and availabilities + const [existingSlots, existingAvailabilities] = await Promise.all([ + tx.scheduleSlot.findMany({ + where: { ScheduledEvents: { some: { eventId } } }, + select: { + days: true, + startTime: true, + endTime: true, + recurrenceNumber: true, + initialDateScheduled: true, + allDay: true } - } - }); + }), + tx.availability.findMany({ + where: { eventId }, + select: { + availability: true, + dateSet: true, + scheduleSettingsId: true + } + }) + ]); + + // Checks if all schedule slots are the same (ie no changes) + const haveDifferentSlots = (a: typeof existingSlots, b: typeof scheduleSlot) => { + if (a.length !== b.length) return true; + return a.some((oldSlot, idx) => { + const newSlot = b[idx]; + return ( + oldSlot.days !== newSlot.days || + oldSlot.startTime !== newSlot.startTime || + oldSlot.endTime !== newSlot.endTime || + oldSlot.recurrenceNumber !== newSlot.recurrenceNumber || + oldSlot.initialDateScheduled !== newSlot.initialDateScheduled || + oldSlot.allDay !== newSlot.allDay + ); + }); + }; + + // Checks if all availabilties are the same (ie no changes) + const haveDifferentAvailabilities = ( + a: typeof existingAvailabilities, + b: typeof availabilitiesWithScheduleSettings + ) => { + if (a.length !== b.length) return true; + return a.some((oldAvail, idx) => { + const newAvail = b[idx]; + return ( + oldAvail.scheduleSettingsId !== newAvail.scheduleSettingsId || + oldAvail.availability !== newAvail.availability || + oldAvail.dateSet !== newAvail.dateSet + ); + }); + }; - await tx.availability.deleteMany({ - where: { - event: { + if (haveDifferentSlots(existingSlots, scheduleSlot)) { + await tx.scheduleSlot.deleteMany({ + where: { ScheduledEvents: { some: { eventId } } } + }); + await Promise.all( + scheduleSlot.map((s) => + tx.scheduleSlot.create({ + data: { + days: s.days, + startTime: s.startTime ?? null, + endTime: s.endTime ?? null, + recurrenceNumber: s.recurrenceNumber, + initialDateScheduled: s.initialDateScheduled, + allDay: s.allDay, + ScheduledEvents: { connect: { eventId } } + } + }) + ) + ); + } + + if (haveDifferentAvailabilities(existingAvailabilities, availabilitiesWithScheduleSettings)) { + await tx.availability.deleteMany({ + where: { eventId } + }); + await tx.availability.createMany({ + data: availabilitiesWithScheduleSettings.map((a) => ({ + ...a, eventId - } - } - }); + })) + }); + } // Update the event with new data return await tx.event.update({ where: { eventId }, data: { - userCreatedId: submitter.userId, - dateCreated: new Date(), title, eventTypeId, members: { @@ -588,21 +656,6 @@ export default class CalendarService { set: workPackageIds.map((workPackageId) => ({ workPackageId })) }, documentIds, - scheduledTimes: { - create: scheduleSlot.map((s) => ({ - days: s.days, - startTime: s.startTime ?? null, - endTime: s.endTime ?? null, - recurrenceNumber: s.recurrenceNumber, - initialDateScheduled: s.initialDateScheduled, - allDay: s.allDay - })) - }, - availabilities: { - createMany: { - data: availabilitiesWithScheduleSettings - } - }, approved, approvedByUserId, location, @@ -638,7 +691,9 @@ export default class CalendarService { if (!event) throw new NotFoundException('Event', eventId); if (event.dateDeleted) throw new DeletedException('Event', eventId); - const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin); + const hasPermission = + (await userHasPermission(submitter.userId, organization.organizationId, isAdmin)) || + submitter.userId === event.userCreatedId; if (!hasPermission) { throw new AccessDeniedException('Only admins can delete events!'); From ae614bd8f4c9963fd18548bf695bcecfcc48becc Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 1 Nov 2025 12:27:54 -0400 Subject: [PATCH 169/477] update --- .../src/controllers/calendar.controllers.ts | 3 +-- src/backend/src/routes/calendar.routes.ts | 27 +++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 4769ccfb36..51eb8db49c 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -275,8 +275,7 @@ export default class CalendarController { //overall filtering for events static async getFilteredEvents(req: Request, res: Response, next: NextFunction) { try { - const { filterArgs } = req.body; - const filteredEvents = await CalendarService.getFilteredEvents(filterArgs, req.organization); + const filteredEvents = await CalendarService.getFilteredEvents(req.body, req.organization); res.status(200).json(filteredEvents); } catch (error: unknown) { next(error); diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index ed20c9f282..8a58c5e8d5 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -151,20 +151,19 @@ calendarRouter.get('/shops', CalendarController.getAllShops); // no restrictions filtering, in case multiple filters need to be sent calendarRouter.post( '/events/filter', - body('filterArgs').optional(), - body('filterArgs.memberIds').optional().isArray(), - body('filterArgs.memberIds.*').optional().isString(), - body('filterArgs.teamIds').optional().isArray(), - body('filterArgs.teamIds.*').optional().isString(), - body('filterArgs.calendarIds').isArray().optional(), - body('filterArgs.calendarIds.*').isString().optional(), - body('filterArgs.eventTypeIds').optional().isArray(), - body('filterArgs.eventTypeIds.*').optional().isString(), - body('filterArgs.eventIds').isArray().optional(), - body('filterArgs.eventIds.*').isString().optional(), - body('filterArgs.approvalStatus').isBoolean().optional(), - isDate(body('filterArgs.startPeriod')).optional(), - isDate(body('filterArgs.endPeriod')).optional(), + body('memberIds').optional().isArray(), + body('memberIds.*').optional().isString(), + body('teamIds').optional().isArray(), + body('teamIds.*').optional().isString(), + body('calendarIds').isArray().optional(), + body('calendarIds.*').isString().optional(), + body('eventTypeIds').optional().isArray(), + body('eventTypeIds.*').optional().isString(), + body('eventIds').isArray().optional(), + body('eventIds.*').isString().optional(), + body('approvalStatus').isBoolean().optional(), + isDate(body('startPeriod')).optional(), + isDate(body('endPeriod')).optional(), validateInputs, CalendarController.getFilteredEvents ); From 547b9ac0daa6f1cd592b5d39a162c60cc9fab1e2 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 1 Nov 2025 13:16:56 -0400 Subject: [PATCH 170/477] #3634 Updated machinery backend/frontend relationship one-to-many when adding machine and assigning to multiple shops --- .../src/controllers/calendar.controllers.ts | 6 +- src/backend/src/services/calendar.services.ts | 284 ++++++++++++++++-- src/backend/tests/unit/calendar.test.ts | 11 +- src/frontend/src/apis/calendar.api.ts | 2 + src/frontend/src/hooks/calendar.hooks.ts | 17 +- .../AdminToolsScheduleConfig.tsx | 93 +++--- .../Machinery/EditMachineryModal.tsx | 18 +- 7 files changed, 364 insertions(+), 67 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 4ef6eb38da..a6453aab54 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -61,7 +61,7 @@ export default class CalendarController { static async editMachinery(req: Request, res: Response, next: NextFunction) { try { const { machineryId } = req.params; - const { name, shopId, quantity } = req.body; + const { name, shopId, quantity, originalShopId, shopMachineryId } = req.body; const machinery = await CalendarService.editMachinery( req.currentUser, @@ -69,7 +69,9 @@ export default class CalendarController { name, shopId, quantity, - req.organization + req.organization, + originalShopId, + shopMachineryId ); res.status(200).json(machinery); } catch (error: unknown) { diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index a048826a8e..91a0c7685f 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -144,12 +144,10 @@ export default class CalendarService { * @throws NotFoundException If the shop with the given shopId does not exist. */ static async createMachinery(submitter: User, name: string, shopId: string, quantity: number, organization: Organization) { - // Check if user is admin if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create machinery'); } - // Check if shop with id exists and belongs to the same organization const existingShop = await prisma.shop.findUnique({ where: { shopId } }); @@ -162,6 +160,62 @@ export default class CalendarService { throw new InvalidOrganizationException('Shop'); } + // Check if machinery with the same name already exists in this organization. + const existingMachinery = await prisma.machinery.findUnique({ + where: { + uniqueMachinery: { + name, + organizationId: organization.organizationId + } + }, + include: { + shops: { + where: { + shopId + } + } + } + }); + + // If machinery exists and is already in this shop, add to the quantity + if (existingMachinery && existingMachinery.shops.length > 0) { + const newQuantity = existingMachinery.shops[0].quantity + quantity; + + const updatedMachinery = await prisma.machinery.update({ + where: { machineryId: existingMachinery.machineryId }, + data: { + shops: { + updateMany: { + where: { shopId }, + data: { quantity: newQuantity } + } + } + }, + ...getMachineryQueryArgs(organization.organizationId) + }); + return machineryTransformer(updatedMachinery); + } + + // If machinery exists but not in this shop, create new shop-machinery relationship + if (existingMachinery) { + const updatedMachinery = await prisma.machinery.update({ + where: { machineryId: existingMachinery.machineryId }, + data: { + shops: { + create: [ + { + shopId, + quantity + } + ] + } + }, + ...getMachineryQueryArgs(organization.organizationId) + }); + return machineryTransformer(updatedMachinery); + } + + // Create new machinery with shop relationship const newMachinery = await prisma.machinery.create({ data: { name, @@ -386,9 +440,11 @@ export default class CalendarService { * @param submitter The user submitting the request, who must be a head or above. * @param machineryId The ID of the machinery to edit. * @param name The new name of the machinery. - * @param shopId The shop ID to associate with the machinery. + * @param shopId The shop ID to associate with the machinery (the new shop if changing shops). * @param quantity The quantity of machinery in the shop. * @param organization The organization for which the machinery is being edited. + * @param originalShopId The original shop ID of the shop-machinery relationship being edited. + * @param shopMachineryId The ID of the shop-machinery relationship being edited. * * @returns The updated machinery object with associated shop machinery. * @@ -402,14 +458,14 @@ export default class CalendarService { name: string, shopId: string, quantity: number, - organization: Organization + organization: Organization, + originalShopId?: string, + shopMachineryId?: string ) { - // Check if user is head or above if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead))) { throw new AccessDeniedException('Only heads and above can edit machinery'); } - // Check if machinery with id exists and belongs to the same organization const existingMachinery = await prisma.machinery.findUnique({ where: { machineryId } }); @@ -422,7 +478,6 @@ export default class CalendarService { throw new InvalidOrganizationException('Shop'); } - // Check if shop with id exists and belongs to the same organization const existingShop = await prisma.shop.findUnique({ where: { shopId } }); @@ -435,22 +490,217 @@ export default class CalendarService { throw new InvalidOrganizationException('Shop'); } - // Update the machinery and its shop machinery relationship - const updatedMachinery = await prisma.machinery.update({ - where: { machineryId }, - data: { - name, - shops: { - updateMany: { - where: {}, + const updatedMachinery = await prisma.$transaction(async (tx) => { + // Find the specific shop-machinery relationship being edited + // This identifies which shop's quantity/relationship we're modifying + let shopMachineryToUpdate; + if (shopMachineryId) { + shopMachineryToUpdate = await tx.shopMachinery.findUnique({ + where: { shopMachineryId } + }); + } else if (originalShopId) { + shopMachineryToUpdate = await tx.shopMachinery.findFirst({ + where: { + machineryId, + shopId: originalShopId + } + }); + } + + // Check if another machinery with the same name already exists + const existingMachineryWithSameName = await tx.machinery.findUnique({ + where: { + uniqueMachinery: { + name, + organizationId: organization.organizationId + } + }, + include: { + shops: { + where: { shopId } + } + } + }); + + // Case 1: Editing results in same name + same shop as existing machinery + // Consolidate by deleting current relationship and adding quantity to existing one + if (existingMachineryWithSameName && existingMachineryWithSameName.shops.length > 0) { + const [existingShopMachinery] = existingMachineryWithSameName.shops; + + // If we're consolidating into a different shop-machinery relationship + if ( + shopMachineryToUpdate && + (shopMachineryToUpdate.shopMachineryId !== existingShopMachinery.shopMachineryId || + existingMachineryWithSameName.machineryId !== machineryId) + ) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } + }); + + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); + + // If this was a different machinery, clean up if it has no more shops + if (existingMachineryWithSameName.machineryId !== machineryId) { + const remainingShops = await tx.shopMachinery.findMany({ + where: { machineryId } + }); + if (remainingShops.length === 0) { + await tx.machinery.delete({ + where: { machineryId } + }); + } + } + } else { + // Same relationship, just update quantity + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity } + }); + } + + const resultMachinery = await tx.machinery.findUnique({ + where: { machineryId: existingMachineryWithSameName.machineryId }, + ...getMachineryQueryArgs(organization.organizationId) + }); + if (!resultMachinery) { + throw new NotFoundException('Machinery', existingMachineryWithSameName.machineryId); + } + return resultMachinery; + } + + // Case 2: Name matches existing machinery but different shop + // Move relationship to the existing machinery but with different shop + if (existingMachineryWithSameName && existingMachineryWithSameName.machineryId !== machineryId) { + if (shopMachineryToUpdate) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } + }); + } + + // Check if existing machinery already has this shop + const existingShopMachinery = await tx.shopMachinery.findUnique({ + where: { + uniqueShopMachinery: { + shopId, + machineryId: existingMachineryWithSameName.machineryId + } + } + }); + + if (existingShopMachinery) { + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); + } else { + await tx.shopMachinery.create({ data: { shopId, + machineryId: existingMachineryWithSameName.machineryId, quantity } + }); + } + + const remainingShops = await tx.shopMachinery.findMany({ + where: { machineryId } + }); + if (remainingShops.length === 0) { + await tx.machinery.delete({ + where: { machineryId } + }); + } + + const resultMachinery = await tx.machinery.findUnique({ + where: { machineryId: existingMachineryWithSameName.machineryId }, + ...getMachineryQueryArgs(organization.organizationId) + }); + if (!resultMachinery) { + throw new NotFoundException('Machinery', existingMachineryWithSameName.machineryId); + } + return resultMachinery; + } + + // Case 3: Normal update - no consolidation needed + // The name doesn't match any existing machinery, or it's the same machinery. + // Just update the shop-machinery relationship and machinery name. + if (shopMachineryToUpdate) { + if (shopMachineryToUpdate.shopId === shopId) { + // Same shop, just update quantity (no shop change needed) + await tx.shopMachinery.update({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId }, + data: { quantity } + }); + } else { + // Different shop - check if target shop already has this machinery + const existingRelationship = await tx.shopMachinery.findUnique({ + where: { + uniqueShopMachinery: { + shopId, + machineryId + } + } + }); + + if (existingRelationship) { + // Target shop already has this machinery, update it and delete old relationship + await tx.shopMachinery.update({ + where: { shopMachineryId: existingRelationship.shopMachineryId }, + data: { quantity } + }); + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } + }); + } else { + // Move relationship to new shop + await tx.shopMachinery.update({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId }, + data: { + shopId, + quantity + } + }); } } - }, - ...getMachineryQueryArgs(organization.organizationId) + } else { + // No existing relationship found, create or update one + const existingRelationship = await tx.shopMachinery.findUnique({ + where: { + uniqueShopMachinery: { + shopId, + machineryId + } + } + }); + + if (existingRelationship) { + await tx.shopMachinery.update({ + where: { shopMachineryId: existingRelationship.shopMachineryId }, + data: { quantity } + }); + } else { + await tx.shopMachinery.create({ + data: { + shopId, + machineryId, + quantity + } + }); + } + } + + // Update machinery name + const updatedMachineryResult = await tx.machinery.update({ + where: { machineryId }, + data: { name }, + ...getMachineryQueryArgs(organization.organizationId) + }); + return updatedMachineryResult; }); return machineryTransformer(updatedMachinery); diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 55b0f52b60..75b2429e95 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -424,13 +424,22 @@ describe('Calendar Tests', () => { //Check that the machinery original shop is not the new shop before editing expect(machinery.shops[0].shop.shopId).not.toBe(newShop.shopId); + // Get the original shop ID to pass to editMachinery + const [originalShopMachinery] = machinery.shops; + const { + shop: { shopId: originalShopId }, + shopMachineryId + } = originalShopMachinery; + const result = await CalendarService.editMachinery( adminUser, machinery.machineryId, 'Updated Shop to Electronics Lab', newShop.shopId, 5, - organization + organization, + originalShopId, + shopMachineryId ); expect(result.name).toEqual('Updated Shop to Electronics Lab'); diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index c972694d74..b16699c46e 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -37,6 +37,8 @@ export const postEditMachinery = async (payload: { name: string; shopId: string; quantity: number; + originalShopId: string; + shopMachineryId: string; }) => { const { machineryId, ...body } = payload; const { data } = await axios.post(apiUrls.calendarEditMachinery(machineryId), body, { diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 7eb5796127..e57b6ddc40 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -48,10 +48,21 @@ export const useCreateMachinery = () => { export const useEditMachinery = (machineryId: string) => { const qc = useQueryClient(); - return useMutation( + return useMutation< + Machinery, + Error, + { shopId: string; machineName: string; quantity: number; originalShopId: string; shopMachineryId: string } + >( async (payload) => { - const { machineName, shopId, quantity } = payload; - return await postEditMachinery({ machineryId, name: machineName, shopId, quantity }); + const { machineName, shopId, quantity, originalShopId, shopMachineryId } = payload; + return await postEditMachinery({ + machineryId, + name: machineName, + shopId, + quantity, + originalShopId, + shopMachineryId + }); }, { onSuccess: () => { diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 9140340ac5..ffd84e8d7c 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -17,7 +17,7 @@ const AdminToolsScheduleConfig: React.FC = () => { const [openCreate, setOpenCreate] = useState(false); const [openCreateMachinery, setOpenCreateMachinery] = useState(false); - const [editMachineryId, setEditMachineryId] = useState(null); + const [editMachinery, setEditMachinery] = useState<{ machineryId: string; shopId: string } | null>(null); if (shopsLoading || machinesLoading) return ; if (shopsError) return ; @@ -141,43 +141,45 @@ const AdminToolsScheduleConfig: React.FC = () => { ) : ( - machines.map((machine) => { - let shopName = '—'; - let machineQuantity = '—'; - if (machine.shops && machine.shops.length > 0) { - shopName = machine.shops[0].shop.name; - machineQuantity = machine.shops[0].quantity.toString(); - } - - return ( - - {machine.name} - {shopName} - - {machineQuantity} - - - - - - setEditMachineryId(machine.machineryId)}> - - - - - - - - - - - - - - - - ); - }) + machines.flatMap( + (machine) => + machine.shops?.map((shopMachinery) => ( + + {machine.name} + {shopMachinery.shop.name} + + {shopMachinery.quantity.toString()} + + + + + + + setEditMachinery({ + machineryId: machine.machineryId, + shopId: shopMachinery.shop.shopId + }) + } + > + + + + + + + + + + + + + + + + )) || [] + ) )} @@ -200,13 +202,22 @@ const AdminToolsScheduleConfig: React.FC = () => { setOpenCreateMachinery(false)} /> {/* Edit Machine Modal */} - {editMachineryId && + {editMachinery && machines && (() => { - const selectedMachine = machines.find((m) => m.machineryId === editMachineryId); + const selectedMachine = machines.find((m) => m.machineryId === editMachinery.machineryId); if (!selectedMachine) return null; - return setEditMachineryId(null)} machinery={selectedMachine} />; + const selectedShopMachinery = selectedMachine.shops?.find((sm) => sm.shop.shopId === editMachinery.shopId); + + if (!selectedShopMachinery) return null; + + const machineryForEdit: typeof selectedMachine = { + ...selectedMachine, + shops: [selectedShopMachinery] + }; + + return setEditMachinery(null)} machinery={machineryForEdit} />; })()} ); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx index 878acdc8ef..7075242541 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx @@ -12,18 +12,30 @@ interface EditMachineryModalProps { } const EditMachineryModal = ({ open, onClose, machinery }: EditMachineryModalProps) => { + const shopMachinery = machinery.shops?.[0]; + const originalShopId = shopMachinery?.shop?.shopId || ''; + const shopMachineryId = shopMachinery?.shopMachineryId || ''; + const { isLoading, isError, error, mutateAsync } = useEditMachinery(machinery.machineryId); const machineryData: MachineryFormValues = { - shopId: machinery.shops?.[0]?.shop?.shopId || '', + shopId: originalShopId, machineName: machinery.name, - quantity: machinery.shops?.[0]?.quantity || 1 + quantity: shopMachinery?.quantity || 1 }; if (isError) return ; if (isLoading) return ; - return ; + const onSubmit = async (data: { shopId: string; machineName: string; quantity: number }) => { + return await mutateAsync({ + ...data, + originalShopId, + shopMachineryId + }); + }; + + return ; }; export default EditMachineryModal; From c611f70a127774ca428afe61f6eb6a7f80d8b729 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 1 Nov 2025 13:27:34 -0400 Subject: [PATCH 171/477] #3634 minor quantity change to accept text input instead of hardcoded list of nums --- .../Machinery/MachineryFormModal.tsx | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx index 43f160d0be..8a8211afa2 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx @@ -1,4 +1,4 @@ -import { Box, FormControl, FormHelperText, Typography, MenuItem, Select, SelectChangeEvent } from '@mui/material'; +import { Box, FormControl, FormHelperText, Typography, MenuItem, Select } from '@mui/material'; import NERFormModal from '../../../../components/NERFormModal'; import ReactHookTextField from '../../../../components/ReactHookTextField'; import { useToast } from '../../../../hooks/toasts.hooks'; @@ -104,7 +104,7 @@ export const MachineryFormModal: React.FC = ({ open, on render={({ field: { onChange, value } }) => ( ) => onChange(parseInt(event.target.value))} - size="small" - sx={{ height: 56, width: '100%', textAlign: 'left' }} - displayEmpty - > - {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((num) => ( - - {num} - - ))} - - )} - /> + {errors.quantity?.message} From ead60b197680c5bb4e3f80e01e9db27e1ce84943 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 1 Nov 2025 18:58:27 -0400 Subject: [PATCH 172/477] endpoint alterations --- .../src/controllers/calendar.controllers.ts | 86 ------------------- src/backend/src/routes/calendar.routes.ts | 41 +-------- src/backend/tests/unit/calendar.test.ts | 71 +++++++++++---- 3 files changed, 56 insertions(+), 142 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 51eb8db49c..7165e7b2c6 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -282,92 +282,6 @@ export default class CalendarController { } } - static async getAllEvents(req: Request, res: Response, next: NextFunction) { - try { - const events = await CalendarService.getFilteredEvents({}, req.organization); - res.status(200).json(events); - } catch (error: unknown) { - next(error); - } - } - - static async getSpecificEvent(req: Request, res: Response, next: NextFunction) { - try { - const { eventId } = req.params; - const filteredEvents = await CalendarService.getFilteredEvents({ eventIds: [eventId] }, req.organization); - res.status(200).json(filteredEvents); - } catch (error: unknown) { - next(error); - } - } - - static async getEventsFromCalendar(req: Request, res: Response, next: NextFunction) { - try { - const { calendarId } = req.params; - const { startPeriod, endPeriod } = req.query; - const parsedStartPeriod = typeof startPeriod === 'string' ? new Date(startPeriod) : undefined; - const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; - const events = await CalendarService.getFilteredEvents( - { calendarIds: [calendarId], startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, - req.organization - ); - res.status(200).json(events); - } catch (error: unknown) { - next(error); - } - } - - static async getSpecificMembersEvents(req: Request, res: Response, next: NextFunction) { - try { - const { memberId } = req.params; - const { startPeriod, endPeriod } = req.query; - const parsedStartPeriod = typeof startPeriod === 'string' ? new Date(startPeriod) : undefined; - const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; - const events = await CalendarService.getFilteredEvents( - { memberIds: [memberId], startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, - req.organization - ); - res.status(200).json(events); - } catch (error: unknown) { - next(error); - } - } - - static async getUnapprovedEvents(req: Request, res: Response, next: NextFunction) { - try { - const filteredEvents = await CalendarService.getFilteredEvents({ approvalStatus: false }, req.organization); - res.status(200).json(filteredEvents); - } catch (error: unknown) { - next(error); - } - } - - static async getApprovedEvents(req: Request, res: Response, next: NextFunction) { - try { - const filteredEvents = await CalendarService.getFilteredEvents({ approvalStatus: true }, req.organization); - res.status(200).json(filteredEvents); - } catch (error: unknown) { - next(error); - } - } - - static async getEventsFromTimeframe(req: Request, res: Response, next: NextFunction) { - try { - const { startPeriod, endPeriod } = req.query; - const parsedStartPeriod = typeof startPeriod === 'string' ? new Date(startPeriod) : undefined; - const parsedEndPeriod = typeof endPeriod === 'string' ? new Date(endPeriod) : undefined; - - const events = await CalendarService.getFilteredEvents( - { startPeriod: parsedStartPeriod, endPeriod: parsedEndPeriod }, - req.organization - ); - - res.status(200).json(events); - } catch (error: unknown) { - next(error); - } - } - static async getAllCalendars(req: Request, res: Response, next: NextFunction) { try { const calendars = await CalendarService.getAllCalendars(req.organization); diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 8a58c5e8d5..7796a56fbe 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -162,49 +162,12 @@ calendarRouter.post( body('eventIds').isArray().optional(), body('eventIds.*').isString().optional(), body('approvalStatus').isBoolean().optional(), - isDate(body('startPeriod')).optional(), - isDate(body('endPeriod')).optional(), + isDate(body('startPeriod')), + isDate(body('endPeriod')), validateInputs, CalendarController.getFilteredEvents ); -// Example get queries using the base filter service, in case it's easier to use these - -// filter via specific ID -calendarRouter.get( - '/events/member/:memberId', - nonEmptyString(query('startPeriod')).optional(), - nonEmptyString(query('endPeriod')).optional(), - validateInputs, - CalendarController.getSpecificMembersEvents -); - -calendarRouter.get( - '/events/calendar/:calendarId', - nonEmptyString(query('startPeriod')).optional(), - nonEmptyString(query('endPeriod')).optional(), - validateInputs, - CalendarController.getEventsFromCalendar -); - -calendarRouter.get('/events/event/:eventId', CalendarController.getSpecificEvent); - -// filter just based on time -calendarRouter.get( - '/events/timeframe', - nonEmptyString(query('startPeriod')).optional(), - nonEmptyString(query('endPeriod')).optional(), - validateInputs, - CalendarController.getEventsFromTimeframe -); - -// unfiltered -calendarRouter.get('/events', CalendarController.getAllEvents); - -// filtered by approval -calendarRouter.get('/events/unapproved', CalendarController.getUnapprovedEvents); -calendarRouter.get('/events/approved', CalendarController.getApprovedEvents); - calendarRouter.get('/calendars', CalendarController.getAllCalendars); export default calendarRouter; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 51fea53db7..c4cc9abfe4 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1323,7 +1323,10 @@ describe('Calendar Tests', () => { 'Weekly team synchronization meeting' ); - const result = await CalendarService.getFilteredEvents({}, organization); + const result = await CalendarService.getFilteredEvents( + { startPeriod: new Date('2020-10-01T09:00:00Z'), endPeriod: new Date('2027-11-01T09:00:00Z') }, + organization + ); expect(result).toStrictEqual([event1, event2]); }); @@ -1528,39 +1531,73 @@ describe('Calendar Tests', () => { 'Weekly team synchronization meeting' ); - const result = await CalendarService.getFilteredEvents({ memberIds: [member.userId] }, organization); + const result = await CalendarService.getFilteredEvents( + { + startPeriod: new Date('2020-10-01T09:00:00Z'), + endPeriod: new Date('2027-11-01T09:00:00Z'), + memberIds: [member.userId] + }, + organization + ); expect(result).toStrictEqual([event1]); }); }); it('fails if memberIds do not exist', async () => { - await expect(CalendarService.getFilteredEvents({ memberIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('User', 'fakeId') - ); + await expect( + CalendarService.getFilteredEvents( + { + startPeriod: new Date('2020-10-01T09:00:00Z'), + endPeriod: new Date('2027-11-01T09:00:00Z'), + memberIds: ['fakeId'] + }, + organization + ) + ).rejects.toThrow(new NotFoundException('User', 'fakeId')); }); it('fails if eventTypeIds do not exist', async () => { - await expect(CalendarService.getFilteredEvents({ eventTypeIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('Event Type', 'fakeId') - ); + await expect( + CalendarService.getFilteredEvents( + { + startPeriod: new Date('2020-10-01T09:00:00Z'), + endPeriod: new Date('2027-11-01T09:00:00Z'), + eventTypeIds: ['fakeId'] + }, + organization + ) + ).rejects.toThrow(new NotFoundException('Event Type', 'fakeId')); }); it('fails if eventIds do not exist', async () => { - await expect(CalendarService.getFilteredEvents({ eventIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('Event', 'fakeId') - ); + await expect( + CalendarService.getFilteredEvents( + { startPeriod: new Date('2020-10-01T09:00:00Z'), endPeriod: new Date('2027-11-01T09:00:00Z'), eventIds: ['fakeId'] }, + organization + ) + ).rejects.toThrow(new NotFoundException('Event', 'fakeId')); }); it('fails if calendarIds do not exist', async () => { - await expect(CalendarService.getFilteredEvents({ calendarIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('Calendar', 'fakeId') - ); + await expect( + CalendarService.getFilteredEvents( + { + startPeriod: new Date('2020-10-01T09:00:00Z'), + endPeriod: new Date('2027-11-01T09:00:00Z'), + calendarIds: ['fakeId'] + }, + organization + ) + ).rejects.toThrow(new NotFoundException('Calendar', 'fakeId')); }); it('fails if teamIds do not exist', async () => { - await expect(CalendarService.getFilteredEvents({ teamIds: ['fakeId'] }, organization)).rejects.toThrow( - new NotFoundException('Team', 'fakeId') - ); + await expect( + CalendarService.getFilteredEvents( + { startPeriod: new Date('2020-10-01T09:00:00Z'), endPeriod: new Date('2027-11-01T09:00:00Z'), teamIds: ['fakeId'] }, + organization + ) + ).rejects.toThrow(new NotFoundException('Team', 'fakeId')); }); describe('Delete Machinery', () => { From 520496e68bb76b8023631fdf881bb4e12c72b3e0 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 1 Nov 2025 19:00:39 -0400 Subject: [PATCH 173/477] lint got stuck in the dryer --- src/backend/src/routes/calendar.routes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 7796a56fbe..b25b29b49c 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { body, param, query } from 'express-validator'; +import { body, param } from 'express-validator'; import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek } from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; From 3649e0a587f05e42466012aab0bb815a8fa5abfb Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 1 Nov 2025 19:32:26 -0400 Subject: [PATCH 174/477] changes? --- .../migration.sql | 0 src/backend/src/services/calendar.services.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/backend/src/prisma/migrations/{20251022010413_calendar => 20251101233144_calendar}/migration.sql (100%) diff --git a/src/backend/src/prisma/migrations/20251022010413_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql similarity index 100% rename from src/backend/src/prisma/migrations/20251022010413_calendar/migration.sql rename to src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 2476f61b2e..6e4c5ef41a 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -359,7 +359,7 @@ export default class CalendarService { ); const computeEndDate = (initial: Date, recurrenceNumber: number) => { - const weeks = Math.max(1, recurrenceNumber ?? 1); + const weeks = Math.max(1, recurrenceNumber ?? 0); return new Date(initial.getTime() + weeks * 7 * 24 * 60 * 60 * 1000); }; From a0bff4b948055094fd4dda5d44f779f1220ccc2b Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sat, 1 Nov 2025 20:36:55 -0400 Subject: [PATCH 175/477] #3569 removed availabilities --- .../src/controllers/calendar.controllers.ts | 8 -- .../src/prisma-query-args/event.query-args.ts | 3 +- .../20250904214316_calendar/migration.sql | 7 - src/backend/src/prisma/schema.prisma | 4 - src/backend/src/prisma/seed.ts | 28 ---- src/backend/src/routes/calendar.routes.ts | 10 -- src/backend/src/services/calendar.services.ts | 126 ++---------------- .../src/transformers/calendar.transformer.ts | 2 - src/backend/tests/unit/calendar.test.ts | 108 +-------------- src/shared/src/types/calendar-types.ts | 4 +- 10 files changed, 14 insertions(+), 286 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index f9aa5da9d6..0bd7f1735b 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -13,7 +13,6 @@ export default class CalendarController { members, location, zoomLink, - availabilities, shop, machinery, workPackage, @@ -33,7 +32,6 @@ export default class CalendarController { members, location, zoomLink, - availabilities, shop, machinery, workPackage, @@ -179,7 +177,6 @@ export default class CalendarController { members, location, zoomLink, - availabilities, shop, machinery, workPackage, @@ -199,7 +196,6 @@ export default class CalendarController { members, location, zoomLink, - availabilities, shop, machinery, workPackage, @@ -248,7 +244,6 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, - availability, approved, approvedByUserId, questionDocument, @@ -268,7 +263,6 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, - availability, approved, approvedByUserId, questionDocument, @@ -295,7 +289,6 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, - availability, approved, approvedByUserId, questionDocument, @@ -316,7 +309,6 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, - availability, approved, approvedByUserId, questionDocument, diff --git a/src/backend/src/prisma-query-args/event.query-args.ts b/src/backend/src/prisma-query-args/event.query-args.ts index a063a71bc8..49c669072a 100644 --- a/src/backend/src/prisma-query-args/event.query-args.ts +++ b/src/backend/src/prisma-query-args/event.query-args.ts @@ -15,7 +15,6 @@ export const getEventQueryArgs = (organizationId: string) => machinery: getMachineryQueryArgs(organizationId), workPackages: getWorkPackageQueryArgs(organizationId), approvedBy: getUserQueryArgs(organizationId), - scheduledTimes: true, - availabilities: true + scheduledTimes: true } }); diff --git a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql index 816c214a91..59c62d53b5 100644 --- a/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20250904214316_calendar/migration.sql @@ -1,9 +1,6 @@ -- CreateEnum CREATE TYPE "public"."DayOfWeek" AS ENUM ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'); --- AlterTable -ALTER TABLE "public"."Availability" ADD COLUMN "eventId" TEXT; - -- CreateTable CREATE TABLE "public"."Shop" ( "shopId" TEXT NOT NULL, @@ -104,7 +101,6 @@ CREATE TABLE "public"."EventType" ( "members" BOOLEAN NOT NULL DEFAULT FALSE, "location" BOOLEAN NOT NULL DEFAULT FALSE, "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, - "availabilities" BOOLEAN NOT NULL DEFAULT FALSE, "shop" BOOLEAN NOT NULL DEFAULT FALSE, "machinery" BOOLEAN NOT NULL DEFAULT FALSE, "workPackage" BOOLEAN NOT NULL DEFAULT FALSE, @@ -257,9 +253,6 @@ ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userCreatedId_fkey" F -- AddForeignKey ALTER TABLE "public"."EventType" ADD CONSTRAINT "EventType_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; --- AddForeignKey -ALTER TABLE "public"."Availability" ADD CONSTRAINT "Availability_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "public"."Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; - -- AddForeignKey ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index da0c108153..e869a4b820 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1048,7 +1048,6 @@ model Event { members User[] @relation(name: "eventAttender") location String? zoomLink String? - availabilities Availability[] shops Shop[] machinery Machinery[] workPackages Work_Package[] @@ -1091,7 +1090,6 @@ model EventType { members Boolean location Boolean zoomLink Boolean - availabilities Boolean shop Boolean machinery Boolean workPackage Boolean @@ -1165,8 +1163,6 @@ model Availability { availabilityId String @id @default(uuid()) scheduleSettingsId String scheduleSettings Schedule_Settings @relation(fields: [scheduleSettingsId], references: [drScheduleSettingsId]) - eventId String? - event Event? @relation(fields: [eventId], references: [eventId]) // Availibilies are integers between 0 and 11 from 10am - 10pm for a given day at hour intervals see meetingTime field in Design_Review availability Int[] diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index eeb2e2fca5..24dd80f8bb 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3168,7 +3168,6 @@ const performSeed: () => Promise = async () => { true, true, true, - true, false, false, false, @@ -3189,7 +3188,6 @@ const performSeed: () => Promise = async () => { true, true, true, - true, false, false, false, @@ -3211,7 +3209,6 @@ const performSeed: () => Promise = async () => { true, false, false, - false, true, true, true, @@ -3232,7 +3229,6 @@ const performSeed: () => Promise = async () => { true, false, false, - false, true, false, true, @@ -3261,12 +3257,6 @@ const performSeed: () => Promise = async () => { allDay: false } ], - [ - { - availability: [9, 10], - dateSet: new Date('2025-10-20T00:00:00.000Z') - } - ], true, batman.userId, 'Conference Room A', @@ -3295,12 +3285,6 @@ const performSeed: () => Promise = async () => { allDay: false } ], - [ - { - availability: [14, 15], - dateSet: new Date('2025-10-22T00:00:00.000Z') - } - ], true, thomasEmrax.userId, 'Electronics Lab', @@ -3329,12 +3313,6 @@ const performSeed: () => Promise = async () => { allDay: false } ], - [ - { - availability: [10, 11], - dateSet: new Date('2025-10-24T00:00:00.000Z') - } - ], true, katara.userId, 'Design Studio', @@ -3363,12 +3341,6 @@ const performSeed: () => Promise = async () => { allDay: false } ], - [ - { - availability: [13, 14], - dateSet: new Date('2025-10-27T00:00:00.000Z') - } - ], true, batman.userId, 'Testing Facility', diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index d6f90d4200..fa768ae789 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -25,7 +25,6 @@ calendarRouter.post( body('members').isBoolean(), body('location').isBoolean(), body('zoomLink').isBoolean(), - body('availabilities').isBoolean(), body('shop').isBoolean(), body('machinery').isBoolean(), body('workPackage').isBoolean(), @@ -64,10 +63,6 @@ calendarRouter.post( intMinZero(body('scheduleSlot.*.recurrenceNumber')), isDate(body('scheduleSlot.*.initialDateScheduled')), body('scheduleSlot.*.allDay').isBoolean(), - body('availability').isArray(), - body('availability.*.availability').isArray(), - intMinZero(body('availability.*.availability.*')), - isDate(body('availability.*.dateSet')), validateInputs, CalendarController.createEvent ); @@ -100,10 +95,6 @@ calendarRouter.post( intMinZero(body('scheduleSlot.*.recurrenceNumber')), isDate(body('scheduleSlot.*.initialDateScheduled')), body('scheduleSlot.*.allDay').isBoolean(), - body('availability').isArray(), - body('availability.*.availability').isArray(), - intMinZero(body('availability.*.availability.*')), - isDate(body('availability.*.dateSet')), validateInputs, CalendarController.editEvent ); @@ -167,7 +158,6 @@ calendarRouter.post( body('members').isBoolean(), body('location').isBoolean(), body('zoomLink').isBoolean(), - body('availabilities').isBoolean(), body('shop').isBoolean(), body('machinery').isBoolean(), body('workPackage').isBoolean(), diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 2983beb585..93e0c4c979 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,18 +1,7 @@ import { calendarTransformer, eventTransformer, machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { Organization } from '@prisma/client'; -import { - isAdmin, - isHead, - EventType, - Shop, - Calendar, - User, - ScheduleSlotCreateArgs, - AvailabilityCreateArgs, - Event, - Machinery -} from 'shared'; +import { isAdmin, isHead, EventType, Shop, Calendar, User, ScheduleSlotCreateArgs, Event, Machinery } from 'shared'; import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException, @@ -43,7 +32,6 @@ export default class CalendarService { * @param members Determines if this event type has members. * @param location Determines if this event type has a location. * @param zoomLink Determines if this event type has a zoom link. - * @param availabilities Determines if this event type has availabilities. * @param shop Determines if a shop is associated with this event type. * @param machinery Determines if machinery is associated with this event type. * @param workPackage Determines if a work package is associated with this event type. @@ -68,7 +56,6 @@ export default class CalendarService { members: boolean, location: boolean, zoomLink: boolean, - availabilities: boolean, shop: boolean, machinery: boolean, workPackage: boolean, @@ -114,7 +101,6 @@ export default class CalendarService { members, location, zoomLink, - availabilities, shop, machinery, workPackage, @@ -203,7 +189,6 @@ export default class CalendarService { * @param workPackageIds An array of work packages associated with the event. * @param documentIds An array of documents associated with the event. * @param scheduleSlots An array of schedule slots associated with the event. - * @param availabilities An array of availabilities associated with the event. * @param approved Determines if the event has been approved. * @param approvedByUserId The ID of the approving user. * @param questionDocument The link to the question document. @@ -227,7 +212,6 @@ export default class CalendarService { workPackageIds: string[], documentIds: string[], scheduleSlot: ScheduleSlotCreateArgs[], - availability: AvailabilityCreateArgs[], approved: boolean, approvedByUserId?: string, questionDocument?: string, @@ -315,31 +299,6 @@ export default class CalendarService { } } - // Ensure each availability has a scheduleSettingsId - const availabilitiesWithScheduleSettings = await Promise.all( - availability.map(async (availability) => { - let scheduleSettings = await prisma.schedule_Settings.findUnique({ - where: { userId: submitter.userId } - }); - - if (!scheduleSettings) { - scheduleSettings = await prisma.schedule_Settings.create({ - data: { - userId: submitter.userId, - personalGmail: '', - personalZoomLink: '' - } - }); - } - - return { - availability: availability.availability, - dateSet: availability.dateSet, - scheduleSettingsId: scheduleSettings.drScheduleSettingsId - }; - }) - ); - const newEvent = await prisma.event.create({ data: { userCreatedId: submitter.userId, @@ -369,11 +328,6 @@ export default class CalendarService { allDay: s.allDay })) }, - availabilities: { - createMany: { - data: availabilitiesWithScheduleSettings - } - }, approved, approvedByUserId, location, @@ -401,7 +355,6 @@ export default class CalendarService { * @param workPackageIds An array of work packages associated with the event. * @param documentIds An array of documents associated with the event. * @param scheduleSlots An array of schedule slots associated with the event. - * @param availabilities An array of availabilities associated with the event. * @param approved Determines if the event has been approved. * @param approvedByUserId The ID of the approving user. * @param questionDocument The link to the question document. @@ -426,7 +379,6 @@ export default class CalendarService { workPackageIds: string[], documentIds: string[], scheduleSlot: ScheduleSlotCreateArgs[], - availability: AvailabilityCreateArgs[], approved: boolean, approvedByUserId?: string, questionDocument?: string, @@ -442,6 +394,14 @@ export default class CalendarService { if (!foundEvent) throw new NotFoundException('Event', eventId); if (foundEvent.dateDeleted) throw new DeletedException('Event', eventId); + const hasPermission = + (await userHasPermission(submitter.userId, organization.organizationId, isAdmin)) || + submitter.userId === foundEvent.userCreatedId; + + if (!hasPermission) { + throw new AccessDeniedException('Only admins and creators can edit events!'); + } + // Validate eventTypeId const foundEventType = await prisma.eventType.findUnique({ where: { eventTypeId } @@ -522,35 +482,10 @@ export default class CalendarService { } } - // Ensure each availability has a scheduleSettingsId - const availabilitiesWithScheduleSettings = await Promise.all( - availability.map(async (availability) => { - let scheduleSettings = await prisma.schedule_Settings.findUnique({ - where: { userId: submitter.userId } - }); - - if (!scheduleSettings) { - scheduleSettings = await prisma.schedule_Settings.create({ - data: { - userId: submitter.userId, - personalGmail: '', - personalZoomLink: '' - } - }); - } - - return { - availability: availability.availability, - dateSet: availability.dateSet, - scheduleSettingsId: scheduleSettings.drScheduleSettingsId - }; - }) - ); - // Use transaction for the update const updatedEvent = await prisma.$transaction(async (tx) => { - // Fetch existing schedule slots and availabilities - const [existingSlots, existingAvailabilities] = await Promise.all([ + // Fetch existing schedule slots + const [existingSlots] = await Promise.all([ tx.scheduleSlot.findMany({ where: { ScheduledEvents: { some: { eventId } } }, select: { @@ -561,14 +496,6 @@ export default class CalendarService { initialDateScheduled: true, allDay: true } - }), - tx.availability.findMany({ - where: { eventId }, - select: { - availability: true, - dateSet: true, - scheduleSettingsId: true - } }) ]); @@ -588,22 +515,6 @@ export default class CalendarService { }); }; - // Checks if all availabilties are the same (ie no changes) - const haveDifferentAvailabilities = ( - a: typeof existingAvailabilities, - b: typeof availabilitiesWithScheduleSettings - ) => { - if (a.length !== b.length) return true; - return a.some((oldAvail, idx) => { - const newAvail = b[idx]; - return ( - oldAvail.scheduleSettingsId !== newAvail.scheduleSettingsId || - oldAvail.availability !== newAvail.availability || - oldAvail.dateSet !== newAvail.dateSet - ); - }); - }; - if (haveDifferentSlots(existingSlots, scheduleSlot)) { await tx.scheduleSlot.deleteMany({ where: { ScheduledEvents: { some: { eventId } } } @@ -625,18 +536,6 @@ export default class CalendarService { ); } - if (haveDifferentAvailabilities(existingAvailabilities, availabilitiesWithScheduleSettings)) { - await tx.availability.deleteMany({ - where: { eventId } - }); - await tx.availability.createMany({ - data: availabilitiesWithScheduleSettings.map((a) => ({ - ...a, - eventId - })) - }); - } - // Update the event with new data return await tx.event.update({ where: { eventId }, @@ -986,7 +885,6 @@ export default class CalendarService { * @param members Determines if this event type has members. * @param location Determines if this event type has a location. * @param zoomLink Determines if this event type has a zoom link. - * @param availabilities Determines if this event type has availabilities. * @param shop Determines if a shop is associated with this event type. * @param machinery Determines if machinery is associated with this event type. * @param workPackage Determines if a work package is associated with this event type. @@ -1011,7 +909,6 @@ export default class CalendarService { members: boolean, location: boolean, zoomLink: boolean, - availabilities: boolean, shop: boolean, machinery: boolean, workPackage: boolean, @@ -1067,7 +964,6 @@ export default class CalendarService { members, location, zoomLink, - availabilities, shop, machinery, workPackage, diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index dd0d34b0f8..f806725fa3 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -51,7 +51,6 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload): workPackages: event.workPackages.map(workPackageTransformer), documentIds: event.documentIds, scheduledTimes: event.scheduledTimes.map(scheduleTimesTransformer), - availability: event.availabilities, approved: event.approved, approvedBy: event.approvedBy ?? undefined, location: event.location ?? undefined, diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 397bc81748..7b6f3bb97b 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -10,17 +10,7 @@ import { import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; -import { - Availability, - AvailabilityCreateArgs, - DayOfWeek, - EventType, - Machinery, - ScheduleSlot, - ScheduleSlotCreateArgs, - Shop, - Event -} from 'shared'; +import { DayOfWeek, EventType, Machinery, ScheduleSlot, ScheduleSlotCreateArgs, Shop, Event } from 'shared'; describe('Calendar Tests', () => { let orgId: string; @@ -80,7 +70,6 @@ describe('Calendar Tests', () => { false, false, false, - false, true ); }); @@ -256,7 +245,6 @@ describe('Calendar Tests', () => { true, true, true, - true, false, false, false, @@ -279,7 +267,6 @@ describe('Calendar Tests', () => { true, true, true, - false, true, false, false, @@ -296,7 +283,6 @@ describe('Calendar Tests', () => { expect(result.members).toBe(true); expect(result.location).toBe(true); expect(result.zoomLink).toBe(false); - expect(result.availability).toBe(true); expect(result.shop).toBe(false); expect(result.machinery).toBe(false); expect(result.workPackage).toBe(false); @@ -627,7 +613,6 @@ describe('Calendar Tests', () => { false, false, false, - false, true ); }); @@ -651,7 +636,6 @@ describe('Calendar Tests', () => { false, false, false, - false, false ) ).rejects.toThrow(new AccessDeniedAdminOnlyException('edit event type')); @@ -676,7 +660,6 @@ describe('Calendar Tests', () => { true, true, true, - true, true ) ).rejects.toThrow(new NotFoundException('Calendar', invalidCalendarId)); @@ -719,7 +702,6 @@ describe('Calendar Tests', () => { false, false, false, - false, false ) ).rejects.toThrow(new InvalidOrganizationException('Calendar')); @@ -738,7 +720,6 @@ describe('Calendar Tests', () => { true, true, false, - false, true, false, false, @@ -761,7 +742,6 @@ describe('Calendar Tests', () => { false, true, true, - true, false, true, true, @@ -832,12 +812,6 @@ describe('Calendar Tests', () => { allDay: false } ]; - const availabilities = [ - { - availability: [9, 10], - dateSet: new Date('2025-10-13') - } - ]; const result = await CalendarService.createEvent( adminUser, @@ -850,7 +824,6 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, - availabilities, true, adminUser.userId, 'https://example.com/questions.pdf', @@ -871,8 +844,6 @@ describe('Calendar Tests', () => { expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); - expect(result.availability).toHaveLength(1); - expect(result.availability[0].availability).toEqual([9, 10]); expect(result.approved).toBe(true); expect(result.approvedBy!.userId).toBe(adminUser.userId); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); @@ -892,12 +863,6 @@ describe('Calendar Tests', () => { allDay: false } ]; - const availabilities = [ - { - availability: [9, 10], - dateSet: new Date('2025-10-13') - } - ]; await expect( CalendarService.createEvent( @@ -911,7 +876,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Event Type', 'non-existent-event-type-id')); @@ -928,12 +892,6 @@ describe('Calendar Tests', () => { allDay: false } ]; - const availabilities = [ - { - availability: [9, 10], - dateSet: new Date('2025-10-13') - } - ]; await expect( CalendarService.createEvent( @@ -947,7 +905,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new InvalidOrganizationException('Event Type')); @@ -955,7 +912,6 @@ describe('Calendar Tests', () => { it('succeeds with minimal inputs', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; const result = await CalendarService.createEvent( adminUser, @@ -968,7 +924,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ); @@ -980,7 +935,6 @@ describe('Calendar Tests', () => { expect(result.workPackages).toHaveLength(0); expect(result.documentIds).toHaveLength(0); expect(result.scheduledTimes).toHaveLength(0); - expect(result.availability).toHaveLength(0); expect(result.approved).toBe(false); expect(result.approvedBy).toBeUndefined(); expect(result.questionDocument).toBeUndefined(); @@ -991,7 +945,6 @@ describe('Calendar Tests', () => { it('fails if memberIds are invalid', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1005,7 +958,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); @@ -1013,7 +965,6 @@ describe('Calendar Tests', () => { it('fails if memberIds belong to a different organization', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1027,7 +978,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('User', otherOrgUser.userId)); @@ -1035,7 +985,6 @@ describe('Calendar Tests', () => { it('fails if shopIds are invalid', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1049,7 +998,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Shop', 'non-existent-shop-id')); @@ -1057,7 +1005,6 @@ describe('Calendar Tests', () => { it('fails if shopIds belong to a different organization', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1071,7 +1018,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Shop', otherOrgShop.shopId)); @@ -1079,7 +1025,6 @@ describe('Calendar Tests', () => { it('fails if machineryIds are invalid', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1093,7 +1038,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Machinery', 'non-existent-machinery-id')); @@ -1101,7 +1045,6 @@ describe('Calendar Tests', () => { it('fails if machineryIds belong to a different organization', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1115,7 +1058,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Machinery', otherOrgMachinery.machineryId)); @@ -1123,7 +1065,6 @@ describe('Calendar Tests', () => { it('fails if workPackageIds are invalid', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1137,7 +1078,6 @@ describe('Calendar Tests', () => { ['non-existent-work-package-id'], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Work Package', 'non-existent-work-package-id')); @@ -1145,7 +1085,6 @@ describe('Calendar Tests', () => { it('fails if approvedByUserId is invalid', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1159,7 +1098,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, true, 'non-existent-user-id' ) @@ -1168,7 +1106,6 @@ describe('Calendar Tests', () => { it('fails if approvedByUserId belongs to a different organization', async () => { const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1182,7 +1119,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, true, otherOrgUser.userId ) @@ -1197,7 +1133,6 @@ describe('Calendar Tests', () => { }); const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1211,7 +1146,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Shop', deletedShop.shopId)); @@ -1232,7 +1166,6 @@ describe('Calendar Tests', () => { }); const scheduleSlots = [] as ScheduleSlot[]; - const availabilities = [] as Availability[]; await expect( CalendarService.createEvent( @@ -1246,7 +1179,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); @@ -1334,7 +1266,6 @@ describe('Calendar Tests', () => { let event: Event; let member: User; let scheduleSlots: ScheduleSlotCreateArgs[]; - let availabilities: AvailabilityCreateArgs[]; beforeEach(async () => { member = await createTestUser(supermanAdmin, orgId); @@ -1348,12 +1279,6 @@ describe('Calendar Tests', () => { allDay: false } ]; - availabilities = [ - { - availability: [9, 10], - dateSet: new Date('2025-10-13') - } - ]; event = await CalendarService.createEvent( adminUser, @@ -1366,7 +1291,6 @@ describe('Calendar Tests', () => { [], ['doc1'], scheduleSlots, - availabilities, false ); }); @@ -1385,7 +1309,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Event', 'non-existent-id')); @@ -1410,7 +1333,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new DeletedException('Event', event.eventId)); @@ -1430,7 +1352,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Event Type', 'non-existent-event-type-id')); @@ -1455,7 +1376,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new DeletedException('Event Type', eventType.eventTypeId)); @@ -1488,7 +1408,6 @@ describe('Calendar Tests', () => { false, false, false, - false, true ); @@ -1505,7 +1424,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new InvalidOrganizationException('Event Type')); @@ -1525,7 +1443,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); @@ -1545,7 +1462,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Shop', 'non-existent-shop-id')); @@ -1571,7 +1487,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Shop', deletedShop.shopId)); @@ -1591,7 +1506,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Machinery', 'non-existent-machinery-id')); @@ -1623,7 +1537,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); @@ -1643,7 +1556,6 @@ describe('Calendar Tests', () => { ['non-existent-wp-id'], [], scheduleSlots, - availabilities, false ) ).rejects.toThrow(new NotFoundException('Work Package', 'non-existent-wp-id')); @@ -1663,7 +1575,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, true, 'non-existent-user-id' ) @@ -1682,12 +1593,6 @@ describe('Calendar Tests', () => { allDay: true } ]; - const newAvailabilities: AvailabilityCreateArgs[] = [ - { - availability: [14, 15], - dateSet: new Date('2025-10-15') - } - ]; const result = await CalendarService.editEvent( adminUser, @@ -1701,7 +1606,6 @@ describe('Calendar Tests', () => { [], ['doc2', 'doc3'], newScheduleSlots, - newAvailabilities, true, adminUser.userId, 'https://updated.com/questions.pdf', @@ -1736,7 +1640,6 @@ describe('Calendar Tests', () => { [], [], [], - [], false ); @@ -1765,12 +1668,6 @@ describe('Calendar Tests', () => { allDay: false } ]; - const availabilities: AvailabilityCreateArgs[] = [ - { - availability: [9, 10], - dateSet: new Date('2025-10-13') - } - ]; event = await CalendarService.createEvent( adminUser, @@ -1783,7 +1680,6 @@ describe('Calendar Tests', () => { [], [], scheduleSlots, - availabilities, false ); }); @@ -1846,7 +1742,6 @@ describe('Calendar Tests', () => { false, false, false, - false, true ); }); @@ -1902,7 +1797,6 @@ describe('Calendar Tests', () => { false, false, false, - false, true ); diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index b3a378819e..61e81a8795 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -1,5 +1,5 @@ import { WorkPackage } from './project-types'; -import { Availability, User } from './user-types'; +import { User } from './user-types'; export interface Calendar { calendarId: string; @@ -51,7 +51,6 @@ export interface EventType { members: boolean; location: boolean; zoomLink: boolean; - availability: boolean; shop: boolean; machinery: boolean; workPackage: boolean; @@ -95,7 +94,6 @@ export interface Event { people: User[]; location?: string; zoomLink?: string; - availability: Availability[]; shops: Shop[]; machinery: Machinery[]; workPackages: WorkPackage[]; From 67d9b1fe06ac9486ad6abb6ff033282597419db9 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 2 Nov 2025 11:56:30 -0500 Subject: [PATCH 176/477] #3634 restructured endpoints to make machine first before doing something with it to shops --- .../src/controllers/calendar.controllers.ts | 24 +- src/backend/src/routes/calendar.routes.ts | 16 +- src/backend/src/services/calendar.services.ts | 352 ++++++++++++------ src/backend/tests/unit/calendar.test.ts | 95 ++--- src/frontend/src/apis/calendar.api.ts | 25 +- src/frontend/src/hooks/calendar.hooks.ts | 41 +- .../Machinery/CreateMachineryModal.tsx | 23 +- .../Machinery/EditMachineryModal.tsx | 54 ++- .../Machinery/MachineryFormModal.tsx | 10 +- src/frontend/src/utils/urls.ts | 2 + 10 files changed, 435 insertions(+), 207 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index a6453aab54..cd763459dd 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -49,9 +49,9 @@ export default class CalendarController { static async createMachinery(req: Request, res: Response, next: NextFunction) { try { - const { name, shopId, quantity } = req.body; + const { name } = req.body; - const machinery = await CalendarService.createMachinery(req.currentUser, name, shopId, quantity, req.organization); + const machinery = await CalendarService.createMachinery(req.currentUser, name, req.organization); res.status(200).json(machinery); } catch (error: unknown) { next(error); @@ -61,17 +61,27 @@ export default class CalendarController { static async editMachinery(req: Request, res: Response, next: NextFunction) { try { const { machineryId } = req.params; - const { name, shopId, quantity, originalShopId, shopMachineryId } = req.body; + const { name } = req.body; - const machinery = await CalendarService.editMachinery( + const machinery = await CalendarService.editMachinery(req.currentUser, machineryId, name, req.organization); + res.status(200).json(machinery); + } catch (error: unknown) { + next(error); + } + } + + static async addMachineryToShop(req: Request, res: Response, next: NextFunction) { + try { + const { machineryId } = req.params; + const { shopId, quantity, originalShopId } = req.body; + + const machinery = await CalendarService.addMachineryToShop( req.currentUser, machineryId, - name, shopId, quantity, req.organization, - originalShopId, - shopMachineryId + originalShopId ); res.status(200).json(machinery); } catch (error: unknown) { diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index fc80bfec34..0496076ff6 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -72,22 +72,22 @@ calendarRouter.post( CalendarController.createEvent ); +calendarRouter.post('/machinery/create', nonEmptyString(body('name')), validateInputs, CalendarController.createMachinery); + calendarRouter.post( - '/machinery/create', + '/machinery/:machineryId/edit', nonEmptyString(body('name')), - nonEmptyString(body('shopId')), - body('quantity').isInt({ min: 1 }), validateInputs, - CalendarController.createMachinery + CalendarController.editMachinery ); calendarRouter.post( - '/machinery/:machineryId/edit', - nonEmptyString(body('name')), + '/machinery/:machineryId/add-to-shop', nonEmptyString(body('shopId')), - body('quantity').isInt({ min: 1 }), + body('quantity').isInt({ min: 0 }), + body('originalShopId').optional().isString(), validateInputs, - CalendarController.editMachinery + CalendarController.addMachineryToShop ); calendarRouter.post('/machinery/:machineryId/delete', CalendarController.deleteMachinery); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 91a0c7685f..edef5fb558 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -143,24 +143,12 @@ export default class CalendarService { * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. * @throws NotFoundException If the shop with the given shopId does not exist. */ - static async createMachinery(submitter: User, name: string, shopId: string, quantity: number, organization: Organization) { + static async createMachinery(submitter: User, name: string, organization: Organization) { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create machinery'); } - const existingShop = await prisma.shop.findUnique({ - where: { shopId } - }); - - if (!existingShop) { - throw new NotFoundException('Shop', shopId); - } - - if (existingShop.organizationId !== organization.organizationId) { - throw new InvalidOrganizationException('Shop'); - } - - // Check if machinery with the same name already exists in this organization. + // Check if machinery with the same name already exists const existingMachinery = await prisma.machinery.findUnique({ where: { uniqueMachinery: { @@ -168,67 +156,20 @@ export default class CalendarService { organizationId: organization.organizationId } }, - include: { - shops: { - where: { - shopId - } - } - } + ...getMachineryQueryArgs(organization.organizationId) }); - // If machinery exists and is already in this shop, add to the quantity - if (existingMachinery && existingMachinery.shops.length > 0) { - const newQuantity = existingMachinery.shops[0].quantity + quantity; - - const updatedMachinery = await prisma.machinery.update({ - where: { machineryId: existingMachinery.machineryId }, - data: { - shops: { - updateMany: { - where: { shopId }, - data: { quantity: newQuantity } - } - } - }, - ...getMachineryQueryArgs(organization.organizationId) - }); - return machineryTransformer(updatedMachinery); - } - - // If machinery exists but not in this shop, create new shop-machinery relationship + // If machinery with same name exists, return it instead of creating a new one + // The addMachineryToShop endpoint will handle consolidation/creation of shop relationships if (existingMachinery) { - const updatedMachinery = await prisma.machinery.update({ - where: { machineryId: existingMachinery.machineryId }, - data: { - shops: { - create: [ - { - shopId, - quantity - } - ] - } - }, - ...getMachineryQueryArgs(organization.organizationId) - }); - return machineryTransformer(updatedMachinery); + return machineryTransformer(existingMachinery); } - // Create new machinery with shop relationship const newMachinery = await prisma.machinery.create({ data: { name, userCreatedId: submitter.userId, - organizationId: organization.organizationId, - shops: { - create: [ - { - shopId, - quantity - } - ] - } + organizationId: organization.organizationId }, ...getMachineryQueryArgs(organization.organizationId) }); @@ -435,35 +376,154 @@ export default class CalendarService { } /** - * Edits an existing machinery and its associated shop machinery. + * Edits an existing machinery name. If the new name matches another existing machinery, + * all shop relationships are merged into that machinery and the old machinery is deleted. * * @param submitter The user submitting the request, who must be a head or above. * @param machineryId The ID of the machinery to edit. * @param name The new name of the machinery. - * @param shopId The shop ID to associate with the machinery (the new shop if changing shops). - * @param quantity The quantity of machinery in the shop. * @param organization The organization for which the machinery is being edited. - * @param originalShopId The original shop ID of the shop-machinery relationship being edited. - * @param shopMachineryId The ID of the shop-machinery relationship being edited. * * @returns The updated machinery object with associated shop machinery. * * @throws AccessDeniedException If the submitter is not a head or above. + * @throws NotFoundException If the machinery with the given ID does not exist. + * @throws InvalidOrganizationException If the machinery does not belong to the same organization. + */ + static async editMachinery(submitter: User, machineryId: string, name: string, organization: Organization) { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead))) { + throw new AccessDeniedException('Only heads and above can edit machinery'); + } + + const existingMachinery = await prisma.machinery.findUnique({ + where: { machineryId } + }); + + if (!existingMachinery) { + throw new NotFoundException('Machinery', machineryId); + } + + if (existingMachinery.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Machinery'); + } + + // If name is the same, just update it (no consolidation needed) + if (existingMachinery.name === name) { + const updatedMachinery = await prisma.machinery.findUnique({ + where: { machineryId }, + ...getMachineryQueryArgs(organization.organizationId) + }); + if (!updatedMachinery) { + throw new NotFoundException('Machinery', machineryId); + } + return machineryTransformer(updatedMachinery); + } + + // Check if another machinery with the same name already exists + const existingMachineryWithSameName = await prisma.machinery.findUnique({ + where: { + uniqueMachinery: { + name, + organizationId: organization.organizationId + } + }, + include: { + shops: true + } + }); + + // If name matches an existing machinery, consolidate by merging all shop relationships + if (existingMachineryWithSameName && existingMachineryWithSameName.machineryId !== machineryId) { + const updatedMachinery = await prisma.$transaction(async (tx) => { + // Get all shop relationships from the machinery being edited + const shopRelationshipsToMove = await tx.shopMachinery.findMany({ + where: { machineryId } + }); + + // Move each shop relationship to the existing machinery + for (const relationship of shopRelationshipsToMove) { + const existingShopMachinery = await tx.shopMachinery.findUnique({ + where: { + uniqueShopMachinery: { + shopId: relationship.shopId, + machineryId: existingMachineryWithSameName.machineryId + } + } + }); + + if (existingShopMachinery) { + // If the target machinery already has this shop, add quantities together + const newQuantity = existingShopMachinery.quantity + relationship.quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); + await tx.shopMachinery.delete({ + where: { shopMachineryId: relationship.shopMachineryId } + }); + } else { + // Move the relationship to the existing machinery + await tx.shopMachinery.update({ + where: { shopMachineryId: relationship.shopMachineryId }, + data: { machineryId: existingMachineryWithSameName.machineryId } + }); + } + } + + // Delete the old machinery (all relationships have been moved) + await tx.machinery.delete({ + where: { machineryId } + }); + + // Return the consolidated machinery + const resultMachinery = await tx.machinery.findUnique({ + where: { machineryId: existingMachineryWithSameName.machineryId }, + ...getMachineryQueryArgs(organization.organizationId) + }); + if (!resultMachinery) { + throw new NotFoundException('Machinery', existingMachineryWithSameName.machineryId); + } + return resultMachinery; + }); + + return machineryTransformer(updatedMachinery); + } + + // No consolidation needed, just update the name + const updatedMachinery = await prisma.machinery.update({ + where: { machineryId }, + data: { name }, + ...getMachineryQueryArgs(organization.organizationId) + }); + + return machineryTransformer(updatedMachinery); + } + + /** + * Adds or updates a machinery to a shop. Handles consolidation when machinery name matches existing machinery. + * If quantity is 0, deletes the shop-machinery relationship (only applicable to editing the machinery modal). + * + * @param submitter The user submitting the request, who must be a head or above. + * @param machineryId The ID of the machinery to add/update. + * @param shopId The ID of the shop to add/update the machinery in. + * @param quantity The quantity of machinery. If 0, the relationship is deleted. + * @param organization The organization context. + * @param originalShopId Optional: The original shop ID when moving/updating an existing relationship. If not provided, this is treated as an "add" operation and quantities are incremented. + * @returns The machinery object with updated shop relationships. + * @throws AccessDeniedException If the submitter is not a head or above. * @throws NotFoundException If the machinery or shop with the given IDs do not exist. * @throws InvalidOrganizationException If the machinery or shop does not belong to the same organization. */ - static async editMachinery( + static async addMachineryToShop( submitter: User, machineryId: string, - name: string, shopId: string, quantity: number, organization: Organization, - originalShopId?: string, - shopMachineryId?: string + originalShopId?: string ) { if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead))) { - throw new AccessDeniedException('Only heads and above can edit machinery'); + throw new AccessDeniedException('Only heads and above can manage shop-machinery relationships'); } const existingMachinery = await prisma.machinery.findUnique({ @@ -475,7 +535,7 @@ export default class CalendarService { } if (existingMachinery.organizationId !== organization.organizationId) { - throw new InvalidOrganizationException('Shop'); + throw new InvalidOrganizationException('Machinery'); } const existingShop = await prisma.shop.findUnique({ @@ -490,15 +550,13 @@ export default class CalendarService { throw new InvalidOrganizationException('Shop'); } + // Use a transaction to ensure all database operations complete atomically. + // This is critical for consolidation logic where we may delete one machinery and merge into another. const updatedMachinery = await prisma.$transaction(async (tx) => { - // Find the specific shop-machinery relationship being edited + // Find the specific shop-machinery relationship being edited (if updating existing) // This identifies which shop's quantity/relationship we're modifying let shopMachineryToUpdate; - if (shopMachineryId) { - shopMachineryToUpdate = await tx.shopMachinery.findUnique({ - where: { shopMachineryId } - }); - } else if (originalShopId) { + if (originalShopId) { shopMachineryToUpdate = await tx.shopMachinery.findFirst({ where: { machineryId, @@ -507,11 +565,14 @@ export default class CalendarService { }); } + // Get the machinery name to check for consolidation + const machineryName = existingMachinery.name; + // Check if another machinery with the same name already exists const existingMachineryWithSameName = await tx.machinery.findUnique({ where: { uniqueMachinery: { - name, + name: machineryName, organizationId: organization.organizationId } }, @@ -522,7 +583,7 @@ export default class CalendarService { } }); - // Case 1: Editing results in same name + same shop as existing machinery + // Case 1: Same name + same shop as existing machinery (consolidation) // Consolidate by deleting current relationship and adding quantity to existing one if (existingMachineryWithSameName && existingMachineryWithSameName.shops.length > 0) { const [existingShopMachinery] = existingMachineryWithSameName.shops; @@ -537,11 +598,18 @@ export default class CalendarService { where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } }); - const newQuantity = existingShopMachinery.quantity + quantity; - await tx.shopMachinery.update({ - where: { shopMachineryId: existingShopMachinery.shopMachineryId }, - data: { quantity: newQuantity } - }); + // Handle quantity: if 0, delete; otherwise add to existing + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } else { + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); + } // If this was a different machinery, clean up if it has no more shops if (existingMachineryWithSameName.machineryId !== machineryId) { @@ -554,12 +622,24 @@ export default class CalendarService { }); } } - } else { - // Same relationship, just update quantity + } else if (quantity === 0) { + // Same relationship, delete if quantity is 0 + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } else if (shopMachineryToUpdate) { + // Edit operation - set/replace quantity await tx.shopMachinery.update({ where: { shopMachineryId: existingShopMachinery.shopMachineryId }, data: { quantity } }); + } else { + // Add operation - increment quantity + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); } const resultMachinery = await tx.machinery.findUnique({ @@ -591,13 +671,22 @@ export default class CalendarService { } }); - if (existingShopMachinery) { + if (quantity === 0) { + // If quantity is 0 and relationship exists, delete it + if (existingShopMachinery) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } + } else if (existingShopMachinery) { + // Add quantity to existing relationship const newQuantity = existingShopMachinery.quantity + quantity; await tx.shopMachinery.update({ where: { shopMachineryId: existingShopMachinery.shopMachineryId }, data: { quantity: newQuantity } }); } else { + // Create new relationship for existing machinery await tx.shopMachinery.create({ data: { shopId, @@ -607,6 +696,7 @@ export default class CalendarService { }); } + // Clean up old machinery if it has no more shops const remainingShops = await tx.shopMachinery.findMany({ where: { machineryId } }); @@ -627,15 +717,19 @@ export default class CalendarService { } // Case 3: Normal update - no consolidation needed - // The name doesn't match any existing machinery, or it's the same machinery. - // Just update the shop-machinery relationship and machinery name. if (shopMachineryToUpdate) { if (shopMachineryToUpdate.shopId === shopId) { - // Same shop, just update quantity (no shop change needed) - await tx.shopMachinery.update({ - where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId }, - data: { quantity } - }); + // Same shop, update quantity or delete if 0 + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } + }); + } else { + await tx.shopMachinery.update({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId }, + data: { quantity } + }); + } } else { // Different shop - check if target shop already has this machinery const existingRelationship = await tx.shopMachinery.findUnique({ @@ -649,10 +743,21 @@ export default class CalendarService { if (existingRelationship) { // Target shop already has this machinery, update it and delete old relationship - await tx.shopMachinery.update({ - where: { shopMachineryId: existingRelationship.shopMachineryId }, - data: { quantity } + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingRelationship.shopMachineryId } + }); + } else { + await tx.shopMachinery.update({ + where: { shopMachineryId: existingRelationship.shopMachineryId }, + data: { quantity } + }); + } + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } }); + } else if (quantity === 0) { + // Move relationship to new shop, but quantity is 0 so delete await tx.shopMachinery.delete({ where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } }); @@ -668,7 +773,8 @@ export default class CalendarService { } } } else { - // No existing relationship found, create or update one + // No originalShopId - this is a create operation (adding machine to shop) + // Check if relationship already exists const existingRelationship = await tx.shopMachinery.findUnique({ where: { uniqueShopMachinery: { @@ -679,11 +785,20 @@ export default class CalendarService { }); if (existingRelationship) { - await tx.shopMachinery.update({ - where: { shopMachineryId: existingRelationship.shopMachineryId }, - data: { quantity } - }); - } else { + // Relationship exists - add quantities together when creating + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingRelationship.shopMachineryId } + }); + } else { + const newQuantity = existingRelationship.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingRelationship.shopMachineryId }, + data: { quantity: newQuantity } + }); + } + } else if (quantity > 0) { + // Create new relationship only if quantity > 0 await tx.shopMachinery.create({ data: { shopId, @@ -694,12 +809,25 @@ export default class CalendarService { } } - // Update machinery name - const updatedMachineryResult = await tx.machinery.update({ + // Clean up machinery if it has no more shops after deletion + if (quantity === 0) { + const remainingShops = await tx.shopMachinery.findMany({ + where: { machineryId } + }); + if (remainingShops.length === 0) { + await tx.machinery.delete({ + where: { machineryId } + }); + } + } + + const updatedMachineryResult = await tx.machinery.findUnique({ where: { machineryId }, - data: { name }, ...getMachineryQueryArgs(organization.organizationId) }); + if (!updatedMachineryResult) { + throw new NotFoundException('Machinery', machineryId); + } return updatedMachineryResult; }); diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 75b2429e95..a82a05a75a 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -46,7 +46,14 @@ describe('Calendar Tests', () => { ); ({ shopId } = shop); - machinery = await CalendarService.createMachinery(adminUser, 'Original Machinery Name', shop.shopId, 1, organization); + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Original Machinery Name', organization); + machinery = await CalendarService.addMachineryToShop( + adminUser, + createdMachinery.machineryId, + shop.shopId, + 1, + organization + ); eventType = await CalendarService.createEventType( adminUser, 'Team Meeting', @@ -296,17 +303,16 @@ describe('Calendar Tests', () => { await CalendarService.createMachinery( await createTestUser(wonderwomanGuest, orgId), 'Captain America Shield Press', - shop.shopId, - 1, organization ) ).rejects.toThrow(new AccessDeniedAdminOnlyException('create machinery')); }); it('Succeeds and creates machinery', async () => { - const result = await CalendarService.createMachinery( - await createTestUser(supermanAdmin, orgId), - 'Iron Man Mark 42 CNC Mill', + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Iron Man Mark 42 CNC Mill', organization); + const result = await CalendarService.addMachineryToShop( + adminUser, + createdMachinery.machineryId, shop.shopId, 2, organization @@ -328,8 +334,6 @@ describe('Calendar Tests', () => { await createTestUser(wonderwomanGuest, orgId), machinery.machineryId, 'Updated Machinery Name', - shop.shopId, - 2, organization ) ).rejects.toThrow(new AccessDeniedException('Only heads and above can edit machinery')); @@ -338,15 +342,7 @@ describe('Calendar Tests', () => { it('Fails if machinery does not exist', async () => { const nonExistentId = 'non-existent-id'; await expect( - async () => - await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), - nonExistentId, - 'Updated Machinery Name', - shop.shopId, - 2, - organization - ) + async () => await CalendarService.editMachinery(adminUser, nonExistentId, 'Updated Machinery Name', organization) ).rejects.toThrow(new NotFoundException('Machinery', nonExistentId)); }); @@ -354,25 +350,26 @@ describe('Calendar Tests', () => { const nonExistentShopId = 'non-existent-shop-id'; await expect( async () => - await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), + await CalendarService.addMachineryToShop( + adminUser, machinery.machineryId, - 'Updated Machinery Name', nonExistentShopId, 2, - organization + organization, + shop.shopId ) ).rejects.toThrow(new NotFoundException('Shop', nonExistentShopId)); }); it('Succeeds and updates machinery for head user', async () => { - const result = await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), + await CalendarService.editMachinery(adminUser, machinery.machineryId, 'Updated Machinery Name', organization); + const result = await CalendarService.addMachineryToShop( + adminUser, machinery.machineryId, - 'Updated Machinery Name', shop.shopId, 3, - organization + organization, + shop.shopId ); expect(result.name).toEqual('Updated Machinery Name'); @@ -382,13 +379,14 @@ describe('Calendar Tests', () => { }); it('Succeeds and updates machinery for admin user', async () => { - const result = await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), + await CalendarService.editMachinery(adminUser, machinery.machineryId, 'Admin Updated Machinery', organization); + const result = await CalendarService.addMachineryToShop( + adminUser, machinery.machineryId, - 'Admin Updated Machinery', shop.shopId, 5, - organization + organization, + shop.shopId ); expect(result.name).toEqual('Admin Updated Machinery'); @@ -398,13 +396,14 @@ describe('Calendar Tests', () => { }); it('Succeeds and updates machinery without description', async () => { - const result = await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), + await CalendarService.editMachinery(adminUser, machinery.machineryId, 'No Description Machinery', organization); + const result = await CalendarService.addMachineryToShop( + adminUser, machinery.machineryId, - 'No Description Machinery', shop.shopId, 2, - organization + organization, + shop.shopId ); expect(result.name).toEqual('No Description Machinery'); @@ -424,22 +423,20 @@ describe('Calendar Tests', () => { //Check that the machinery original shop is not the new shop before editing expect(machinery.shops[0].shop.shopId).not.toBe(newShop.shopId); - // Get the original shop ID to pass to editMachinery + // Get the original shop ID to pass to addMachineryToShop const [originalShopMachinery] = machinery.shops; const { - shop: { shopId: originalShopId }, - shopMachineryId + shop: { shopId: originalShopId } } = originalShopMachinery; - const result = await CalendarService.editMachinery( + await CalendarService.editMachinery(adminUser, machinery.machineryId, 'Updated Shop to Electronics Lab', organization); + const result = await CalendarService.addMachineryToShop( adminUser, machinery.machineryId, - 'Updated Shop to Electronics Lab', newShop.shopId, 5, organization, - originalShopId, - shopMachineryId + originalShopId ); expect(result.name).toEqual('Updated Shop to Electronics Lab'); @@ -504,7 +501,8 @@ describe('Calendar Tests', () => { }); it('also deletes associated shopMachinery bridge rows', async () => { // create a machinery that links to this shop - await CalendarService.createMachinery(adminUser, 'Bridge-Linked', shop.shopId, 1, organization); + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Bridge-Linked', organization); + await CalendarService.addMachineryToShop(adminUser, createdMachinery.machineryId, shop.shopId, 1, organization); //confirm the bridge row exists before delete const before = await prisma.shopMachinery.count({ where: { shopId } }); expect(before).toBeGreaterThan(0); @@ -820,9 +818,10 @@ describe('Calendar Tests', () => { otherOrg ); - otherOrgMachinery = await CalendarService.createMachinery( + const createdOtherOrgMachinery = await CalendarService.createMachinery(otherOrgUser, 'Other Org Machinery', otherOrg); + otherOrgMachinery = await CalendarService.addMachineryToShop( otherOrgUser, - 'Other Org Machinery', + createdOtherOrgMachinery.machineryId, otherOrgShop.shopId, 1, otherOrg @@ -1228,9 +1227,10 @@ describe('Calendar Tests', () => { }); it('fails if machineryIds are deleted', async () => { - const deletedMachinery = await CalendarService.createMachinery( + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Deleted Machinery', organization); + const deletedMachinery = await CalendarService.addMachineryToShop( adminUser, - 'Deleted Machinery', + createdMachinery.machineryId, shop.shopId, 1, organization @@ -1267,9 +1267,10 @@ describe('Calendar Tests', () => { let anotherShop: Shop; beforeEach(async () => { - machineryToDelete = await CalendarService.createMachinery( + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Deletable Machinery', organization); + machineryToDelete = await CalendarService.addMachineryToShop( adminUser, - 'Deletable Machinery', + createdMachinery.machineryId, shop.shopId, 2, organization diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index b16699c46e..0364090e99 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -20,11 +20,10 @@ export const getAllMachinery = () => { }); }; -export const postCreateMachinery = async (payload: { machineName: string; shopId: string; quantity: number }) => { - const { machineName, ...rest } = payload; +export const postCreateMachinery = async (payload: { machineName: string }) => { const { data } = await axios.post( apiUrls.calendarCreateMachinery(), - { name: machineName, ...rest }, + { name: payload.machineName }, { transformResponse: (data) => JSON.parse(data) as Machinery } @@ -32,16 +31,26 @@ export const postCreateMachinery = async (payload: { machineName: string; shopId return data; }; -export const postEditMachinery = async (payload: { +export const postEditMachinery = async (payload: { machineryId: string; name: string }) => { + const { machineryId, name } = payload; + const { data } = await axios.post( + apiUrls.calendarEditMachinery(machineryId), + { name }, + { + transformResponse: (data) => JSON.parse(data) as Machinery + } + ); + return data; +}; + +export const postAddMachineryToShop = async (payload: { machineryId: string; - name: string; shopId: string; quantity: number; - originalShopId: string; - shopMachineryId: string; + originalShopId?: string; }) => { const { machineryId, ...body } = payload; - const { data } = await axios.post(apiUrls.calendarEditMachinery(machineryId), body, { + const { data } = await axios.post(apiUrls.calendarAddMachineryToShop(machineryId), body, { transformResponse: (data) => JSON.parse(data) as Machinery }); return data; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index e57b6ddc40..004ee34f2c 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,6 +1,13 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; import { Shop, Machinery } from 'shared'; -import { getAllShops, postCreateShop, getAllMachinery, postCreateMachinery, postEditMachinery } from '../apis/calendar.api'; +import { + getAllShops, + postCreateShop, + getAllMachinery, + postCreateMachinery, + postEditMachinery, + postAddMachineryToShop +} from '../apis/calendar.api'; export const SHOPS_KEY = ['shops'] as const; export const MACHINERY_KEY = ['machinery'] as const; @@ -34,7 +41,7 @@ export const useAllMachines = () => export const useCreateMachinery = () => { const qc = useQueryClient(); - return useMutation( + return useMutation( async (payload) => { return await postCreateMachinery(payload); }, @@ -48,20 +55,28 @@ export const useCreateMachinery = () => { export const useEditMachinery = (machineryId: string) => { const qc = useQueryClient(); - return useMutation< - Machinery, - Error, - { shopId: string; machineName: string; quantity: number; originalShopId: string; shopMachineryId: string } - >( + return useMutation( async (payload) => { - const { machineName, shopId, quantity, originalShopId, shopMachineryId } = payload; return await postEditMachinery({ machineryId, - name: machineName, - shopId, - quantity, - originalShopId, - shopMachineryId + name: payload.machineName + }); + }, + { + onSuccess: () => { + qc.invalidateQueries(MACHINERY_KEY); + } + } + ); +}; + +export const useAddMachineryToShop = (machineryId: string) => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + return await postAddMachineryToShop({ + machineryId, + ...payload }); }, { diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx index dddb1c70d3..f7c462bccd 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx @@ -1,6 +1,8 @@ import ErrorPage from '../../../ErrorPage'; import LoadingIndicator from '../../../../components/LoadingIndicator'; -import { useCreateMachinery } from '../../../../hooks/calendar.hooks'; +import { useCreateMachinery, MACHINERY_KEY } from '../../../../hooks/calendar.hooks'; +import { postAddMachineryToShop } from '../../../../apis/calendar.api'; +import { useQueryClient } from 'react-query'; import MachineryFormModal from './MachineryFormModal'; interface CreateMachineryModalProps { @@ -9,12 +11,27 @@ interface CreateMachineryModalProps { } const CreateMachineryModal = ({ open, onClose }: CreateMachineryModalProps) => { - const { isLoading, isError, error, mutateAsync } = useCreateMachinery(); + const { isLoading, isError, error, mutateAsync: createMachinery } = useCreateMachinery(); + const queryClient = useQueryClient(); if (isError) return ; if (isLoading) return ; - return ; + const onSubmit = async (data: { shopId: string; machineName: string; quantity: number }) => { + const { machineName, shopId, quantity } = data; + // First create the machinery + const createdMachinery = await createMachinery({ machineName }); + // Then add it to the shop + const result = await postAddMachineryToShop({ + machineryId: createdMachinery.machineryId, + shopId, + quantity + }); + queryClient.invalidateQueries(MACHINERY_KEY); + return result; + }; + + return ; }; export default CreateMachineryModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx index 7075242541..1b5c6dafa9 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx @@ -1,6 +1,8 @@ import ErrorPage from '../../../ErrorPage'; import LoadingIndicator from '../../../../components/LoadingIndicator'; -import { useEditMachinery } from '../../../../hooks/calendar.hooks'; +import { useEditMachinery, useAddMachineryToShop, MACHINERY_KEY } from '../../../../hooks/calendar.hooks'; +import { postAddMachineryToShop } from '../../../../apis/calendar.api'; +import { useQueryClient } from 'react-query'; import { Machinery } from 'shared'; import MachineryFormModal from './MachineryFormModal'; import { MachineryFormValues } from './MachineryFormModal'; @@ -14,9 +16,24 @@ interface EditMachineryModalProps { const EditMachineryModal = ({ open, onClose, machinery }: EditMachineryModalProps) => { const shopMachinery = machinery.shops?.[0]; const originalShopId = shopMachinery?.shop?.shopId || ''; - const shopMachineryId = shopMachinery?.shopMachineryId || ''; + const queryClient = useQueryClient(); - const { isLoading, isError, error, mutateAsync } = useEditMachinery(machinery.machineryId); + const { + isLoading: isEditing, + isError: isEditError, + error: editError, + mutateAsync: editMachinery + } = useEditMachinery(machinery.machineryId); + const { + isLoading: isAdding, + isError: isAddError, + error: addError, + mutateAsync: addMachineryToShop + } = useAddMachineryToShop(machinery.machineryId); + + const isLoading = isEditing || isAdding; + const isError = isEditError || isAddError; + const error = editError || addError; const machineryData: MachineryFormValues = { shopId: originalShopId, @@ -28,10 +45,33 @@ const EditMachineryModal = ({ open, onClose, machinery }: EditMachineryModalProp if (isLoading) return ; const onSubmit = async (data: { shopId: string; machineName: string; quantity: number }) => { - return await mutateAsync({ - ...data, - originalShopId, - shopMachineryId + const { machineName, shopId, quantity } = data; + let currentMachineryId = machinery.machineryId; + + // Check if name changed - this may merge with another machinery + if (machineName !== machinery.name) { + const updatedMachinery = await editMachinery({ machineName }); + currentMachineryId = updatedMachinery.machineryId; + } + + // Update shop/quantity relationship using the current machinery ID + if (currentMachineryId !== machinery.machineryId) { + // Use the API directly since the machinery ID changed after merge + const result = await postAddMachineryToShop({ + machineryId: currentMachineryId, + shopId, + quantity, + originalShopId: originalShopId || undefined + }); + queryClient.invalidateQueries(MACHINERY_KEY); + return result; + } + + // Same machinery ID, use the hook as normal + return await addMachineryToShop({ + shopId, + quantity, + originalShopId: originalShopId || undefined }); }; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx index 8a8211afa2..54c1cdc819 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx @@ -18,12 +18,18 @@ export interface MachineryFormValues { quantity: number; } -const schema = yup.object({ +const createSchema = yup.object({ shopId: yup.string().required('Shop is required'), machineName: yup.string().required('Machine Name is required'), quantity: yup.number().required('Quantity is required').min(1, 'Quantity must be at least 1') }); +const editSchema = yup.object({ + shopId: yup.string().required('Shop is required'), + machineName: yup.string().required('Machine Name is required'), + quantity: yup.number().required('Quantity is required').min(0, 'Quantity cannot be negative') +}); + interface MachineryFormModalProps { open: boolean; onClose: () => void; @@ -45,7 +51,7 @@ export const MachineryFormModal: React.FC = ({ open, on watch, setValue } = useForm({ - resolver: yupResolver(schema), + resolver: yupResolver(initialValues ? editSchema : createSchema), defaultValues: initialValues || defaultValues }); diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index a7f6fbd475..6a46c90cd2 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -436,6 +436,7 @@ const calendarCreateShop = () => `${calendar()}/shop/create`; const calendarMachinery = () => `${calendar()}/machinery`; const calendarCreateMachinery = () => `${calendar()}/machinery/create`; const calendarEditMachinery = (machineryId: string) => `${calendar()}/machinery/${machineryId}/edit`; +const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -737,6 +738,7 @@ export const apiUrls = { calendarMachinery, calendarCreateMachinery, calendarEditMachinery, + calendarAddMachineryToShop, version }; From 1e1883635ba22355fe40a74076ded2b7660b975a Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 2 Nov 2025 13:06:48 -0500 Subject: [PATCH 177/477] #3634 Attempt to fix merge conflict and recommit new endpoint changes --- .../src/controllers/calendar.controllers.ts | 24 +- src/backend/src/prisma/seed.ts | 32 +- src/backend/src/routes/calendar.routes.ts | 16 +- src/backend/src/services/calendar.services.ts | 352 ++++++++++++------ src/backend/tests/unit/calendar.test.ts | 95 ++--- src/frontend/src/apis/calendar.api.ts | 25 +- src/frontend/src/hooks/calendar.hooks.ts | 41 +- .../Machinery/CreateMachineryModal.tsx | 23 +- .../Machinery/EditMachineryModal.tsx | 54 ++- .../Machinery/MachineryFormModal.tsx | 10 +- src/frontend/src/utils/urls.ts | 2 + 11 files changed, 460 insertions(+), 214 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index a6453aab54..cd763459dd 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -49,9 +49,9 @@ export default class CalendarController { static async createMachinery(req: Request, res: Response, next: NextFunction) { try { - const { name, shopId, quantity } = req.body; + const { name } = req.body; - const machinery = await CalendarService.createMachinery(req.currentUser, name, shopId, quantity, req.organization); + const machinery = await CalendarService.createMachinery(req.currentUser, name, req.organization); res.status(200).json(machinery); } catch (error: unknown) { next(error); @@ -61,17 +61,27 @@ export default class CalendarController { static async editMachinery(req: Request, res: Response, next: NextFunction) { try { const { machineryId } = req.params; - const { name, shopId, quantity, originalShopId, shopMachineryId } = req.body; + const { name } = req.body; - const machinery = await CalendarService.editMachinery( + const machinery = await CalendarService.editMachinery(req.currentUser, machineryId, name, req.organization); + res.status(200).json(machinery); + } catch (error: unknown) { + next(error); + } + } + + static async addMachineryToShop(req: Request, res: Response, next: NextFunction) { + try { + const { machineryId } = req.params; + const { shopId, quantity, originalShopId } = req.body; + + const machinery = await CalendarService.addMachineryToShop( req.currentUser, machineryId, - name, shopId, quantity, req.organization, - originalShopId, - shopMachineryId + originalShopId ); res.status(200).json(machinery); } catch (error: unknown) { diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index ea865834e2..ae38238323 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3083,18 +3083,36 @@ const performSeed: () => Promise = async () => { }); // Create machineries and assign to shops - const ironMachine = await MachineryService.createMachinery(thomasEmrax, 'Iron Man CNC Mill', advancedShop.shopId, 1, ner); - const hammer = await MachineryService.createMachinery(thomasEmrax, 'Thor Hammer Lathe', advancedShop.shopId, 2, ner); - const printer = await MachineryService.createMachinery( + const ironMachineCreated = await MachineryService.createMachinery(thomasEmrax, 'Iron Man CNC Mill', ner); + const ironMachine = await MachineryService.addMachineryToShop( thomasEmrax, - 'Spider-Man 3D Printer', + ironMachineCreated.machineryId, + advancedShop.shopId, + 1, + ner + ); + const hammerCreated = await MachineryService.createMachinery(thomasEmrax, 'Thor Hammer Lathe', ner); + const hammer = await MachineryService.addMachineryToShop( + thomasEmrax, + hammerCreated.machineryId, + advancedShop.shopId, + 2, + ner + ); + const printerCreated = await MachineryService.createMachinery(thomasEmrax, 'Spider-Man 3D Printer', ner); + const printer = await MachineryService.addMachineryToShop( + thomasEmrax, + printerCreated.machineryId, electronicsLab.shopId, 1, ner ); - await MachineryService.createMachinery(thomasEmrax, 'Captain America Oscilloscope', electronicsLab.shopId, 3, ner); - await MachineryService.createMachinery(thomasEmrax, 'Hulk Dynamometer', testingFacility.shopId, 1, ner); - await MachineryService.createMachinery(thomasEmrax, 'Black Widow Thermal Camera', testingFacility.shopId, 2, ner); + const captainAmericaCreated = await MachineryService.createMachinery(thomasEmrax, 'Captain America Oscilloscope', ner); + await MachineryService.addMachineryToShop(thomasEmrax, captainAmericaCreated.machineryId, electronicsLab.shopId, 3, ner); + const hulkCreated = await MachineryService.createMachinery(thomasEmrax, 'Hulk Dynamometer', ner); + await MachineryService.addMachineryToShop(thomasEmrax, hulkCreated.machineryId, testingFacility.shopId, 1, ner); + const blackWidowCreated = await MachineryService.createMachinery(thomasEmrax, 'Black Widow Thermal Camera', ner); + await MachineryService.addMachineryToShop(thomasEmrax, blackWidowCreated.machineryId, testingFacility.shopId, 2, ner); // various calendars for testing const calendar = await CalendarService.createCalendar( diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index fc80bfec34..0496076ff6 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -72,22 +72,22 @@ calendarRouter.post( CalendarController.createEvent ); +calendarRouter.post('/machinery/create', nonEmptyString(body('name')), validateInputs, CalendarController.createMachinery); + calendarRouter.post( - '/machinery/create', + '/machinery/:machineryId/edit', nonEmptyString(body('name')), - nonEmptyString(body('shopId')), - body('quantity').isInt({ min: 1 }), validateInputs, - CalendarController.createMachinery + CalendarController.editMachinery ); calendarRouter.post( - '/machinery/:machineryId/edit', - nonEmptyString(body('name')), + '/machinery/:machineryId/add-to-shop', nonEmptyString(body('shopId')), - body('quantity').isInt({ min: 1 }), + body('quantity').isInt({ min: 0 }), + body('originalShopId').optional().isString(), validateInputs, - CalendarController.editMachinery + CalendarController.addMachineryToShop ); calendarRouter.post('/machinery/:machineryId/delete', CalendarController.deleteMachinery); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 91a0c7685f..edef5fb558 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -143,24 +143,12 @@ export default class CalendarService { * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. * @throws NotFoundException If the shop with the given shopId does not exist. */ - static async createMachinery(submitter: User, name: string, shopId: string, quantity: number, organization: Organization) { + static async createMachinery(submitter: User, name: string, organization: Organization) { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create machinery'); } - const existingShop = await prisma.shop.findUnique({ - where: { shopId } - }); - - if (!existingShop) { - throw new NotFoundException('Shop', shopId); - } - - if (existingShop.organizationId !== organization.organizationId) { - throw new InvalidOrganizationException('Shop'); - } - - // Check if machinery with the same name already exists in this organization. + // Check if machinery with the same name already exists const existingMachinery = await prisma.machinery.findUnique({ where: { uniqueMachinery: { @@ -168,67 +156,20 @@ export default class CalendarService { organizationId: organization.organizationId } }, - include: { - shops: { - where: { - shopId - } - } - } + ...getMachineryQueryArgs(organization.organizationId) }); - // If machinery exists and is already in this shop, add to the quantity - if (existingMachinery && existingMachinery.shops.length > 0) { - const newQuantity = existingMachinery.shops[0].quantity + quantity; - - const updatedMachinery = await prisma.machinery.update({ - where: { machineryId: existingMachinery.machineryId }, - data: { - shops: { - updateMany: { - where: { shopId }, - data: { quantity: newQuantity } - } - } - }, - ...getMachineryQueryArgs(organization.organizationId) - }); - return machineryTransformer(updatedMachinery); - } - - // If machinery exists but not in this shop, create new shop-machinery relationship + // If machinery with same name exists, return it instead of creating a new one + // The addMachineryToShop endpoint will handle consolidation/creation of shop relationships if (existingMachinery) { - const updatedMachinery = await prisma.machinery.update({ - where: { machineryId: existingMachinery.machineryId }, - data: { - shops: { - create: [ - { - shopId, - quantity - } - ] - } - }, - ...getMachineryQueryArgs(organization.organizationId) - }); - return machineryTransformer(updatedMachinery); + return machineryTransformer(existingMachinery); } - // Create new machinery with shop relationship const newMachinery = await prisma.machinery.create({ data: { name, userCreatedId: submitter.userId, - organizationId: organization.organizationId, - shops: { - create: [ - { - shopId, - quantity - } - ] - } + organizationId: organization.organizationId }, ...getMachineryQueryArgs(organization.organizationId) }); @@ -435,35 +376,154 @@ export default class CalendarService { } /** - * Edits an existing machinery and its associated shop machinery. + * Edits an existing machinery name. If the new name matches another existing machinery, + * all shop relationships are merged into that machinery and the old machinery is deleted. * * @param submitter The user submitting the request, who must be a head or above. * @param machineryId The ID of the machinery to edit. * @param name The new name of the machinery. - * @param shopId The shop ID to associate with the machinery (the new shop if changing shops). - * @param quantity The quantity of machinery in the shop. * @param organization The organization for which the machinery is being edited. - * @param originalShopId The original shop ID of the shop-machinery relationship being edited. - * @param shopMachineryId The ID of the shop-machinery relationship being edited. * * @returns The updated machinery object with associated shop machinery. * * @throws AccessDeniedException If the submitter is not a head or above. + * @throws NotFoundException If the machinery with the given ID does not exist. + * @throws InvalidOrganizationException If the machinery does not belong to the same organization. + */ + static async editMachinery(submitter: User, machineryId: string, name: string, organization: Organization) { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead))) { + throw new AccessDeniedException('Only heads and above can edit machinery'); + } + + const existingMachinery = await prisma.machinery.findUnique({ + where: { machineryId } + }); + + if (!existingMachinery) { + throw new NotFoundException('Machinery', machineryId); + } + + if (existingMachinery.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Machinery'); + } + + // If name is the same, just update it (no consolidation needed) + if (existingMachinery.name === name) { + const updatedMachinery = await prisma.machinery.findUnique({ + where: { machineryId }, + ...getMachineryQueryArgs(organization.organizationId) + }); + if (!updatedMachinery) { + throw new NotFoundException('Machinery', machineryId); + } + return machineryTransformer(updatedMachinery); + } + + // Check if another machinery with the same name already exists + const existingMachineryWithSameName = await prisma.machinery.findUnique({ + where: { + uniqueMachinery: { + name, + organizationId: organization.organizationId + } + }, + include: { + shops: true + } + }); + + // If name matches an existing machinery, consolidate by merging all shop relationships + if (existingMachineryWithSameName && existingMachineryWithSameName.machineryId !== machineryId) { + const updatedMachinery = await prisma.$transaction(async (tx) => { + // Get all shop relationships from the machinery being edited + const shopRelationshipsToMove = await tx.shopMachinery.findMany({ + where: { machineryId } + }); + + // Move each shop relationship to the existing machinery + for (const relationship of shopRelationshipsToMove) { + const existingShopMachinery = await tx.shopMachinery.findUnique({ + where: { + uniqueShopMachinery: { + shopId: relationship.shopId, + machineryId: existingMachineryWithSameName.machineryId + } + } + }); + + if (existingShopMachinery) { + // If the target machinery already has this shop, add quantities together + const newQuantity = existingShopMachinery.quantity + relationship.quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); + await tx.shopMachinery.delete({ + where: { shopMachineryId: relationship.shopMachineryId } + }); + } else { + // Move the relationship to the existing machinery + await tx.shopMachinery.update({ + where: { shopMachineryId: relationship.shopMachineryId }, + data: { machineryId: existingMachineryWithSameName.machineryId } + }); + } + } + + // Delete the old machinery (all relationships have been moved) + await tx.machinery.delete({ + where: { machineryId } + }); + + // Return the consolidated machinery + const resultMachinery = await tx.machinery.findUnique({ + where: { machineryId: existingMachineryWithSameName.machineryId }, + ...getMachineryQueryArgs(organization.organizationId) + }); + if (!resultMachinery) { + throw new NotFoundException('Machinery', existingMachineryWithSameName.machineryId); + } + return resultMachinery; + }); + + return machineryTransformer(updatedMachinery); + } + + // No consolidation needed, just update the name + const updatedMachinery = await prisma.machinery.update({ + where: { machineryId }, + data: { name }, + ...getMachineryQueryArgs(organization.organizationId) + }); + + return machineryTransformer(updatedMachinery); + } + + /** + * Adds or updates a machinery to a shop. Handles consolidation when machinery name matches existing machinery. + * If quantity is 0, deletes the shop-machinery relationship (only applicable to editing the machinery modal). + * + * @param submitter The user submitting the request, who must be a head or above. + * @param machineryId The ID of the machinery to add/update. + * @param shopId The ID of the shop to add/update the machinery in. + * @param quantity The quantity of machinery. If 0, the relationship is deleted. + * @param organization The organization context. + * @param originalShopId Optional: The original shop ID when moving/updating an existing relationship. If not provided, this is treated as an "add" operation and quantities are incremented. + * @returns The machinery object with updated shop relationships. + * @throws AccessDeniedException If the submitter is not a head or above. * @throws NotFoundException If the machinery or shop with the given IDs do not exist. * @throws InvalidOrganizationException If the machinery or shop does not belong to the same organization. */ - static async editMachinery( + static async addMachineryToShop( submitter: User, machineryId: string, - name: string, shopId: string, quantity: number, organization: Organization, - originalShopId?: string, - shopMachineryId?: string + originalShopId?: string ) { if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead))) { - throw new AccessDeniedException('Only heads and above can edit machinery'); + throw new AccessDeniedException('Only heads and above can manage shop-machinery relationships'); } const existingMachinery = await prisma.machinery.findUnique({ @@ -475,7 +535,7 @@ export default class CalendarService { } if (existingMachinery.organizationId !== organization.organizationId) { - throw new InvalidOrganizationException('Shop'); + throw new InvalidOrganizationException('Machinery'); } const existingShop = await prisma.shop.findUnique({ @@ -490,15 +550,13 @@ export default class CalendarService { throw new InvalidOrganizationException('Shop'); } + // Use a transaction to ensure all database operations complete atomically. + // This is critical for consolidation logic where we may delete one machinery and merge into another. const updatedMachinery = await prisma.$transaction(async (tx) => { - // Find the specific shop-machinery relationship being edited + // Find the specific shop-machinery relationship being edited (if updating existing) // This identifies which shop's quantity/relationship we're modifying let shopMachineryToUpdate; - if (shopMachineryId) { - shopMachineryToUpdate = await tx.shopMachinery.findUnique({ - where: { shopMachineryId } - }); - } else if (originalShopId) { + if (originalShopId) { shopMachineryToUpdate = await tx.shopMachinery.findFirst({ where: { machineryId, @@ -507,11 +565,14 @@ export default class CalendarService { }); } + // Get the machinery name to check for consolidation + const machineryName = existingMachinery.name; + // Check if another machinery with the same name already exists const existingMachineryWithSameName = await tx.machinery.findUnique({ where: { uniqueMachinery: { - name, + name: machineryName, organizationId: organization.organizationId } }, @@ -522,7 +583,7 @@ export default class CalendarService { } }); - // Case 1: Editing results in same name + same shop as existing machinery + // Case 1: Same name + same shop as existing machinery (consolidation) // Consolidate by deleting current relationship and adding quantity to existing one if (existingMachineryWithSameName && existingMachineryWithSameName.shops.length > 0) { const [existingShopMachinery] = existingMachineryWithSameName.shops; @@ -537,11 +598,18 @@ export default class CalendarService { where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } }); - const newQuantity = existingShopMachinery.quantity + quantity; - await tx.shopMachinery.update({ - where: { shopMachineryId: existingShopMachinery.shopMachineryId }, - data: { quantity: newQuantity } - }); + // Handle quantity: if 0, delete; otherwise add to existing + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } else { + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); + } // If this was a different machinery, clean up if it has no more shops if (existingMachineryWithSameName.machineryId !== machineryId) { @@ -554,12 +622,24 @@ export default class CalendarService { }); } } - } else { - // Same relationship, just update quantity + } else if (quantity === 0) { + // Same relationship, delete if quantity is 0 + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } else if (shopMachineryToUpdate) { + // Edit operation - set/replace quantity await tx.shopMachinery.update({ where: { shopMachineryId: existingShopMachinery.shopMachineryId }, data: { quantity } }); + } else { + // Add operation - increment quantity + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); } const resultMachinery = await tx.machinery.findUnique({ @@ -591,13 +671,22 @@ export default class CalendarService { } }); - if (existingShopMachinery) { + if (quantity === 0) { + // If quantity is 0 and relationship exists, delete it + if (existingShopMachinery) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } + } else if (existingShopMachinery) { + // Add quantity to existing relationship const newQuantity = existingShopMachinery.quantity + quantity; await tx.shopMachinery.update({ where: { shopMachineryId: existingShopMachinery.shopMachineryId }, data: { quantity: newQuantity } }); } else { + // Create new relationship for existing machinery await tx.shopMachinery.create({ data: { shopId, @@ -607,6 +696,7 @@ export default class CalendarService { }); } + // Clean up old machinery if it has no more shops const remainingShops = await tx.shopMachinery.findMany({ where: { machineryId } }); @@ -627,15 +717,19 @@ export default class CalendarService { } // Case 3: Normal update - no consolidation needed - // The name doesn't match any existing machinery, or it's the same machinery. - // Just update the shop-machinery relationship and machinery name. if (shopMachineryToUpdate) { if (shopMachineryToUpdate.shopId === shopId) { - // Same shop, just update quantity (no shop change needed) - await tx.shopMachinery.update({ - where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId }, - data: { quantity } - }); + // Same shop, update quantity or delete if 0 + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } + }); + } else { + await tx.shopMachinery.update({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId }, + data: { quantity } + }); + } } else { // Different shop - check if target shop already has this machinery const existingRelationship = await tx.shopMachinery.findUnique({ @@ -649,10 +743,21 @@ export default class CalendarService { if (existingRelationship) { // Target shop already has this machinery, update it and delete old relationship - await tx.shopMachinery.update({ - where: { shopMachineryId: existingRelationship.shopMachineryId }, - data: { quantity } + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingRelationship.shopMachineryId } + }); + } else { + await tx.shopMachinery.update({ + where: { shopMachineryId: existingRelationship.shopMachineryId }, + data: { quantity } + }); + } + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } }); + } else if (quantity === 0) { + // Move relationship to new shop, but quantity is 0 so delete await tx.shopMachinery.delete({ where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } }); @@ -668,7 +773,8 @@ export default class CalendarService { } } } else { - // No existing relationship found, create or update one + // No originalShopId - this is a create operation (adding machine to shop) + // Check if relationship already exists const existingRelationship = await tx.shopMachinery.findUnique({ where: { uniqueShopMachinery: { @@ -679,11 +785,20 @@ export default class CalendarService { }); if (existingRelationship) { - await tx.shopMachinery.update({ - where: { shopMachineryId: existingRelationship.shopMachineryId }, - data: { quantity } - }); - } else { + // Relationship exists - add quantities together when creating + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingRelationship.shopMachineryId } + }); + } else { + const newQuantity = existingRelationship.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingRelationship.shopMachineryId }, + data: { quantity: newQuantity } + }); + } + } else if (quantity > 0) { + // Create new relationship only if quantity > 0 await tx.shopMachinery.create({ data: { shopId, @@ -694,12 +809,25 @@ export default class CalendarService { } } - // Update machinery name - const updatedMachineryResult = await tx.machinery.update({ + // Clean up machinery if it has no more shops after deletion + if (quantity === 0) { + const remainingShops = await tx.shopMachinery.findMany({ + where: { machineryId } + }); + if (remainingShops.length === 0) { + await tx.machinery.delete({ + where: { machineryId } + }); + } + } + + const updatedMachineryResult = await tx.machinery.findUnique({ where: { machineryId }, - data: { name }, ...getMachineryQueryArgs(organization.organizationId) }); + if (!updatedMachineryResult) { + throw new NotFoundException('Machinery', machineryId); + } return updatedMachineryResult; }); diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 75b2429e95..a82a05a75a 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -46,7 +46,14 @@ describe('Calendar Tests', () => { ); ({ shopId } = shop); - machinery = await CalendarService.createMachinery(adminUser, 'Original Machinery Name', shop.shopId, 1, organization); + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Original Machinery Name', organization); + machinery = await CalendarService.addMachineryToShop( + adminUser, + createdMachinery.machineryId, + shop.shopId, + 1, + organization + ); eventType = await CalendarService.createEventType( adminUser, 'Team Meeting', @@ -296,17 +303,16 @@ describe('Calendar Tests', () => { await CalendarService.createMachinery( await createTestUser(wonderwomanGuest, orgId), 'Captain America Shield Press', - shop.shopId, - 1, organization ) ).rejects.toThrow(new AccessDeniedAdminOnlyException('create machinery')); }); it('Succeeds and creates machinery', async () => { - const result = await CalendarService.createMachinery( - await createTestUser(supermanAdmin, orgId), - 'Iron Man Mark 42 CNC Mill', + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Iron Man Mark 42 CNC Mill', organization); + const result = await CalendarService.addMachineryToShop( + adminUser, + createdMachinery.machineryId, shop.shopId, 2, organization @@ -328,8 +334,6 @@ describe('Calendar Tests', () => { await createTestUser(wonderwomanGuest, orgId), machinery.machineryId, 'Updated Machinery Name', - shop.shopId, - 2, organization ) ).rejects.toThrow(new AccessDeniedException('Only heads and above can edit machinery')); @@ -338,15 +342,7 @@ describe('Calendar Tests', () => { it('Fails if machinery does not exist', async () => { const nonExistentId = 'non-existent-id'; await expect( - async () => - await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), - nonExistentId, - 'Updated Machinery Name', - shop.shopId, - 2, - organization - ) + async () => await CalendarService.editMachinery(adminUser, nonExistentId, 'Updated Machinery Name', organization) ).rejects.toThrow(new NotFoundException('Machinery', nonExistentId)); }); @@ -354,25 +350,26 @@ describe('Calendar Tests', () => { const nonExistentShopId = 'non-existent-shop-id'; await expect( async () => - await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), + await CalendarService.addMachineryToShop( + adminUser, machinery.machineryId, - 'Updated Machinery Name', nonExistentShopId, 2, - organization + organization, + shop.shopId ) ).rejects.toThrow(new NotFoundException('Shop', nonExistentShopId)); }); it('Succeeds and updates machinery for head user', async () => { - const result = await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), + await CalendarService.editMachinery(adminUser, machinery.machineryId, 'Updated Machinery Name', organization); + const result = await CalendarService.addMachineryToShop( + adminUser, machinery.machineryId, - 'Updated Machinery Name', shop.shopId, 3, - organization + organization, + shop.shopId ); expect(result.name).toEqual('Updated Machinery Name'); @@ -382,13 +379,14 @@ describe('Calendar Tests', () => { }); it('Succeeds and updates machinery for admin user', async () => { - const result = await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), + await CalendarService.editMachinery(adminUser, machinery.machineryId, 'Admin Updated Machinery', organization); + const result = await CalendarService.addMachineryToShop( + adminUser, machinery.machineryId, - 'Admin Updated Machinery', shop.shopId, 5, - organization + organization, + shop.shopId ); expect(result.name).toEqual('Admin Updated Machinery'); @@ -398,13 +396,14 @@ describe('Calendar Tests', () => { }); it('Succeeds and updates machinery without description', async () => { - const result = await CalendarService.editMachinery( - await createTestUser(supermanAdmin, orgId), + await CalendarService.editMachinery(adminUser, machinery.machineryId, 'No Description Machinery', organization); + const result = await CalendarService.addMachineryToShop( + adminUser, machinery.machineryId, - 'No Description Machinery', shop.shopId, 2, - organization + organization, + shop.shopId ); expect(result.name).toEqual('No Description Machinery'); @@ -424,22 +423,20 @@ describe('Calendar Tests', () => { //Check that the machinery original shop is not the new shop before editing expect(machinery.shops[0].shop.shopId).not.toBe(newShop.shopId); - // Get the original shop ID to pass to editMachinery + // Get the original shop ID to pass to addMachineryToShop const [originalShopMachinery] = machinery.shops; const { - shop: { shopId: originalShopId }, - shopMachineryId + shop: { shopId: originalShopId } } = originalShopMachinery; - const result = await CalendarService.editMachinery( + await CalendarService.editMachinery(adminUser, machinery.machineryId, 'Updated Shop to Electronics Lab', organization); + const result = await CalendarService.addMachineryToShop( adminUser, machinery.machineryId, - 'Updated Shop to Electronics Lab', newShop.shopId, 5, organization, - originalShopId, - shopMachineryId + originalShopId ); expect(result.name).toEqual('Updated Shop to Electronics Lab'); @@ -504,7 +501,8 @@ describe('Calendar Tests', () => { }); it('also deletes associated shopMachinery bridge rows', async () => { // create a machinery that links to this shop - await CalendarService.createMachinery(adminUser, 'Bridge-Linked', shop.shopId, 1, organization); + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Bridge-Linked', organization); + await CalendarService.addMachineryToShop(adminUser, createdMachinery.machineryId, shop.shopId, 1, organization); //confirm the bridge row exists before delete const before = await prisma.shopMachinery.count({ where: { shopId } }); expect(before).toBeGreaterThan(0); @@ -820,9 +818,10 @@ describe('Calendar Tests', () => { otherOrg ); - otherOrgMachinery = await CalendarService.createMachinery( + const createdOtherOrgMachinery = await CalendarService.createMachinery(otherOrgUser, 'Other Org Machinery', otherOrg); + otherOrgMachinery = await CalendarService.addMachineryToShop( otherOrgUser, - 'Other Org Machinery', + createdOtherOrgMachinery.machineryId, otherOrgShop.shopId, 1, otherOrg @@ -1228,9 +1227,10 @@ describe('Calendar Tests', () => { }); it('fails if machineryIds are deleted', async () => { - const deletedMachinery = await CalendarService.createMachinery( + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Deleted Machinery', organization); + const deletedMachinery = await CalendarService.addMachineryToShop( adminUser, - 'Deleted Machinery', + createdMachinery.machineryId, shop.shopId, 1, organization @@ -1267,9 +1267,10 @@ describe('Calendar Tests', () => { let anotherShop: Shop; beforeEach(async () => { - machineryToDelete = await CalendarService.createMachinery( + const createdMachinery = await CalendarService.createMachinery(adminUser, 'Deletable Machinery', organization); + machineryToDelete = await CalendarService.addMachineryToShop( adminUser, - 'Deletable Machinery', + createdMachinery.machineryId, shop.shopId, 2, organization diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index b16699c46e..0364090e99 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -20,11 +20,10 @@ export const getAllMachinery = () => { }); }; -export const postCreateMachinery = async (payload: { machineName: string; shopId: string; quantity: number }) => { - const { machineName, ...rest } = payload; +export const postCreateMachinery = async (payload: { machineName: string }) => { const { data } = await axios.post( apiUrls.calendarCreateMachinery(), - { name: machineName, ...rest }, + { name: payload.machineName }, { transformResponse: (data) => JSON.parse(data) as Machinery } @@ -32,16 +31,26 @@ export const postCreateMachinery = async (payload: { machineName: string; shopId return data; }; -export const postEditMachinery = async (payload: { +export const postEditMachinery = async (payload: { machineryId: string; name: string }) => { + const { machineryId, name } = payload; + const { data } = await axios.post( + apiUrls.calendarEditMachinery(machineryId), + { name }, + { + transformResponse: (data) => JSON.parse(data) as Machinery + } + ); + return data; +}; + +export const postAddMachineryToShop = async (payload: { machineryId: string; - name: string; shopId: string; quantity: number; - originalShopId: string; - shopMachineryId: string; + originalShopId?: string; }) => { const { machineryId, ...body } = payload; - const { data } = await axios.post(apiUrls.calendarEditMachinery(machineryId), body, { + const { data } = await axios.post(apiUrls.calendarAddMachineryToShop(machineryId), body, { transformResponse: (data) => JSON.parse(data) as Machinery }); return data; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index e57b6ddc40..004ee34f2c 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,6 +1,13 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; import { Shop, Machinery } from 'shared'; -import { getAllShops, postCreateShop, getAllMachinery, postCreateMachinery, postEditMachinery } from '../apis/calendar.api'; +import { + getAllShops, + postCreateShop, + getAllMachinery, + postCreateMachinery, + postEditMachinery, + postAddMachineryToShop +} from '../apis/calendar.api'; export const SHOPS_KEY = ['shops'] as const; export const MACHINERY_KEY = ['machinery'] as const; @@ -34,7 +41,7 @@ export const useAllMachines = () => export const useCreateMachinery = () => { const qc = useQueryClient(); - return useMutation( + return useMutation( async (payload) => { return await postCreateMachinery(payload); }, @@ -48,20 +55,28 @@ export const useCreateMachinery = () => { export const useEditMachinery = (machineryId: string) => { const qc = useQueryClient(); - return useMutation< - Machinery, - Error, - { shopId: string; machineName: string; quantity: number; originalShopId: string; shopMachineryId: string } - >( + return useMutation( async (payload) => { - const { machineName, shopId, quantity, originalShopId, shopMachineryId } = payload; return await postEditMachinery({ machineryId, - name: machineName, - shopId, - quantity, - originalShopId, - shopMachineryId + name: payload.machineName + }); + }, + { + onSuccess: () => { + qc.invalidateQueries(MACHINERY_KEY); + } + } + ); +}; + +export const useAddMachineryToShop = (machineryId: string) => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + return await postAddMachineryToShop({ + machineryId, + ...payload }); }, { diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx index dddb1c70d3..f7c462bccd 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx @@ -1,6 +1,8 @@ import ErrorPage from '../../../ErrorPage'; import LoadingIndicator from '../../../../components/LoadingIndicator'; -import { useCreateMachinery } from '../../../../hooks/calendar.hooks'; +import { useCreateMachinery, MACHINERY_KEY } from '../../../../hooks/calendar.hooks'; +import { postAddMachineryToShop } from '../../../../apis/calendar.api'; +import { useQueryClient } from 'react-query'; import MachineryFormModal from './MachineryFormModal'; interface CreateMachineryModalProps { @@ -9,12 +11,27 @@ interface CreateMachineryModalProps { } const CreateMachineryModal = ({ open, onClose }: CreateMachineryModalProps) => { - const { isLoading, isError, error, mutateAsync } = useCreateMachinery(); + const { isLoading, isError, error, mutateAsync: createMachinery } = useCreateMachinery(); + const queryClient = useQueryClient(); if (isError) return ; if (isLoading) return ; - return ; + const onSubmit = async (data: { shopId: string; machineName: string; quantity: number }) => { + const { machineName, shopId, quantity } = data; + // First create the machinery + const createdMachinery = await createMachinery({ machineName }); + // Then add it to the shop + const result = await postAddMachineryToShop({ + machineryId: createdMachinery.machineryId, + shopId, + quantity + }); + queryClient.invalidateQueries(MACHINERY_KEY); + return result; + }; + + return ; }; export default CreateMachineryModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx index 7075242541..1b5c6dafa9 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/EditMachineryModal.tsx @@ -1,6 +1,8 @@ import ErrorPage from '../../../ErrorPage'; import LoadingIndicator from '../../../../components/LoadingIndicator'; -import { useEditMachinery } from '../../../../hooks/calendar.hooks'; +import { useEditMachinery, useAddMachineryToShop, MACHINERY_KEY } from '../../../../hooks/calendar.hooks'; +import { postAddMachineryToShop } from '../../../../apis/calendar.api'; +import { useQueryClient } from 'react-query'; import { Machinery } from 'shared'; import MachineryFormModal from './MachineryFormModal'; import { MachineryFormValues } from './MachineryFormModal'; @@ -14,9 +16,24 @@ interface EditMachineryModalProps { const EditMachineryModal = ({ open, onClose, machinery }: EditMachineryModalProps) => { const shopMachinery = machinery.shops?.[0]; const originalShopId = shopMachinery?.shop?.shopId || ''; - const shopMachineryId = shopMachinery?.shopMachineryId || ''; + const queryClient = useQueryClient(); - const { isLoading, isError, error, mutateAsync } = useEditMachinery(machinery.machineryId); + const { + isLoading: isEditing, + isError: isEditError, + error: editError, + mutateAsync: editMachinery + } = useEditMachinery(machinery.machineryId); + const { + isLoading: isAdding, + isError: isAddError, + error: addError, + mutateAsync: addMachineryToShop + } = useAddMachineryToShop(machinery.machineryId); + + const isLoading = isEditing || isAdding; + const isError = isEditError || isAddError; + const error = editError || addError; const machineryData: MachineryFormValues = { shopId: originalShopId, @@ -28,10 +45,33 @@ const EditMachineryModal = ({ open, onClose, machinery }: EditMachineryModalProp if (isLoading) return ; const onSubmit = async (data: { shopId: string; machineName: string; quantity: number }) => { - return await mutateAsync({ - ...data, - originalShopId, - shopMachineryId + const { machineName, shopId, quantity } = data; + let currentMachineryId = machinery.machineryId; + + // Check if name changed - this may merge with another machinery + if (machineName !== machinery.name) { + const updatedMachinery = await editMachinery({ machineName }); + currentMachineryId = updatedMachinery.machineryId; + } + + // Update shop/quantity relationship using the current machinery ID + if (currentMachineryId !== machinery.machineryId) { + // Use the API directly since the machinery ID changed after merge + const result = await postAddMachineryToShop({ + machineryId: currentMachineryId, + shopId, + quantity, + originalShopId: originalShopId || undefined + }); + queryClient.invalidateQueries(MACHINERY_KEY); + return result; + } + + // Same machinery ID, use the hook as normal + return await addMachineryToShop({ + shopId, + quantity, + originalShopId: originalShopId || undefined }); }; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx index 8a8211afa2..54c1cdc819 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx @@ -18,12 +18,18 @@ export interface MachineryFormValues { quantity: number; } -const schema = yup.object({ +const createSchema = yup.object({ shopId: yup.string().required('Shop is required'), machineName: yup.string().required('Machine Name is required'), quantity: yup.number().required('Quantity is required').min(1, 'Quantity must be at least 1') }); +const editSchema = yup.object({ + shopId: yup.string().required('Shop is required'), + machineName: yup.string().required('Machine Name is required'), + quantity: yup.number().required('Quantity is required').min(0, 'Quantity cannot be negative') +}); + interface MachineryFormModalProps { open: boolean; onClose: () => void; @@ -45,7 +51,7 @@ export const MachineryFormModal: React.FC = ({ open, on watch, setValue } = useForm({ - resolver: yupResolver(schema), + resolver: yupResolver(initialValues ? editSchema : createSchema), defaultValues: initialValues || defaultValues }); diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index a7f6fbd475..6a46c90cd2 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -436,6 +436,7 @@ const calendarCreateShop = () => `${calendar()}/shop/create`; const calendarMachinery = () => `${calendar()}/machinery`; const calendarCreateMachinery = () => `${calendar()}/machinery/create`; const calendarEditMachinery = (machineryId: string) => `${calendar()}/machinery/${machineryId}/edit`; +const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -737,6 +738,7 @@ export const apiUrls = { calendarMachinery, calendarCreateMachinery, calendarEditMachinery, + calendarAddMachineryToShop, version }; From e7039f4779a279bcc140d7bed055a60089fbd7df Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 2 Nov 2025 13:25:16 -0500 Subject: [PATCH 178/477] #3634 fixing build issues --- src/backend/src/services/calendar.services.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 41188b1e10..70309feb56 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1343,6 +1343,18 @@ export default class CalendarService { return shops.map(shopTransformer); } + static async getAllMachinery(organization: Organization): Promise { + const machinery = await prisma.machinery.findMany({ + where: { + organizationId: organization.organizationId, + dateDeleted: null + }, + ...getMachineryQueryArgs(organization.organizationId) + }); + + return machinery.map(machineryTransformer); + } + static async getAllCalendars(organization: Organization): Promise { const calendars = await prisma.calendar.findMany({ where: { From 2b0ea5c0465e1123e25531418089ee003035e1d8 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 2 Nov 2025 14:41:07 -0500 Subject: [PATCH 179/477] new files --- src/frontend/src/app/AppAuthenticated.tsx | 2 + src/frontend/src/layouts/Sidebar/Sidebar.tsx | 5 + .../src/pages/NewCalendarPage/CalendarTab.tsx | 43 ++++ .../src/pages/NewCalendarPage/NewCalendar.tsx | 20 ++ .../pages/NewCalendarPage/NewCalendarPage.tsx | 210 ++++++++++++++++++ src/frontend/src/utils/routes.ts | 2 + 6 files changed, 282 insertions(+) create mode 100644 src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx create mode 100644 src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx create mode 100644 src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx diff --git a/src/frontend/src/app/AppAuthenticated.tsx b/src/frontend/src/app/AppAuthenticated.tsx index 9b58381a39..ed47bc82c6 100644 --- a/src/frontend/src/app/AppAuthenticated.tsx +++ b/src/frontend/src/app/AppAuthenticated.tsx @@ -34,6 +34,7 @@ import { useHomePageContext } from './HomePageContext'; import { useCurrentOrganization } from '../hooks/organizations.hooks'; import Statistics from '../pages/StatisticsPage/Statistics'; import RetrospectiveGanttChartPage from '../pages/RetrospectivePage/Retrospective'; +import NewCalendar from '../pages/NewCalendarPage/NewCalendar'; interface AppAuthenticatedProps { userId: string; @@ -127,6 +128,7 @@ const AppAuthenticated: React.FC = ({ userId, userRole }) + diff --git a/src/frontend/src/layouts/Sidebar/Sidebar.tsx b/src/frontend/src/layouts/Sidebar/Sidebar.tsx index 6fd7b11f4d..687a08ea47 100644 --- a/src/frontend/src/layouts/Sidebar/Sidebar.tsx +++ b/src/frontend/src/layouts/Sidebar/Sidebar.tsx @@ -94,6 +94,11 @@ const Sidebar = ({ drawerOpen, setDrawerOpen, moveContent, setMoveContent }: Sid icon: , route: routes.CALENDAR }, + { + name: 'New Calendar', + icon: , + route: routes.NEW_CALENDAR + }, { name: 'Retrospective', icon: , diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx new file mode 100644 index 0000000000..c39d27bd48 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -0,0 +1,43 @@ +import { routes } from '../../utils/routes'; +import NewCalendarPage from './NewCalendarPage'; +import PageLayout from '../../components/PageLayout'; +import { Box } from '@mui/material'; +import FullPageTabs from '../../components/FullPageTabs'; +import { useState } from 'react'; +import { useCurrentUser } from '../../hooks/users.hooks'; +import { isHead, isLead } from 'shared'; +import SettingsPage from '../SettingsPage/SettingsPage'; + +const CalendarTab: React.FC = () => { + const [tabIndex, setTabIndex] = useState(0); + const user = useCurrentUser(); + const canViewReviews = isHead(user.role) || isLead(user.role); + const tabs = [ + { tabUrlValue: 'mainCalendar', tabName: 'Calendar' }, + { tabUrlValue: 'yourEvents', tabName: 'Your Events' } + ]; + + if (canViewReviews) tabs.push({ tabUrlValue: 'reviews', tabName: 'Review Bookings' }); + + return ( + + + + } + > + {tabIndex === 1 ? : tabIndex === 0 ? : } + + ); +}; + +export default CalendarTab; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx new file mode 100644 index 0000000000..eae83f5005 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx @@ -0,0 +1,20 @@ +/* + * This file is part of NER's FinishLine and licensed under GNU AGPLv3. + * See the LICENSE file in the repository root folder for details. + */ +import { Route, Switch } from 'react-router-dom'; +import { routes } from '../../utils/routes'; +import DesignReviewDetails from '../CalendarPage/DesignReviewDetailPage/DesignReviewDetails'; +import NewCalendarPage from './NewCalendarPage'; +import CalendarTab from './CalendarTab'; + +const NewCalendar: React.FC = () => { + return ( + + + + + ); +}; + +export default NewCalendar; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx new file mode 100644 index 0000000000..b23ec55603 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -0,0 +1,210 @@ +/* + * This file is part of NER's FinishLine and licensed under GNU AGPLv3. + * See the LICENSE file in the repository root folder for details. + */ +import { useState } from 'react'; +import { Box, Grid, Stack, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material'; +import PageLayout from '../../components/PageLayout'; +import { DesignReview, DesignReviewStatus } from 'shared'; +import MonthSelector from '../CalendarPage/CalendarComponents/MonthSelector'; +import CalendarDayCard, { getTeamTypeIcon } from '../CalendarPage/CalendarComponents/CalendarDayCard'; +import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; +import ActionsMenu from '../../components/ActionsMenu'; +import { useAllDesignReviews } from '../../hooks/design-reviews.hooks'; +import ErrorPage from '../ErrorPage'; +import { useCurrentUser } from '../../hooks/users.hooks'; +import { datePipe } from '../../utils/pipes'; +import LoadingIndicator from '../../components/LoadingIndicator'; +import DRCSummaryModal from '../CalendarPage/DesignReviewSummaryModal'; +import { useAllTeamTypes } from '../../hooks/team-types.hooks'; +import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; +import FullPageTabs from '../../components/FullPageTabs'; +import { routes } from '../../utils/routes'; + +const NewCalendarPage = () => { + const theme = useTheme(); + const { + data: allTeamTypes, + isLoading: allTeamTypesLoading, + isError: allTeamTypesIsError, + error: allTeamTypesError + } = useAllTeamTypes(); + + const [displayMonthYear, setDisplayMonthYear] = useState(new Date()); + const { isLoading, isError, error, data: allDesignReviews } = useAllDesignReviews(); + const user = useCurrentUser(); + const [unconfirmedDesignReview, setUnconfirmedDesignReview] = useState(); + const isLargerView = useMediaQuery(theme.breakpoints.up('md')); + const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); + const [tabIndex, setTabIndex] = useState(0); + if (isLoading || !allDesignReviews) return ; + if (isError) return ; + + const confirmedDesignReviews = allDesignReviews; + + const eventDict = new Map(); + confirmedDesignReviews.sort((designReview1, designReview2) => { + if (designReview1.dateScheduled.getTime() === designReview2.dateScheduled.getTime()) { + return designReview1.meetingTimes[0] - designReview2.meetingTimes[0]; + } + return designReview1.dateScheduled.getTime() - designReview2.dateScheduled.getTime(); + }); + + confirmedDesignReviews.forEach((designReview) => { + // Accessing the date actually converts it to local time, which causes the date to be off. This is a workaround. + const date = datePipe( + new Date(designReview.dateScheduled.getTime() - designReview.dateScheduled.getTimezoneOffset() * -60000) + ); + if (eventDict.has(date)) { + eventDict.get(date)?.push(designReview); + } else { + eventDict.set(date, [designReview]); + } + }); + + const currentUserDesignReviews = allDesignReviews.filter( + (designReview) => designReview.userCreated.userId === user.userId && designReview.status !== DesignReviewStatus.DONE + ); + + const startOfEachWeek = [0, 7, 14, 21, 28, 35]; + + const isDayInDifferentMonth = (day: number, week: number) => { + return day < week - 7 || day < 1 || day > week + 7; + }; + + const designReviewButtons = (designReviews: DesignReview[]) => { + return designReviews.map((designReview) => { + return { + icon: getTeamTypeIcon(designReview.teamType.name), + title: designReview.wbsName, + onClick: () => { + setUnconfirmedDesignReview(designReview); + }, + disabled: false + }; + }); + }; + + const NoDRSButton = () => { + return [ + { + title: 'No Design Reviews', + disabled: true, + onClick: () => {} + } + ]; + }; + + const paddingArrayStart = [...Array(calendarPaddingDays(displayMonthYear)).keys()] + .map( + (day) => + daysInMonth(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, displayMonthYear.getDate())) - + day + ) + .reverse(); + const paddingArrayEnd = [ + ...Array(7 - ((daysInMonth(displayMonthYear) + calendarPaddingDays(displayMonthYear)) % 7)).keys() + ].map((day) => day + 1); + const daysThisMonth = paddingArrayStart + .concat([...Array(daysInMonth(displayMonthYear)).keys()].map((day) => day + 1)) + .concat(paddingArrayEnd.length < 7 ? paddingArrayEnd : []); + + const unconfirmedDRSDropdown = ( + + My Unconfirmed DRs + + ); + + if (!allTeamTypes || allTeamTypesLoading) return ; + if (allTeamTypesIsError) return ; + + return ( + <> + {unconfirmedDesignReview && ( + { + setUnconfirmedDesignReview(undefined); + }} + designReview={unconfirmedDesignReview as DesignReview} + teamTypes={allTeamTypes} + /> + )} + + + + + + + + {unconfirmedDRSDropdown} + + + + + + {enumToArray(DAY_NAMES).map((day, index) => ( + + + { + // Day of the week display based on current breakpoint + isLargerView ? day : isExtraSmallView ? day.charAt(0) : day.substring(0, 3) + } + + + ))} + + + + {startOfEachWeek.map((week, weekIndex) => ( + + {daysThisMonth.slice(week, week + 7).map((day, dayIndex) => { + const cardDate = new Date( + displayMonthYear.getFullYear(), + displayMonthYear.getMonth() + (isDayInDifferentMonth(day, week) ? (day > 15 ? -1 : 1) : 0), + day + ); + return ( + + + + + + ); + })} + + ))} + + + + + + + + + + + ); +}; + +export default NewCalendarPage; diff --git a/src/frontend/src/utils/routes.ts b/src/frontend/src/utils/routes.ts index f2317a1af0..f096832e30 100644 --- a/src/frontend/src/utils/routes.ts +++ b/src/frontend/src/utils/routes.ts @@ -66,6 +66,7 @@ const PROJECT_TEMPLATE_EDIT = PROJECT_TEMPLATES + '/edit'; /**************** Design Review Calendar ****************/ const CALENDAR = `/design-review-calendar`; +const NEW_CALENDAR = `/calendar`; const DESIGN_REVIEW_BY_ID = CALENDAR + `/:id`; /**************** Organizations ****************/ @@ -136,6 +137,7 @@ export const routes = { PROJECT_TEMPLATE_EDIT, CALENDAR, + NEW_CALENDAR, DESIGN_REVIEW_BY_ID, ORGANIZATIONS, From ccb83038e349cded511a24f2c14b0653c9dbf347 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 2 Nov 2025 14:57:51 -0500 Subject: [PATCH 180/477] #3569 holy changes --- .../src/controllers/calendar.controllers.ts | 68 ++- .../src/prisma-query-args/event.query-args.ts | 7 +- .../20251101233144_calendar/migration.sql | 104 +++- src/backend/src/prisma/schema.prisma | 93 ++-- src/backend/src/prisma/seed.ts | 40 +- src/backend/src/routes/calendar.routes.ts | 38 +- src/backend/src/services/calendar.services.ts | 483 +++++++++++++++--- .../src/services/design-reviews.services.ts | 18 +- .../src/transformers/calendar.transformer.ts | 18 +- src/backend/src/utils/calendar.utils.ts | 7 + src/backend/src/utils/errors.utils.ts | 10 + src/backend/src/utils/validation.utils.ts | 16 +- src/backend/tests/unit/calendar.test.ts | 422 ++++++--------- src/shared/src/types/calendar-types.ts | 19 +- 14 files changed, 840 insertions(+), 503 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 34934e3eee..ebcc3630de 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -1,5 +1,6 @@ import { NextFunction, Request, Response } from 'express'; import CalendarService from '../services/calendar.services'; +import { getCurrentUserWithUserSettings } from '../utils/auth.utils'; export default class CalendarController { static async createEventType(req: Request, res: Response, next: NextFunction) { @@ -10,7 +11,8 @@ export default class CalendarController { initialDateScheduled, recurring, allDay, - members, + requiredMembers, + optionalMembers, location, zoomLink, shop, @@ -18,7 +20,8 @@ export default class CalendarController { workPackage, questionDocument, documents, - description + description, + onlyHeadsOrAbove } = req.body; const eventType = await CalendarService.createEventType( @@ -29,7 +32,8 @@ export default class CalendarController { initialDateScheduled, recurring, allDay, - members, + requiredMembers, + optionalMembers, location, zoomLink, shop, @@ -37,7 +41,8 @@ export default class CalendarController { workPackage, questionDocument, documents, - description + description, + onlyHeadsOrAbove ); res.status(200).json(eventType); } catch (error: unknown) { @@ -170,11 +175,13 @@ export default class CalendarController { try { const { eventTypeId } = req.params; const { + name, calendarIds, initialDateScheduled, recurring, allDay, - members, + requiredMembers, + optionalMembers, location, zoomLink, shop, @@ -182,7 +189,8 @@ export default class CalendarController { workPackage, questionDocument, documents, - description + description, + onlyHeadsOrAbove } = req.body; const eventType = await CalendarService.editEventType( @@ -190,10 +198,12 @@ export default class CalendarController { req.currentUser, calendarIds, req.organization, + name, initialDateScheduled, recurring, allDay, - members, + requiredMembers, + optionalMembers, location, zoomLink, shop, @@ -201,7 +211,8 @@ export default class CalendarController { workPackage, questionDocument, documents, - description + description, + onlyHeadsOrAbove ); res.status(200).json(eventType); } catch (error: unknown) { @@ -245,8 +256,6 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, - approved, - approvedByUserId, questionDocument, location, zoomLink, @@ -265,8 +274,6 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, - approved, - approvedByUserId, questionDocument, location, zoomLink, @@ -284,16 +291,14 @@ export default class CalendarController { const { title, - eventTypeId, - memberIds, + requiredMemberIds, + optionalMemberIds, teamIds, shopIds, machineryIds, workPackageIds, documentIds, scheduleSlot, - approved, - approvedByUserId, questionDocument, location, zoomLink @@ -303,9 +308,9 @@ export default class CalendarController { req.currentUser, eventId, title, - eventTypeId, req.organization, - memberIds, + requiredMemberIds, + optionalMemberIds, teamIds, shopIds, machineryIds, @@ -313,8 +318,6 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, - approved, - approvedByUserId, questionDocument, location, zoomLink @@ -325,6 +328,31 @@ export default class CalendarController { } } + static async approveEvent(req: Request, res: Response, next: NextFunction) { + try { + const { eventId } = req.params; + + const event = await CalendarService.approveEvent(req.currentUser, eventId, req.organization); + res.status(200).json(event); + } catch (error: unknown) { + next(error); + } + } + + // Mark the current user as confirmed for the given event + static async markUserConfirmed(req: Request, res: Response, next: NextFunction) { + try { + const { availability } = req.body; + const { eventId } = req.params; + const user = await getCurrentUserWithUserSettings(res); + + const updatedEvent = await CalendarService.markUserConfirmed(eventId, availability, user, req.organization); + res.status(200).json(updatedEvent); + } catch (error: unknown) { + next(error); + } + } + //overall filtering for events static async getFilteredEvents(req: Request, res: Response, next: NextFunction) { try { diff --git a/src/backend/src/prisma-query-args/event.query-args.ts b/src/backend/src/prisma-query-args/event.query-args.ts index 9988a68c97..e065657d46 100644 --- a/src/backend/src/prisma-query-args/event.query-args.ts +++ b/src/backend/src/prisma-query-args/event.query-args.ts @@ -1,5 +1,5 @@ import { Prisma } from '@prisma/client'; -import { getUserQueryArgs } from './user.query-args'; +import { getUserQueryArgs, getUserWithSettingsQueryArgs } from './user.query-args'; import { getShopQueryArgs } from './shop.query-args'; import { getMachineryQueryArgs } from './machinery.query-args'; import { getWorkPackageQueryArgs } from './work-packages.query-args'; @@ -11,7 +11,10 @@ export const getEventQueryArgs = (organizationId: string) => Prisma.validator()({ include: { userCreated: getUserQueryArgs(organizationId), - members: getUserQueryArgs(organizationId), + requiredMembers: getUserQueryArgs(organizationId), + optionalMembers: getUserQueryArgs(organizationId), + confirmedMembers: getUserWithSettingsQueryArgs(organizationId), + deniedMembers: getUserQueryArgs(organizationId), teams: getTeamQueryArgs(organizationId), shops: getShopQueryArgs(organizationId), machinery: getMachineryQueryArgs(organizationId), diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index b8f8232ad9..b8a7de0c95 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -99,34 +99,41 @@ CREATE TABLE "public"."EventType" ( "initialDateScheduled" BOOLEAN NOT NULL DEFAULT FALSE, "allDay" BOOLEAN NOT NULL DEFAULT FALSE, "recurring" BOOLEAN NOT NULL DEFAULT FALSE, - "members" BOOLEAN NOT NULL DEFAULT FALSE, + "optionalMembers" BOOLEAN NOT NULL DEFAULT FALSE, + "requiredMembers" BOOLEAN NOT NULL DEFAULT FALSE, "location" BOOLEAN NOT NULL DEFAULT FALSE, "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, "shop" BOOLEAN NOT NULL DEFAULT FALSE, "machinery" BOOLEAN NOT NULL DEFAULT FALSE, "workPackage" BOOLEAN NOT NULL DEFAULT FALSE, "questionDocument" BOOLEAN NOT NULL DEFAULT FALSE, - "documents" BOOLEAN NOT NULL DEFAULT FALSE, + "documents" BOOLEAN NOT NULL DEFAULT FALSE, "description" BOOLEAN NOT NULL DEFAULT FALSE, + "onlyHeadsOrAboveForEventCreation" BOOLEAN NOT NULL DEFAULT FALSE, "organizationId" TEXT NOT NULL, CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") ); --- CreateTable -CREATE TABLE "public"."_EventToScheduleSlot" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, +-- CreateEnum +CREATE TYPE "public"."Event_Status" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'SCHEDULED', 'DONE'); - CONSTRAINT "_EventToScheduleSlot_AB_pkey" PRIMARY KEY ("A","B") -); +-- AlterTable +ALTER TABLE "public"."Design_Review" DROP COLUMN "status", +ADD COLUMN "status" "public"."Event_Status" NOT NULL; + +-- AlterTable +ALTER TABLE "public"."Event" ADD COLUMN "status" "public"."Event_Status" NOT NULL; + +-- DropEnum +DROP TYPE "public"."Design_Review_Status"; -- CreateTable -CREATE TABLE "public"."_eventAttender" ( +CREATE TABLE "public"."_EventToScheduleSlot" ( "A" TEXT NOT NULL, "B" TEXT NOT NULL, - CONSTRAINT "_eventAttender_AB_pkey" PRIMARY KEY ("A","B") + CONSTRAINT "_EventToScheduleSlot_AB_pkey" PRIMARY KEY ("A","B") ); -- CreateTable @@ -169,6 +176,74 @@ CREATE TABLE "public"."_CalendarToEventType" ( CONSTRAINT "_CalendarToEventType_AB_pkey" PRIMARY KEY ("A","B") ); +-- CreateTable +CREATE TABLE "public"."_requiredEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_requiredEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_optionalEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_optionalEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_confirmedEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_confirmedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_deniedEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_deniedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE INDEX "_requiredEventAttendee_B_index" ON "public"."_requiredEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_optionalEventAttendee_B_index" ON "public"."_optionalEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_confirmedEventAttendee_B_index" ON "public"."_confirmedEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_deniedEventAttendee_B_index" ON "public"."_deniedEventAttendee"("B"); + +-- AddForeignKey +ALTER TABLE "public"."_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + -- CreateIndex CREATE UNIQUE INDEX "Shop_name_key" ON "public"."Shop"("name"); @@ -196,9 +271,6 @@ CREATE UNIQUE INDEX "EventType_name_organizationId_key" ON "public"."EventType"( -- CreateIndex CREATE INDEX "_EventToScheduleSlot_B_index" ON "public"."_EventToScheduleSlot"("B"); --- CreateIndex -CREATE INDEX "_eventAttender_B_index" ON "public"."_eventAttender"("B"); - -- CreateIndex CREATE INDEX "_affiliatedTeam_B_index" ON "public"."_affiliatedTeam"("B"); @@ -274,12 +346,6 @@ ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot -- AddForeignKey ALTER TABLE "public"."_EventToScheduleSlot" ADD CONSTRAINT "_EventToScheduleSlot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."ScheduleSlot"("scheduleSlotId") ON DELETE CASCADE ON UPDATE CASCADE; --- AddForeignKey -ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_eventAttender" ADD CONSTRAINT "_eventAttender_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - -- AddForeignKey ALTER TABLE "public"."_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 4c237831a9..0fba9e28f1 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -93,7 +93,7 @@ enum Material_Status { READY_TO_ORDER } -enum Design_Review_Status { +enum Event_Status { UNCONFIRMED CONFIRMED SCHEDULED @@ -263,7 +263,6 @@ model User { createdShops Shop[] @relation(name: "shopCreator") deletedShops Shop[] @relation(name: "shopDeleter") approvedEvents Event[] @relation(name: "eventApprover") - eventsAttended Event[] @relation(name: "eventAttender") createdEvents Event[] @relation(name: "eventCreator") deletedEvents Event[] @relation(name: "eventDeleter") createdCalendars Calendar[] @relation(name: "calendarCreator") @@ -273,6 +272,10 @@ model User { deletedSponsorTiers Sponsor_Tier[] financeDelegateForOrganizations Organization[] @relation(name: "financeDelegates") assignedReimbursementRequests Reimbursement_Request[] @relation(name: "reimbursementRequestAssignee") + requiredEvents Event[] @relation(name: "requiredEventAttendee") + optionalEvents Event[] @relation(name: "optionalEventAttendee") + confirmedEvents Event[] @relation(name: "confirmedEventAttendee") + deniedEvents Event[] @relation(name: "deniedEventAttendee") } model Role { @@ -1055,7 +1058,10 @@ model Event { approvedByUserId String? approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") scheduledTimes ScheduleSlot[] - members User[] @relation(name: "eventAttender") + requiredMembers User[] @relation(name: "requiredEventAttendee") + optionalMembers User[] @relation(name: "optionalEventAttendee") + confirmedMembers User[] @relation(name: "confirmedEventAttendee") + deniedMembers User[] @relation(name: "deniedEventAttendee") teams Team[] @relation(name: "affiliatedTeam") location String? zoomLink String? @@ -1063,6 +1069,7 @@ model Event { machinery Machinery[] workPackages Work_Package[] documentIds String[] + status Event_Status questionDocument String? description String? } @@ -1086,30 +1093,32 @@ model Calendar { } model EventType { - eventTypeId String @id @default(uuid()) - name String - dateCreated DateTime @default(now()) - dateDeleted DateTime? - userCreatedId String - userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) - userDeletedId String? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") - calendars Calendar[] - initialDateScheduled Boolean - allDay Boolean - recurring Boolean - members Boolean - location Boolean - zoomLink Boolean - shop Boolean - machinery Boolean - workPackage Boolean - questionDocument Boolean - documents Boolean - description Boolean - events Event[] - organizationId String - organization Organization @relation(fields: [organizationId], references: [organizationId]) + eventTypeId String @id @default(uuid()) + name String + dateCreated DateTime @default(now()) + dateDeleted DateTime? + userCreatedId String + userCreated User @relation(name: "eventTypeCreator", fields: [userCreatedId], references: [userId]) + userDeletedId String? + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") + calendars Calendar[] + initialDateScheduled Boolean + allDay Boolean + recurring Boolean + requiredMembers Boolean + optionalMembers Boolean + location Boolean + zoomLink Boolean + shop Boolean + machinery Boolean + workPackage Boolean + questionDocument Boolean + documents Boolean + description Boolean + onlyHeadsOrAboveForEventCreation Boolean + events Event[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) @@unique([name, organizationId], name: "uniqueEventType") } @@ -1138,32 +1147,32 @@ model Team_Type { } model Design_Review { - designReviewId String @id @default(uuid()) - dateScheduled DateTime @db.Date + designReviewId String @id @default(uuid()) + dateScheduled DateTime @db.Date // Meeting times are an integer between 0 and 11 from 10am - 10pm for the date scheduled at hour intervals meetingTimes Int[] - initialDateScheduled DateTime @db.Date - dateCreated DateTime @default(now()) @db.Timestamp(3) - userCreated User @relation(fields: [userCreatedId], references: [userId], name: "designReviewCreator") + initialDateScheduled DateTime @db.Date + dateCreated DateTime @default(now()) @db.Timestamp(3) + userCreated User @relation(fields: [userCreatedId], references: [userId], name: "designReviewCreator") userCreatedId String - status Design_Review_Status - teamType Team_Type @relation(fields: [teamTypeId], references: [teamTypeId]) + status Event_Status + teamType Team_Type @relation(fields: [teamTypeId], references: [teamTypeId]) teamTypeId String - requiredMembers User[] @relation(name: "requiredAttendee") - optionalMembers User[] @relation(name: "optionalAttendee") - confirmedMembers User[] @relation(name: "confirmedAttendee") - deniedMembers User[] @relation(name: "deniedAttendee") + requiredMembers User[] @relation(name: "requiredAttendee") + optionalMembers User[] @relation(name: "optionalAttendee") + confirmedMembers User[] @relation(name: "confirmedAttendee") + deniedMembers User[] @relation(name: "deniedAttendee") location String? isOnline Boolean isInPerson Boolean zoomLink String? - attendees User[] @relation(name: "userAttended") - dateDeleted DateTime? @db.Timestamp(3) - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "designReviewDeleter") + attendees User[] @relation(name: "userAttended") + dateDeleted DateTime? @db.Timestamp(3) + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "designReviewDeleter") userDeletedId String? docTemplateLink String? wbsElementId String - wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) + wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) notificationSlackThreads Message_Info[] calendarEventId String? diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 9d840bbeb6..c5d7b272f7 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3197,13 +3197,15 @@ const performSeed: () => Promise = async () => { true, true, true, + true, false, false, false, true, true, false, - true + true, + false ); // design review event type @@ -3217,12 +3219,14 @@ const performSeed: () => Promise = async () => { true, true, true, + true, false, false, false, false, true, true, + true, true ); @@ -3236,6 +3240,7 @@ const performSeed: () => Promise = async () => { false, false, true, + true, false, false, true, @@ -3243,7 +3248,8 @@ const performSeed: () => Promise = async () => { true, false, false, - true + true, + false ); // bay time event type @@ -3258,11 +3264,13 @@ const performSeed: () => Promise = async () => { true, false, false, + false, true, false, true, false, false, + true, true ); @@ -3272,7 +3280,8 @@ const performSeed: () => Promise = async () => { 'Impact Attenuator Design Review', meetingEventType.eventTypeId, ner, - [joeShmoe.userId, joeBlow.userId, batman.userId], + [joeShmoe.userId, joeBlow.userId], + [batman.userId], [], [advancedShop.shopId], [printer.machineryId, hammer.machineryId], @@ -3287,11 +3296,9 @@ const performSeed: () => Promise = async () => { allDay: false } ], - true, - batman.userId, + 'https://docs.google.com/document/d/1_example', 'Conference Room A', 'https://zoom.us/j/123456789', - 'https://docs.google.com/document/d/1_example', 'Review design specifications for the impact attenuator' ); @@ -3300,7 +3307,8 @@ const performSeed: () => Promise = async () => { 'Wiring Harness Installation Planning', meetingEventType.eventTypeId, ner, - [regina.userId, janis.userId, cady.userId], + [regina.userId, janis.userId], + [cady.userId], [], [electronicsLab.shopId], [printer.machineryId], @@ -3316,11 +3324,9 @@ const performSeed: () => Promise = async () => { allDay: false } ], - true, - thomasEmrax.userId, + 'https://docs.google.com/document/d/2_example', 'Electronics Lab', 'https://zoom.us/j/987654321', - 'https://docs.google.com/document/d/2_example', 'Plan the installation process for the wiring harness' ); @@ -3329,7 +3335,8 @@ const performSeed: () => Promise = async () => { 'Appa Plush Design Brainstorm', meetingEventType.eventTypeId, ner, - [katara.userId, sokka.userId, toph.userId], + [katara.userId, sokka.userId], + [toph.userId], [justiceLeague.teamId], [], [], @@ -3345,11 +3352,9 @@ const performSeed: () => Promise = async () => { allDay: false } ], - true, - katara.userId, + 'https://docs.google.com/document/d/3_example', 'Design Studio', 'https://zoom.us/j/456789123', - 'https://docs.google.com/document/d/3_example', 'Brainstorm design ideas for Appa plush prototypes' ); @@ -3358,7 +3363,8 @@ const performSeed: () => Promise = async () => { 'Laser Cannon Prototype Review', meetingEventType.eventTypeId, ner, - [zatanna.userId, superman.userId, wonderwoman.userId], + [zatanna.userId, superman.userId], + [wonderwoman.userId], [orioles.teamId], [testingFacility.shopId], [ironMachine.machineryId, hammer.machineryId], @@ -3374,11 +3380,9 @@ const performSeed: () => Promise = async () => { allDay: false } ], - true, - batman.userId, + 'https://docs.google.com/document/d/4_example', 'Testing Facility', 'https://zoom.us/j/789123456', - 'https://docs.google.com/document/d/4_example', 'Review progress and test results for laser cannon prototype' ); }; diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 878271fa83..cd5b626857 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -22,7 +22,8 @@ calendarRouter.post( body('initialDateScheduled').isBoolean(), body('allDay').isBoolean(), body('recurring').isBoolean(), - body('members').isBoolean(), + body('requiredMembers').isBoolean(), + body('optionalMembers').isBoolean(), body('location').isBoolean(), body('zoomLink').isBoolean(), body('shop').isBoolean(), @@ -31,6 +32,7 @@ calendarRouter.post( body('questionDocument').isBoolean(), body('documents').isBoolean(), body('description').isBoolean(), + body('onlyHeadsOrAbove').isBoolean(), validateInputs, CalendarController.createEventType ); @@ -39,10 +41,10 @@ calendarRouter.post( '/event/create', nonEmptyString(body('title')), body('eventTypeId').isString(), - body('approved').isBoolean(), - body('approvedByUserId').optional().isString(), - body('memberIds').isArray(), - body('memberIds.*').isString(), + body('requiredMemberIds').isArray(), + nonEmptyString(body('requiredMemberIds.*')), + body('optionalMemberIds').isArray(), + nonEmptyString(body('optionalMemberIds.*')), body('teamIds').isArray(), body('teamIds.*').isString(), body('location').optional().isString(), @@ -72,11 +74,10 @@ calendarRouter.post( calendarRouter.post( '/event/:eventId/edit', nonEmptyString(body('title')), - body('eventTypeId').isString(), - body('approved').isBoolean(), - body('approvedByUserId').optional().isString(), - body('memberIds').isArray(), - body('memberIds.*').isString(), + body('requiredMemberIds').isArray(), + nonEmptyString(body('requiredMemberIds.*')), + body('optionalMemberIds').isArray(), + nonEmptyString(body('optionalMemberIds.*')), body('teamIds').isArray(), body('teamIds.*').isString(), body('location').optional().isString(), @@ -103,6 +104,18 @@ calendarRouter.post( CalendarController.editEvent ); +calendarRouter.post('/event/:eventId/approve', CalendarController.approveEvent); + +calendarRouter.post( + '/event/:eventId/confirm-schedule', + body('availability').isArray(), + body('availability.*.availability').isArray(), + intMinZero(body('availability.*.availability.*')), + isDate(body('availability.*.dateSet')), + validateInputs, + CalendarController.markUserConfirmed +); + calendarRouter.post('/event/:eventId/delete', CalendarController.deleteEvent); calendarRouter.post( @@ -154,12 +167,14 @@ calendarRouter.post( calendarRouter.post( '/event-type/:eventTypeId/edit', + nonEmptyString(body('name')), body('calendarIds').isArray(), body('calendarIds.*').isString(), body('initialDateScheduled').isBoolean(), body('allDay').isBoolean(), body('recurring').isBoolean(), - body('members').isBoolean(), + body('requiredMembers').isBoolean(), + body('optionalMembers').isBoolean(), body('location').isBoolean(), body('zoomLink').isBoolean(), body('shop').isBoolean(), @@ -168,6 +183,7 @@ calendarRouter.post( body('questionDocument').isBoolean(), body('documents').isBoolean(), body('description').isBoolean(), + body('onlyHeadsOrAbove').isBoolean(), validateInputs, CalendarController.editEventType ); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index f695d69a46..ed1a577d81 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,6 +1,6 @@ import { calendarTransformer, eventTransformer, machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; -import { Organization } from '@prisma/client'; +import { Event_Status, Organization } from '@prisma/client'; import { isAdmin, isHead, @@ -9,27 +9,38 @@ import { Calendar, User, ScheduleSlotCreateArgs, - AvailabilityCreateArgs, Event, FilterArgs, - Machinery + Machinery, + AvailabilityCreateArgs, + EventStatus } from 'shared'; import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException, AccessDeniedException, DeletedException, + HttpException, + InvalidEventTypeConfigurationException, InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; -import { userHasPermission } from '../utils/users.utils'; +import { + areUsersinList, + getPrismaQueryUserIds, + getUsers, + updateUserAvailability, + userHasPermission +} from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { shopTransformer } from '../transformers/calendar.transformer'; import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; import { getCalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; import { getEventQueryArgs } from '../prisma-query-args/event.query-args'; -import { buildScheduledTimesOverlap } from '../utils/calendar.utils'; +import { buildScheduledTimesOverlap, isUserOnEvent } from '../utils/calendar.utils'; +import { UserWithSettings } from '../utils/auth.utils'; +import { getUserScheduleSettingsQueryArgs } from '../prisma-query-args/user.query-args'; export default class CalendarService { /** @@ -42,7 +53,8 @@ export default class CalendarService { * @param initialDateScheduled Determines if a date is associated with this event type. * @param recurring Determines if this event type is recurring. * @param allDay Determines if this event type is all day. - * @param members Determines if this event type has members. + * @param requiredMembers Determines if this event type has required members. + * @param optionalMembers Determines if this event type has optional members. * @param location Determines if this event type has a location. * @param zoomLink Determines if this event type has a zoom link. * @param shop Determines if a shop is associated with this event type. @@ -51,6 +63,7 @@ export default class CalendarService { * @param questionDocument Determines if a question document is associated with this event type. * @param documents Determines if documents are associates with this event type. * @param description Determines if a description is associated with this event type. + * @param onlyHeadsOrAbove Determines if events under this event type can only be created by heads or above. * * @returns The created event type. * @@ -66,7 +79,8 @@ export default class CalendarService { initialDateScheduled: boolean, recurring: boolean, allDay: boolean, - members: boolean, + requiredMembers: boolean, + optionalMembers: boolean, location: boolean, zoomLink: boolean, shop: boolean, @@ -74,7 +88,8 @@ export default class CalendarService { workPackage: boolean, questionDocument: boolean, documents: boolean, - description: boolean + description: boolean, + onlyHeadsOrAbove: boolean ): Promise { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create event type'); @@ -111,7 +126,8 @@ export default class CalendarService { initialDateScheduled, recurring, allDay, - members, + requiredMembers, + optionalMembers, location, zoomLink, shop, @@ -120,6 +136,7 @@ export default class CalendarService { questionDocument, documents, description, + onlyHeadsOrAboveForEventCreation: onlyHeadsOrAbove, organizationId: organization.organizationId }, ...getEventTypeQueryArgs(organization.organizationId) @@ -196,14 +213,13 @@ export default class CalendarService { * @param title The title of the event. * @param eventTypeId The event type id the event is associated with. * @param organization The organization for which the event type is being created. - * @param memberIds An array of member ids that are invited to the event. + * @param requiredMemberIds An array of required member ids that are invited to the event. + * @param optionalMemberIds An array of optional member ids that are invited to the event. * @param shopIds An array of shops associated with the event. * @param machineryIds An array of machinery associated with the event. * @param workPackageIds An array of work packages associated with the event. * @param documentIds An array of documents associated with the event. * @param scheduleSlots An array of schedule slots associated with the event. - * @param approved Determines if the event has been approved. - * @param approvedByUserId The ID of the approving user. * @param questionDocument The link to the question document. * @param location Location of the event. * @param zoomLink Zoom Link if the event is online. @@ -219,15 +235,14 @@ export default class CalendarService { title: string, eventTypeId: string, organization: Organization, - memberIds: string[], + requiredMemberIds: string[], + optionalMemberIds: string[], teamIds: string[], shopIds: string[], machineryIds: string[], workPackageIds: string[], documentIds: string[], scheduleSlot: ScheduleSlotCreateArgs[], - approved: boolean, - approvedByUserId?: string, questionDocument?: string, location?: string, zoomLink?: string, @@ -243,16 +258,73 @@ export default class CalendarService { throw new InvalidOrganizationException('Event Type'); } - // Validate memberIds - if (memberIds.length > 0) { + if (foundEventType.onlyHeadsOrAboveForEventCreation) { + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isHead || isAdmin); + + if (!hasPermission) { + throw new AccessDeniedException('Only admins and heads can create events under this event type'); + } + } + + // Validate event follows event type configuration + if (foundEventType.requiredMembers && requiredMemberIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one required member'); + } + if (foundEventType.optionalMembers && optionalMemberIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one optional member'); + } + if (foundEventType.location && !location) { + throw new InvalidEventTypeConfigurationException('a location'); + } + if (foundEventType.zoomLink && !zoomLink) { + throw new InvalidEventTypeConfigurationException('a zoom link'); + } + if (foundEventType.shop && shopIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one shop'); + } + if (foundEventType.machinery && machineryIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one machinery'); + } + if (foundEventType.workPackage && workPackageIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one work package'); + } + if (foundEventType.questionDocument && !questionDocument) { + throw new InvalidEventTypeConfigurationException('a question document'); + } + if (foundEventType.documents && documentIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one document'); + } + if (foundEventType.description && !description) { + throw new InvalidEventTypeConfigurationException('a description'); + } + if (foundEventType.initialDateScheduled && scheduleSlot.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one schedule slot'); + } + + // Validate required memberIds + if (requiredMemberIds.length > 0) { const foundMembers = await prisma.user.findMany({ where: { - userId: { in: memberIds }, + userId: { in: requiredMemberIds }, organizations: { some: { organizationId: organization.organizationId } } } }); - if (foundMembers.length !== memberIds.length) { - const missingIds = memberIds.filter((id) => !foundMembers.some((user) => user.userId === id)); + if (foundMembers.length !== requiredMemberIds.length) { + const missingIds = requiredMemberIds.filter((id) => !foundMembers.some((user) => user.userId === id)); + throw new NotFoundException('User', missingIds.join(', ')); + } + } + + // Validate optionals memberIds + if (optionalMemberIds.length > 0) { + const foundMembers = await prisma.user.findMany({ + where: { + userId: { in: optionalMemberIds }, + organizations: { some: { organizationId: organization.organizationId } } + } + }); + if (foundMembers.length !== optionalMemberIds.length) { + const missingIds = optionalMemberIds.filter((id) => !foundMembers.some((user) => user.userId === id)); throw new NotFoundException('User', missingIds.join(', ')); } } @@ -293,12 +365,24 @@ export default class CalendarService { machineryId: { in: machineryIds }, organizationId: organization.organizationId, dateDeleted: null + }, + include: { + shops: { + include: { + shop: true + } + } } }); if (foundMachinery.length !== machineryIds.length) { const missingIds = machineryIds.filter((id) => !foundMachinery.some((m) => m.machineryId === id)); throw new NotFoundException('Machinery', missingIds.join(', ')); } + + // Automatically add machinery's shops to shopIds if not already included + const machineryShopIds = foundMachinery.flatMap((m) => m.shops.map((sm) => sm.shopId)); + const uniqueShopIds = new Set([...shopIds, ...machineryShopIds]); + shopIds = Array.from(uniqueShopIds); } // Validate workPackageIds @@ -314,19 +398,6 @@ export default class CalendarService { } } - // Validate approvedByUserId - if (approvedByUserId) { - const foundApprovedByUser = await prisma.user.findUnique({ - where: { - userId: approvedByUserId, - organizations: { some: { organizationId: organization.organizationId } } - } - }); - if (!foundApprovedByUser) { - throw new NotFoundException('User', approvedByUserId); - } - } - const computeEndDate = (initial: Date, recurrenceNumber: number) => { const weeks = Math.max(1, recurrenceNumber ?? 0); return new Date(initial.getTime() + weeks * 7 * 24 * 60 * 60 * 1000); @@ -338,8 +409,11 @@ export default class CalendarService { dateCreated: new Date(), title, eventTypeId, - members: { - connect: memberIds.map((userId) => ({ userId })) + requiredMembers: { + connect: requiredMemberIds.map((userId) => ({ userId })) + }, + optionalMembers: { + connect: optionalMemberIds.map((userId) => ({ userId })) }, teams: { connect: teamIds.map((teamId) => ({ teamId })) @@ -365,8 +439,9 @@ export default class CalendarService { allDay: s.allDay })) }, - approved, - approvedByUserId, + status: Event_Status.UNCONFIRMED, + approved: false, + approvedByUserId: null, location, zoomLink, questionDocument, @@ -384,16 +459,14 @@ export default class CalendarService { * @param submitter The user submitting the request, who must be an admin. * @param eventId The id of the event to edit. * @param title The title of the event. - * @param eventTypeId The event type id the event is associated with. * @param organization The organization for which the event type is being created. - * @param memberIds An array of member ids that are invited to the event. + * @param requiredMemberIds An array of required member ids that are invited to the event. + * @param optionalMemberIds An array of optional member ids that are invited to the event. * @param shopIds An array of shops associated with the event. * @param machineryIds An array of machinery associated with the event. * @param workPackageIds An array of work packages associated with the event. * @param documentIds An array of documents associated with the event. * @param scheduleSlots An array of schedule slots associated with the event. - * @param approved Determines if the event has been approved. - * @param approvedByUserId The ID of the approving user. * @param questionDocument The link to the question document. * @param location Location of the event. * @param zoomLink Zoom Link if the event is online. @@ -408,17 +481,15 @@ export default class CalendarService { submitter: User, eventId: string, title: string, - eventTypeId: string, organization: Organization, - memberIds: string[], + requiredMemberIds: string[], + optionalMemberIds: string[], teamIds: string[], shopIds: string[], machineryIds: string[], workPackageIds: string[], documentIds: string[], scheduleSlot: ScheduleSlotCreateArgs[], - approved: boolean, - approvedByUserId?: string, questionDocument?: string, location?: string, zoomLink?: string, @@ -432,34 +503,101 @@ export default class CalendarService { if (!foundEvent) throw new NotFoundException('Event', eventId); if (foundEvent.dateDeleted) throw new DeletedException('Event', eventId); - const hasPermission = - (await userHasPermission(submitter.userId, organization.organizationId, isAdmin)) || - submitter.userId === foundEvent.userCreatedId; - - if (!hasPermission) { - throw new AccessDeniedException('Only admins and creators can edit events!'); - } - - // Validate eventTypeId + const { eventTypeId } = foundEvent; const foundEventType = await prisma.eventType.findUnique({ where: { eventTypeId } }); + if (!foundEventType) throw new NotFoundException('Event Type', eventTypeId); if (foundEventType.dateDeleted) throw new DeletedException('Event Type', eventTypeId); - if (foundEventType.organizationId !== organization.organizationId) { - throw new InvalidOrganizationException('Event Type'); + + // Validate event follows event type configuration + if (foundEventType.requiredMembers && requiredMemberIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one required member'); + } + if (foundEventType.optionalMembers && optionalMemberIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one optional member'); + } + if (foundEventType.location && !location) { + throw new InvalidEventTypeConfigurationException('a location'); + } + if (foundEventType.zoomLink && !zoomLink) { + throw new InvalidEventTypeConfigurationException('a zoom link'); + } + if (foundEventType.shop && shopIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one shop'); + } + if (foundEventType.machinery && machineryIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one machinery'); + } + if (foundEventType.workPackage && workPackageIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one work package'); + } + if (foundEventType.questionDocument && !questionDocument) { + throw new InvalidEventTypeConfigurationException('a question document'); + } + if (foundEventType.documents && documentIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one document'); + } + if (foundEventType.description && !description) { + throw new InvalidEventTypeConfigurationException('a description'); + } + if (foundEventType.initialDateScheduled && scheduleSlot.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one schedule slot'); + } + if (foundEventType.name === 'Design Review') { + // question document is required if the status is scheduled or done + if (foundEvent.status === Event_Status.SCHEDULED || foundEvent.status === Event_Status.DONE) { + if (questionDocument == null) { + throw new HttpException(400, 'doc template link is required for scheduled and done design reviews'); + } + } + } + + if (requiredMemberIds.length > 0 && requiredMemberIds.some((rMemberId) => optionalMemberIds.includes(rMemberId))) { + throw new HttpException(400, 'required members cannot be in optional members'); } - // Validate memberIds - if (memberIds.length > 0) { + if (foundEventType.onlyHeadsOrAboveForEventCreation) { + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isHead || isAdmin); + + if (!hasPermission) { + throw new AccessDeniedException('Only admins and heads can edit this event!'); + } + } else { + const hasPermission = + (await userHasPermission(submitter.userId, organization.organizationId, isHead || isAdmin)) || + submitter.userId === foundEvent.userCreatedId; + + if (!hasPermission) { + throw new AccessDeniedException('Only admins and heads and creators can edit this event!'); + } + } + + // Validate required memberIds + if (requiredMemberIds.length > 0) { const foundMembers = await prisma.user.findMany({ where: { - userId: { in: memberIds }, + userId: { in: requiredMemberIds }, organizations: { some: { organizationId: organization.organizationId } } } }); - if (foundMembers.length !== memberIds.length) { - const missingIds = memberIds.filter((id) => !foundMembers.some((user) => user.userId === id)); + if (foundMembers.length !== requiredMemberIds.length) { + const missingIds = requiredMemberIds.filter((id) => !foundMembers.some((user) => user.userId === id)); + throw new NotFoundException('User', missingIds.join(', ')); + } + } + + // Validate optional memberIds + if (optionalMemberIds.length > 0) { + const foundMembers = await prisma.user.findMany({ + where: { + userId: { in: optionalMemberIds }, + organizations: { some: { organizationId: organization.organizationId } } + } + }); + if (foundMembers.length !== optionalMemberIds.length) { + const missingIds = optionalMemberIds.filter((id) => !foundMembers.some((user) => user.userId === id)); throw new NotFoundException('User', missingIds.join(', ')); } } @@ -500,12 +638,24 @@ export default class CalendarService { machineryId: { in: machineryIds }, organizationId: organization.organizationId, dateDeleted: null + }, + include: { + shops: { + include: { + shop: true + } + } } }); if (foundMachinery.length !== machineryIds.length) { const missingIds = machineryIds.filter((id) => !foundMachinery.some((m) => m.machineryId === id)); throw new NotFoundException('Machinery', missingIds.join(', ')); } + + // Automatically add machinery's shops to shopIds if not already included + const machineryShopIds = foundMachinery.flatMap((m) => m.shops.map((sm) => sm.shopId)); + const uniqueShopIds = new Set([...shopIds, ...machineryShopIds]); + shopIds = Array.from(uniqueShopIds); } // Validate workPackageIds @@ -521,19 +671,6 @@ export default class CalendarService { } } - // Validate approvedByUserId - if (approvedByUserId) { - const foundApprovedByUser = await prisma.user.findUnique({ - where: { - userId: approvedByUserId, - organizations: { some: { organizationId: organization.organizationId } } - } - }); - if (!foundApprovedByUser) { - throw new NotFoundException('User', approvedByUserId); - } - } - // Use transaction for the update const updatedEvent = await prisma.$transaction(async (tx) => { // Fetch existing schedule slots @@ -593,14 +730,21 @@ export default class CalendarService { ); } + // throw if a user isn't found, then build prisma queries for connecting userIds + const updatedRequiredMembers = getPrismaQueryUserIds(await getUsers(requiredMemberIds)); + const updatedOptionalMembers = getPrismaQueryUserIds(await getUsers(optionalMemberIds)); + // Update the event with new data return await tx.event.update({ where: { eventId }, data: { title, eventTypeId, - members: { - set: memberIds.map((userId) => ({ userId })) + requiredMembers: { + set: updatedRequiredMembers + }, + optionalMembers: { + set: updatedOptionalMembers }, teams: { set: teamIds.map((teamId) => ({ teamId })) @@ -615,8 +759,6 @@ export default class CalendarService { set: workPackageIds.map((workPackageId) => ({ workPackageId })) }, documentIds, - approved, - approvedByUserId, location, zoomLink, questionDocument, @@ -629,6 +771,170 @@ export default class CalendarService { return eventTransformer(updatedEvent); } + /** + * Approve event in the database + * @param submitter The user submitting the request who must be a head or above. + * @param eventId The id of the given event. + * @param organization The organization for which the event is being deleted. + * + * @returns The approved event. + * + * @throws NotFoundException If the given eventId is not found. + * @throws InvalidOrganizationException If the given eventId is not part of the same organization. + * @throws DeletedException If the event has already been deleted. + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin or head. + */ + static async approveEvent(submitter: User, eventId: string, organization: Organization): Promise { + const event = await prisma.event.findUnique({ + where: { eventId } + }); + + if (!event) throw new NotFoundException('Event', eventId); + if (event.dateDeleted) throw new DeletedException('Event', eventId); + + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin || isHead); + + if (!hasPermission) { + throw new AccessDeniedException('Only admins or heads can approve events!'); + } + + const approvedEvent = await prisma.event.update({ + where: { eventId }, + data: { + approved: true, + approvedByUserId: submitter.userId + }, + ...getEventQueryArgs(organization.organizationId) + }); + + return eventTransformer(approvedEvent); + } + + /** + * Edits an event by confirming a given user's availability and also updating their schedule settings with the given availability + * @param submitter the member that is being confirmed + * @param eventId the id of the event + * @param availabilities the given member's availabilities + * @param organizationId the organization that the user is currently in + * @returns the modified event with its updated confirmed members + */ + static async markUserConfirmed( + eventId: string, + availabilities: AvailabilityCreateArgs[], + submitter: UserWithSettings, + organization: Organization + ): Promise { + const event = await prisma.event.findUnique({ + where: { eventId }, + ...getEventQueryArgs(organization.organizationId) + }); + + if (!event) throw new NotFoundException('Event', eventId); + if (event.dateDeleted) throw new DeletedException('Event', eventId); + + if (!isUserOnEvent(submitter, eventTransformer(event))) + throw new HttpException(400, 'Current user is not in the list of this events members'); + + let userSettings = await prisma.schedule_Settings.findUnique({ + where: { userId: submitter.userId }, + ...getUserScheduleSettingsQueryArgs() + }); + + if (!userSettings) { + userSettings = await prisma.schedule_Settings.create({ + data: { + userId: submitter.userId, + availabilities: { + createMany: { + data: availabilities.map((availability) => ({ + availability: availability.availability, + dateSet: availability.dateSet + })) + } + }, + personalGmail: '', + personalZoomLink: '' + }, + ...getUserScheduleSettingsQueryArgs() + }); + } + + await updateUserAvailability(availabilities, userSettings, submitter); + + // set submitter as confirmed if they're not already + if (!event.confirmedMembers.map((user) => user.userId).includes(submitter.userId)) { + const updatedEvent = await prisma.event.update({ + where: { eventId }, + ...getEventQueryArgs(organization.organizationId), + data: { + confirmedMembers: { + connect: { + userId: submitter.userId + } + } + } + }); + + // possibly want to do + //await sendDRUserConfirmationToThread(updatedDesignReview.notificationSlackThreads, submitter); + + // If all required attendees have confirmed their schedule and this member was a required attendee, mark design review as confirmed + if ( + areUsersinList(event.requiredMembers, updatedEvent.confirmedMembers) && + areUsersinList([submitter], event.requiredMembers) + ) { + await prisma.event.update({ + where: { eventId }, + ...getEventQueryArgs(organization.organizationId), + data: { + status: Event_Status.CONFIRMED + } + }); + + //await sendDRConfirmationToThread(updatedDesignReview.notificationSlackThreads, updatedDesignReview.userCreated); + } + + return eventTransformer(updatedEvent); + } + return eventTransformer(event); + } + + /** + * Sets the status of an event, only admin or the user who created the event can set the status. + * @param user the user trying to set the status + * @param designReviewId the id of the event + * @param status the status to set the event to + * @param organizationId the organization that the user is currently in + * @returns the modified event + */ + static async setStatus(user: User, eventId: string, status: EventStatus, organization: Organization): Promise { + // validate the design review exists and is not deleted + const originalEvent = await prisma.event.findUnique({ + where: { eventId } + }); + if (!originalEvent) throw new NotFoundException('Event', eventId); + if (originalEvent.dateDeleted) throw new DeletedException('Event', eventId); + + // verify user is allowed to set the status of the event + if ( + !(await userHasPermission(user.userId, organization.organizationId, isAdmin)) && + user.userId !== originalEvent.userCreatedId + ) { + throw new AccessDeniedAdminOnlyException('set the status of an event'); + } + + // actually try to update the event + const updatedEvent = await prisma.event.update({ + where: { eventId }, + ...getEventQueryArgs(organization.organizationId), + data: { + status + } + }); + + return eventTransformer(updatedEvent); + } + /** * Delete event in the database * @param submitter The user submitting the request, who must be an admin. @@ -942,7 +1248,8 @@ export default class CalendarService { * @param initialDateScheduled Determines if a date is associated with this event type. * @param recurring Determines if this event type is recurring. * @param allDay Determines if this event type is all day. - * @param members Determines if this event type has members. + * @param requiredMembers Determines if this event type has required members. + * @param optionalMembers Determines if this event type has optional members. * @param location Determines if this event type has a location. * @param zoomLink Determines if this event type has a zoom link. * @param shop Determines if a shop is associated with this event type. @@ -951,6 +1258,7 @@ export default class CalendarService { * @param questionDocument Determines if a question document is associated with this event type. * @param documents Determines if documents are associates with this event type. * @param description Determines if a description is associated with this event type. + * @param onlyHeadsOrAbove Determines if events associated with this event type can only be made by heads or above. * * @returns The created event type. * @@ -963,10 +1271,12 @@ export default class CalendarService { submitter: User, calendarIds: string[], organization: Organization, + name: string, initialDateScheduled: boolean, recurring: boolean, allDay: boolean, - members: boolean, + requiredMembers: boolean, + optionalMembers: boolean, location: boolean, zoomLink: boolean, shop: boolean, @@ -974,7 +1284,8 @@ export default class CalendarService { workPackage: boolean, questionDocument: boolean, documents: boolean, - description: boolean + description: boolean, + onlyHeadsOrAbove: boolean ): Promise { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('edit event type'); @@ -1015,13 +1326,15 @@ export default class CalendarService { const updatedEventType = await prisma.eventType.update({ where: { eventTypeId: oldEventType.eventTypeId }, data: { + name, calendars: { connect: calendarIds.map((calendarId) => ({ calendarId })) }, initialDateScheduled, recurring, allDay, - members, + requiredMembers, + optionalMembers, location, zoomLink, shop, @@ -1029,7 +1342,8 @@ export default class CalendarService { workPackage, questionDocument, documents, - description + description, + onlyHeadsOrAboveForEventCreation: onlyHeadsOrAbove }, ...getEventTypeQueryArgs(organization.organizationId) }); @@ -1208,7 +1522,8 @@ export default class CalendarService { const memberOrCreator = memberIds?.length ? { OR: [ - { members: { some: { userId: { in: memberIds } } } }, // attendee + { requiredMembers: { some: { userId: { in: memberIds } } } }, // attendee + { optionalMembers: { some: { userId: { in: memberIds } } } }, { userCreatedId: { in: memberIds } } // creator ] } diff --git a/src/backend/src/services/design-reviews.services.ts b/src/backend/src/services/design-reviews.services.ts index 0e84e1f3e6..a215b9b38a 100644 --- a/src/backend/src/services/design-reviews.services.ts +++ b/src/backend/src/services/design-reviews.services.ts @@ -1,4 +1,4 @@ -import { Design_Review_Status, Team_Type, Organization } from '@prisma/client'; +import { Event_Status, Team_Type, Organization } from '@prisma/client'; import { DesignReview, WbsNumber, @@ -160,7 +160,7 @@ export default class DesignReviewsService { initialDateScheduled: date, dateScheduled: date, dateCreated: new Date(), - status: Design_Review_Status.UNCONFIRMED, + status: Event_Status.UNCONFIRMED, isOnline: false, isInPerson: false, userCreated: { connect: { userId: submitter.userId } }, @@ -262,7 +262,7 @@ export default class DesignReviewsService { * @param zoomLink the zoom link for the design review meeting * @param location the location for the design review meeting * @param docTemplateLink the document template link for the design review - * @param status see Design_Review_Status enum + * @param status see Event_Status enum * @param attendees the attendees for the design review * @param meetingTimes meeting time must be between 0-83 (representing 1hr increments from 10am 10pm, Monday-Sunday) * @param organizationId the organization that the user is currently in @@ -280,7 +280,7 @@ export default class DesignReviewsService { zoomLink: string | null, location: string | null, docTemplateLink: string | null, - status: Design_Review_Status, + status: Event_Status, attendees: string[], meetingTimes: number[], organization: Organization @@ -307,7 +307,7 @@ export default class DesignReviewsService { meetingTimes = validateMeetingTimes(meetingTimes); // docTemplateLink is required if the status is scheduled or done - if (status === Design_Review_Status.SCHEDULED || status === Design_Review_Status.DONE) { + if (status === Event_Status.SCHEDULED || status === Event_Status.DONE) { if (docTemplateLink == null) { throw new HttpException(400, 'doc template link is required for scheduled and done design reviews'); } @@ -349,8 +349,8 @@ export default class DesignReviewsService { originaldesignReview.confirmedMembers.map((user) => user.userId).includes(member.userId) ); - if (status === Design_Review_Status.CONFIRMED && allRequiredMembersConfirmed) { - status = Design_Review_Status.SCHEDULED; + if (status === Event_Status.CONFIRMED && allRequiredMembersConfirmed) { + status = Event_Status.SCHEDULED; } // actually try to update the design review @@ -381,7 +381,7 @@ export default class DesignReviewsService { ...getDesignReviewQueryArgs(organization.organizationId) }); - if (status === Design_Review_Status.SCHEDULED) { + if (status === Event_Status.SCHEDULED) { await sendDRScheduledSlackNotif(updatedDesignReview.notificationSlackThreads, updatedDesignReview); if (updatedDesignReview.calendarEventId && updatedDesignReview.teamType.calendarId) { await updateCalendarEvent( @@ -479,7 +479,7 @@ export default class DesignReviewsService { where: { designReviewId }, ...getDesignReviewQueryArgs(organization.organizationId), data: { - status: Design_Review_Status.CONFIRMED + status: Event_Status.CONFIRMED } }); diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index d142789b38..9fd965d272 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -1,7 +1,7 @@ import { Prisma } from '@prisma/client'; -import { Machinery, Shop, ShopMachinery, EventType, Calendar, Event, ScheduleSlot, DayOfWeek } from 'shared'; +import { Machinery, Shop, ShopMachinery, EventType, Calendar, Event, ScheduleSlot, DayOfWeek, EventStatus } from 'shared'; import { MachineryQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; -import { userTransformer } from './user.transformer'; +import { userTransformer, userWithScheduleSettingsTransformer } from './user.transformer'; import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { CalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; import { EventQueryArgs } from '../prisma-query-args/event.query-args'; @@ -49,7 +49,8 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload): userCreated: userTransformer(event.userCreated), dateCreated: event.dateCreated, eventTypeId: event.eventTypeId, - people: event.members.map(userTransformer), + requiredMembers: event.requiredMembers.map(userTransformer), + optionalMembers: event.optionalMembers.map(userTransformer), + confirmedMembers: event.confirmedMembers.map(userWithScheduleSettingsTransformer), + deniedMembers: event.deniedMembers.map(userTransformer), teams: event.teams.map(teamTransformer), shops: event.shops.map(shopTransformer), machinery: event.machinery.map(machineryTransformer), @@ -105,6 +110,7 @@ export const eventTransformer = (event: Prisma.EventGetPayload): location: event.location ?? undefined, zoomLink: event.zoomLink ?? undefined, questionDocument: event.questionDocument ?? undefined, - description: event.description ?? undefined + description: event.description ?? undefined, + status: event.status as EventStatus }; }; diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index a992ceeb37..c9680309fb 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -1,4 +1,5 @@ import { Prisma } from '@prisma/client'; +import { User, Event } from 'shared'; export function buildScheduledTimesOverlap(start?: Date, end?: Date): Prisma.ScheduleSlotListRelationFilter | undefined { if (!start && !end) return undefined; @@ -9,3 +10,9 @@ export function buildScheduledTimesOverlap(start?: Date, end?: Date): Prisma.Sch return { some: { AND } }; } + +export const isUserOnEvent = (user: User, event: Event): boolean => { + const requiredMembers = event.requiredMembers.map((user) => user.userId); + const optionalMembers = event.optionalMembers.map((user) => user.userId); + return requiredMembers.includes(user.userId) || optionalMembers.includes(user.userId); +}; diff --git a/src/backend/src/utils/errors.utils.ts b/src/backend/src/utils/errors.utils.ts index 7266ffdd5f..9f3832a120 100644 --- a/src/backend/src/utils/errors.utils.ts +++ b/src/backend/src/utils/errors.utils.ts @@ -89,6 +89,16 @@ export class AccessDeniedGuestException extends AccessDeniedException { } } +export class InvalidEventTypeConfigurationException extends HttpException { + /** + * Constructs an invalid event type configuration error + * @param field the name of the required field that is missing + */ + constructor(field: string) { + super(400, `Event Type requires ${field}`); + } +} + /* * Error handling middleware. Takes the error and sends back the status of it and the message */ diff --git a/src/backend/src/utils/validation.utils.ts b/src/backend/src/utils/validation.utils.ts index 8f23d173e4..e20fd61a57 100644 --- a/src/backend/src/utils/validation.utils.ts +++ b/src/backend/src/utils/validation.utils.ts @@ -1,11 +1,4 @@ -import { - DayOfWeek, - Design_Review_Status, - Graph_Display_Type, - Graph_Type, - Measure, - Special_Permission -} from '@prisma/client'; +import { DayOfWeek, Event_Status, Graph_Display_Type, Graph_Type, Measure, Special_Permission } from '@prisma/client'; import { Request, Response } from 'express'; import { body, query, ValidationChain, validationResult } from 'express-validator'; import { MaterialStatus, TaskPriority, TaskStatus, WorkPackageStage, RoleEnum, WbsElementStatus } from 'shared'; @@ -163,12 +156,7 @@ export const isMaterialStatus = (validationObject: ValidationChain): ValidationC export const isDesignReviewStatus = (validationObject: ValidationChain): ValidationChain => { return validationObject .isString() - .isIn([ - Design_Review_Status.CONFIRMED, - Design_Review_Status.DONE, - Design_Review_Status.SCHEDULED, - Design_Review_Status.UNCONFIRMED - ]); + .isIn([Event_Status.CONFIRMED, Event_Status.DONE, Event_Status.SCHEDULED, Event_Status.UNCONFIRMED]); }; export const isDayOfWeek = (validationObject: ValidationChain): ValidationChain => { diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index d85a287be2..7b8826964d 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -59,8 +59,9 @@ describe('Calendar Tests', () => { 'Team Meeting', [calendar.calendarId], organization, - true, false, + false, + true, true, true, false, @@ -70,7 +71,8 @@ describe('Calendar Tests', () => { false, false, false, - true + false, + false ); }); @@ -245,13 +247,15 @@ describe('Calendar Tests', () => { true, true, true, + true, false, false, false, true, true, false, - true + true, + false ) ).rejects.toThrow(new AccessDeniedAdminOnlyException('create event type')); }); @@ -268,19 +272,22 @@ describe('Calendar Tests', () => { true, true, true, + true, false, false, false, false, false, - true + true, + false ); expect(result.name).toEqual('Meeting'); expect(result.initialDateScheduled).toBe(true); expect(result.recurring).toBe(false); expect(result.allDay).toBe(true); - expect(result.members).toBe(true); + expect(result.requiredMembers).toBe(true); + expect(result.optionalMembers).toBe(true); expect(result.location).toBe(true); expect(result.zoomLink).toBe(true); expect(result.shop).toBe(false); @@ -289,6 +296,7 @@ describe('Calendar Tests', () => { expect(result.questionDocument).toBe(false); expect(result.documents).toBe(false); expect(result.description).toBe(true); + expect(result.onlyHeadsOrAboveForEventCreation).toBe(false); }); }); @@ -606,6 +614,7 @@ describe('Calendar Tests', () => { false, true, true, + true, false, false, false, @@ -613,6 +622,7 @@ describe('Calendar Tests', () => { false, false, false, + true, true ); }); @@ -625,6 +635,9 @@ describe('Calendar Tests', () => { guest, [calendar.calendarId], organization, + 'Initial Event Type', + false, + false, false, false, false, @@ -649,6 +662,9 @@ describe('Calendar Tests', () => { adminUser, [invalidCalendarId], organization, + 'Initial Event Type 2', + true, + true, true, true, true, @@ -691,7 +707,10 @@ describe('Calendar Tests', () => { adminUser, [foreignCalendar.calendarId], organization, - true, + 'Initial Event Type', + false, + false, + false, false, false, false, @@ -715,12 +734,15 @@ describe('Calendar Tests', () => { adminUser, [calendar.calendarId], organization, - true, + 'Non Existent Event Type', false, true, true, false, true, + true, + false, + false, false, false, false, @@ -737,26 +759,39 @@ describe('Calendar Tests', () => { adminUser, [calendar.calendarId], organization, + 'Initial Event Type 2', false, true, false, true, true, + true, false, true, true, true, false, true, + false, false ); - expect(result.eventTypeId).toBe(eventType.eventTypeId); - expect(result.recurring).toBe(true); + expect(result.name).toBe('Initial Event Type 2'); expect(result.initialDateScheduled).toBe(false); + expect(result.recurring).toBe(true); + expect(result.allDay).toBe(false); + expect(result.eventTypeId).toBe(eventType.eventTypeId); + expect(result.requiredMembers).toBe(true); + expect(result.optionalMembers).toBe(true); expect(result.location).toBe(true); expect(result.zoomLink).toBe(false); + expect(result.shop).toBe(true); + expect(result.machinery).toBe(true); + expect(result.workPackage).toBe(true); + expect(result.questionDocument).toBe(false); + expect(result.documents).toBe(true); expect(result.description).toBe(false); + expect(result.onlyHeadsOrAboveForEventCreation).toBe(false); }); }); @@ -819,14 +854,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [member.userId], + [adminUser.userId], [], [shop.shopId], [machinery.machineryId], [], [document], scheduleSlots, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -835,8 +869,10 @@ describe('Calendar Tests', () => { expect(result.title).toBe('Team Sync'); expect(result.eventTypeId).toBe(eventType.eventTypeId); - expect(result.people).toHaveLength(1); - expect(result.people[0].userId).toBe(member.userId); + expect(result.requiredMembers).toHaveLength(1); + expect(result.requiredMembers[0].userId).toBe(member.userId); + expect(result.optionalMembers).toHaveLength(1); + expect(result.optionalMembers[0].userId).toBe(adminUser.userId); expect(result.shops).toHaveLength(1); expect(result.shops[0].shopId).toBe(shop.shopId); expect(result.machinery).toHaveLength(1); @@ -845,8 +881,8 @@ describe('Calendar Tests', () => { expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); - expect(result.approved).toBe(true); - expect(result.approvedBy!.userId).toBe(adminUser.userId); + expect(result.approved).toBe(false); + expect(result.approvedBy).toBe(undefined); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); expect(result.zoomLink).toBe('https://zoom.us/j/123456789'); @@ -877,8 +913,8 @@ describe('Calendar Tests', () => { [], [], [], - scheduleSlots, - false + [], + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Event Type', 'non-existent-event-type-id')); }); @@ -903,12 +939,12 @@ describe('Calendar Tests', () => { otherOrg, [member.userId], [], + [], [shop.shopId], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new InvalidOrganizationException('Event Type')); }); @@ -921,19 +957,22 @@ describe('Calendar Tests', () => { 'Minimal Event', eventType.eventTypeId, organization, + [adminUser.userId], + [member.userId], [], [], [], [], [], - [], - scheduleSlots, - false + scheduleSlots ); expect(result.title).toBe('Minimal Event'); expect(result.eventTypeId).toBe(eventType.eventTypeId); - expect(result.people).toHaveLength(0); + expect(result.requiredMembers).toHaveLength(1); + expect(result.requiredMembers[0].userId).toBe(adminUser.userId); + expect(result.optionalMembers).toHaveLength(1); + expect(result.optionalMembers[0].userId).toBe(member.userId); expect(result.shops).toHaveLength(0); expect(result.machinery).toHaveLength(0); expect(result.workPackages).toHaveLength(0); @@ -957,13 +996,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, ['non-existent-user-id'], + [adminUser.userId], [], [], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); }); @@ -978,13 +1017,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [otherOrgUser.userId], + [adminUser.userId], [], [], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('User', otherOrgUser.userId)); }); @@ -998,14 +1037,14 @@ describe('Calendar Tests', () => { 'Invalid Shops', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], ['non-existent-shop-id'], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Shop', 'non-existent-shop-id')); }); @@ -1019,14 +1058,14 @@ describe('Calendar Tests', () => { 'Wrong Org Shops', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [otherOrgShop.shopId], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Shop', otherOrgShop.shopId)); }); @@ -1040,14 +1079,14 @@ describe('Calendar Tests', () => { 'Invalid Machinery', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [], ['non-existent-machinery-id'], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Machinery', 'non-existent-machinery-id')); }); @@ -1061,14 +1100,14 @@ describe('Calendar Tests', () => { 'Wrong Org Machinery', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [], [otherOrgMachinery.machineryId], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Machinery', otherOrgMachinery.machineryId)); }); @@ -1082,62 +1121,18 @@ describe('Calendar Tests', () => { 'Invalid Work Packages', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [], [], ['non-existent-work-package-id'], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Work Package', 'non-existent-work-package-id')); }); - it('fails if approvedByUserId is invalid', async () => { - const scheduleSlots = [] as ScheduleSlot[]; - - await expect( - CalendarService.createEvent( - adminUser, - 'Invalid Approver', - eventType.eventTypeId, - organization, - [], - [], - [], - [], - [], - [], - scheduleSlots, - true, - 'non-existent-user-id' - ) - ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); - }); - - it('fails if approvedByUserId belongs to a different organization', async () => { - const scheduleSlots = [] as ScheduleSlot[]; - - await expect( - CalendarService.createEvent( - adminUser, - 'Wrong Org Approver', - eventType.eventTypeId, - organization, - [], - [], - [], - [], - [], - [], - scheduleSlots, - true, - otherOrgUser.userId - ) - ).rejects.toThrow(new NotFoundException('User', otherOrgUser.userId)); - }); - it('fails if shopIds are deleted', async () => { const deletedShop = await CalendarService.createShop(adminUser, 'Deleted Shop', 'Deleted shop', organization); await prisma.shop.update({ @@ -1153,14 +1148,14 @@ describe('Calendar Tests', () => { 'Deleted Shops', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [deletedShop.shopId], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Shop', deletedShop.shopId)); }); @@ -1187,14 +1182,14 @@ describe('Calendar Tests', () => { 'Deleted Machinery', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [], [deletedMachinery.machineryId], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); }); @@ -1223,14 +1218,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [member.userId], + [adminUser.userId], [], [shop.shopId], [machinery.machineryId], [], [document], scheduleSlots, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1243,14 +1237,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [member.userId], + [adminUser.userId], [], [shop.shopId], [], [], [], scheduleSlots, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1286,14 +1279,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [member.userId], + [adminUser.userId], [], [shop.shopId], [machinery.machineryId], [], [document], scheduleSlots, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1306,14 +1298,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [member.userId], + [adminUser.userId], [], [shop.shopId], [], [], [], scheduleSlots, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1338,14 +1329,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [member.userId], + [adminUser.userId], [], [shop.shopId], [], [], [], scheduleSlots2, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1361,6 +1351,7 @@ describe('Calendar Tests', () => { it('Succeeds and gets all events with matching members', async () => { const member = await createTestUser(supermanAdmin, orgId); + const member2 = await createTestUser(wonderwomanGuest, orgId); const document = 'Test Document'; @@ -1380,6 +1371,7 @@ describe('Calendar Tests', () => { 'Team Sync', eventType.eventTypeId, organization, + [adminUser.userId], [member.userId], [], [shop.shopId], @@ -1387,8 +1379,6 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1400,15 +1390,14 @@ describe('Calendar Tests', () => { 'Awesome Meeting', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member2.userId], [], [shop.shopId], [], [], [], scheduleSlots, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1432,15 +1421,14 @@ describe('Calendar Tests', () => { 'Way too far in the future meeting', eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member2.userId], [], [shop.shopId], [], [], [], scheduleSlots2, - true, - adminUser.userId, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1617,13 +1605,13 @@ describe('Calendar Tests', () => { eventType.eventTypeId, organization, [member.userId], + [adminUser.userId], [], [shop.shopId], [machinery.machineryId], [], ['doc1'], - scheduleSlots, - false + scheduleSlots ); }); @@ -1633,16 +1621,15 @@ describe('Calendar Tests', () => { adminUser, 'non-existent-id', 'Updated Title', - eventType.eventTypeId, organization, + [adminUser.userId], + [member.userId], [], [], [], [], [], - [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Event', 'non-existent-id')); }); @@ -1658,130 +1645,34 @@ describe('Calendar Tests', () => { adminUser, event.eventId, 'Updated Title', - eventType.eventTypeId, organization, + [adminUser.userId], + [member.userId], [], [], [], [], [], - [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new DeletedException('Event', event.eventId)); }); - it('fails if eventTypeId does not exist', async () => { - await expect( - CalendarService.editEvent( - adminUser, - event.eventId, - 'Updated Title', - 'non-existent-event-type-id', - organization, - [], - [], - [], - [], - [], - [], - scheduleSlots, - false - ) - ).rejects.toThrow(new NotFoundException('Event Type', 'non-existent-event-type-id')); - }); - - it('fails if eventType is deleted', async () => { - await prisma.eventType.update({ - where: { eventTypeId: eventType.eventTypeId }, - data: { dateDeleted: new Date() } - }); - - await expect( - CalendarService.editEvent( - adminUser, - event.eventId, - 'Updated Title', - eventType.eventTypeId, - organization, - [], - [], - [], - [], - [], - [], - scheduleSlots, - false - ) - ).rejects.toThrow(new DeletedException('Event Type', eventType.eventTypeId)); - }); - - it('fails if eventType belongs to different organization', async () => { - const otherOrg = await prisma.organization.create({ - data: { - name: 'Other Org (calendar test)', - description: 'for cross-org negative case', - applicationLink: '', - userCreated: { connect: { userId: adminUser.userId } } - } - }); - const AdminInOtherOrg = await createTestUser(alfred, otherOrg.organizationId); - - const otherEventType = await CalendarService.createEventType( - AdminInOtherOrg, - 'Other Org Event Type', - [], - otherOrg, - true, - false, - true, - true, - false, - false, - false, - false, - false, - false, - false, - true - ); - - await expect( - CalendarService.editEvent( - adminUser, - event.eventId, - 'Updated Title', - otherEventType.eventTypeId, - organization, - [], - [], - [], - [], - [], - [], - scheduleSlots, - false - ) - ).rejects.toThrow(new InvalidOrganizationException('Event Type')); - }); - it('fails if memberIds are invalid', async () => { await expect( CalendarService.editEvent( adminUser, event.eventId, 'Updated Title', - eventType.eventTypeId, organization, ['non-existent-user-id'], + [adminUser.userId], [], [], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); }); @@ -1792,16 +1683,15 @@ describe('Calendar Tests', () => { adminUser, event.eventId, 'Updated Title', - eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], ['non-existent-shop-id'], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Shop', 'non-existent-shop-id')); }); @@ -1818,16 +1708,15 @@ describe('Calendar Tests', () => { adminUser, event.eventId, 'Updated Title', - eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [deletedShop.shopId], [], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Shop', deletedShop.shopId)); }); @@ -1838,16 +1727,15 @@ describe('Calendar Tests', () => { adminUser, event.eventId, 'Updated Title', - eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [], ['non-existent-machinery-id'], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Machinery', 'non-existent-machinery-id')); }); @@ -1870,16 +1758,15 @@ describe('Calendar Tests', () => { adminUser, event.eventId, 'Updated Title', - eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [], [deletedMachinery.machineryId], [], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); }); @@ -1890,41 +1777,19 @@ describe('Calendar Tests', () => { adminUser, event.eventId, 'Updated Title', - eventType.eventTypeId, organization, - [], + [adminUser.userId], + [member.userId], [], [], [], ['non-existent-wp-id'], [], - scheduleSlots, - false + scheduleSlots ) ).rejects.toThrow(new NotFoundException('Work Package', 'non-existent-wp-id')); }); - it('fails if approvedByUserId is invalid', async () => { - await expect( - CalendarService.editEvent( - adminUser, - event.eventId, - 'Updated Title', - eventType.eventTypeId, - organization, - [], - [], - [], - [], - [], - [], - scheduleSlots, - true, - 'non-existent-user-id' - ) - ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); - }); - it('succeeds for admin and updates event', async () => { const newMember = await createTestUser(alfred, orgId); const newScheduleSlots: ScheduleSlotCreateArgs[] = [ @@ -1942,17 +1807,15 @@ describe('Calendar Tests', () => { adminUser, event.eventId, 'Updated Event Title', - eventType.eventTypeId, organization, [newMember.userId], + [adminUser.userId], [], [], [], [], ['doc2', 'doc3'], newScheduleSlots, - true, - adminUser.userId, 'https://updated.com/questions.pdf', 'Updated Location', 'https://zoom.us/updated', @@ -1961,11 +1824,13 @@ describe('Calendar Tests', () => { expect(result.eventId).toBe(event.eventId); expect(result.title).toBe('Updated Event Title'); - expect(result.people).toHaveLength(1); - expect(result.people[0].userId).toBe(newMember.userId); + expect(result.requiredMembers).toHaveLength(1); + expect(result.requiredMembers[0].userId).toBe(newMember.userId); + expect(result.optionalMembers).toHaveLength(1); + expect(result.optionalMembers[0].userId).toBe(adminUser.userId); expect(result.documentIds).toEqual(['doc2', 'doc3']); - expect(result.approved).toBe(true); - expect(result.approvedBy!.userId).toBe(adminUser.userId); + expect(result.approved).toBe(false); + expect(result.approvedBy).toBe(undefined); expect(result.questionDocument).toBe('https://updated.com/questions.pdf'); expect(result.location).toBe('Updated Location'); expect(result.zoomLink).toBe('https://zoom.us/updated'); @@ -1977,21 +1842,23 @@ describe('Calendar Tests', () => { adminUser, event.eventId, 'Minimal Update', - eventType.eventTypeId, organization, + [adminUser.userId], + [member.userId], [], [], [], [], [], - [], - [], - false + [] ); expect(result.eventId).toBe(event.eventId); expect(result.title).toBe('Minimal Update'); - expect(result.people).toHaveLength(0); + expect(result.requiredMembers).toHaveLength(1); + expect(result.requiredMembers[0].userId).toBe(adminUser.userId); + expect(result.optionalMembers).toHaveLength(1); + expect(result.optionalMembers[0].userId).toBe(member.userId); expect(result.shops).toHaveLength(0); expect(result.machinery).toHaveLength(0); expect(result.workPackages).toHaveLength(0); @@ -2002,8 +1869,10 @@ describe('Calendar Tests', () => { describe('Delete Event', () => { let event: Event; + let member: User; beforeEach(async () => { + member = await createTestUser(wonderwomanGuest, orgId); const scheduleSlots: ScheduleSlotCreateArgs[] = [ { days: [DayOfWeek.MONDAY], @@ -2020,20 +1889,19 @@ describe('Calendar Tests', () => { 'Event to Delete', eventType.eventTypeId, organization, + [adminUser.userId], + [member.userId], [], [], [], [], [], - [], - scheduleSlots, - false + scheduleSlots ); }); it('fails if user is not an admin', async () => { - const guest = await createTestUser(wonderwomanGuest, orgId); - await expect(CalendarService.deleteEvent(guest, event.eventId, organization)).rejects.toThrow( + await expect(CalendarService.deleteEvent(member, event.eventId, organization)).rejects.toThrow( new AccessDeniedException('Only admins can delete events!') ); }); @@ -2082,6 +1950,8 @@ describe('Calendar Tests', () => { false, true, true, + true, + true, false, false, false, @@ -2137,6 +2007,8 @@ describe('Calendar Tests', () => { false, true, true, + true, + true, false, false, false, diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 823cab906a..490e00cd98 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -1,7 +1,14 @@ import { WorkPackage } from './project-types'; -import { User } from './user-types'; +import { User, UserWithScheduleSettings } from './user-types'; import { Team } from './team-types'; +export enum EventStatus { + UNCONFIRMED = 'UNCONFIRMED', + CONFIRMED = 'CONFIRMED', + SCHEDULED = 'SCHEDULED', + DONE = 'DONE' +} + export interface Calendar { calendarId: string; name: string; @@ -61,7 +68,8 @@ export interface EventType { initialDateScheduled: boolean; allDay: boolean; recurring: boolean; - members: boolean; + requiredMembers: boolean; + optionalMembers: boolean; location: boolean; zoomLink: boolean; shop: boolean; @@ -70,6 +78,7 @@ export interface EventType { questionDocument: boolean; documents: boolean; description: boolean; + onlyHeadsOrAboveForEventCreation: boolean; } export interface Shop { @@ -104,7 +113,10 @@ export interface Event { eventTypeId: string; approvedBy?: User; scheduledTimes: ScheduleSlot[]; - people: User[]; + requiredMembers: User[]; + optionalMembers: User[]; + confirmedMembers: UserWithScheduleSettings[]; + deniedMembers: User[]; teams: Team[]; location?: string; zoomLink?: string; @@ -114,4 +126,5 @@ export interface Event { documentIds: string[]; questionDocument?: string; description?: string; + status: EventStatus; } From c29298a803eeb913d7ac70679ebf3a67cf915585 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 2 Nov 2025 15:35:55 -0500 Subject: [PATCH 181/477] #3569 add teams to event type --- .../src/controllers/calendar.controllers.ts | 4 ++ .../20251101233144_calendar/migration.sql | 1 + src/backend/src/prisma/schema.prisma | 1 + src/backend/src/prisma/seed.ts | 16 ++++--- src/backend/src/routes/calendar.routes.ts | 48 ++++++++++--------- src/backend/src/services/calendar.services.ts | 12 +++++ .../src/transformers/calendar.transformer.ts | 1 + src/backend/tests/unit/calendar.test.ts | 13 +++++ src/shared/src/types/calendar-types.ts | 1 + 9 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index ebcc3630de..035d82a39c 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -13,6 +13,7 @@ export default class CalendarController { allDay, requiredMembers, optionalMembers, + teams, location, zoomLink, shop, @@ -34,6 +35,7 @@ export default class CalendarController { allDay, requiredMembers, optionalMembers, + teams, location, zoomLink, shop, @@ -182,6 +184,7 @@ export default class CalendarController { allDay, requiredMembers, optionalMembers, + teams, location, zoomLink, shop, @@ -204,6 +207,7 @@ export default class CalendarController { allDay, requiredMembers, optionalMembers, + teams, location, zoomLink, shop, diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index b8a7de0c95..6b3b7d54b7 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -101,6 +101,7 @@ CREATE TABLE "public"."EventType" ( "recurring" BOOLEAN NOT NULL DEFAULT FALSE, "optionalMembers" BOOLEAN NOT NULL DEFAULT FALSE, "requiredMembers" BOOLEAN NOT NULL DEFAULT FALSE, + "teams" BOOLEAN NOT NULL DEFAULT FALSE, "location" BOOLEAN NOT NULL DEFAULT FALSE, "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, "shop" BOOLEAN NOT NULL DEFAULT FALSE, diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 0fba9e28f1..b3f408e3d8 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1107,6 +1107,7 @@ model EventType { recurring Boolean requiredMembers Boolean optionalMembers Boolean + teams Boolean location Boolean zoomLink Boolean shop Boolean diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index c5d7b272f7..ba74aa2208 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3195,7 +3195,8 @@ const performSeed: () => Promise = async () => { true, true, true, - true, + false, + false, true, true, false, @@ -3209,7 +3210,7 @@ const performSeed: () => Promise = async () => { ); // design review event type - await CalendarService.createEventType( + const designReviewEventType = await CalendarService.createEventType( thomasEmrax, 'Design Review', [calendar.calendarId], @@ -3219,6 +3220,7 @@ const performSeed: () => Promise = async () => { true, true, true, + false, true, false, false, @@ -3243,6 +3245,7 @@ const performSeed: () => Promise = async () => { true, false, false, + false, true, true, true, @@ -3265,6 +3268,7 @@ const performSeed: () => Promise = async () => { false, false, false, + false, true, false, true, @@ -3278,7 +3282,7 @@ const performSeed: () => Promise = async () => { await CalendarService.createEvent( thomasEmrax, 'Impact Attenuator Design Review', - meetingEventType.eventTypeId, + designReviewEventType.eventTypeId, ner, [joeShmoe.userId, joeBlow.userId], [batman.userId], @@ -3286,7 +3290,7 @@ const performSeed: () => Promise = async () => { [advancedShop.shopId], [printer.machineryId, hammer.machineryId], [workPackage1.id], - [], + ['https://docs.google.com/document/d/1_example'], [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -3305,7 +3309,7 @@ const performSeed: () => Promise = async () => { await CalendarService.createEvent( batman, 'Wiring Harness Installation Planning', - meetingEventType.eventTypeId, + designReviewEventType.eventTypeId, ner, [regina.userId, janis.userId], [cady.userId], @@ -3313,7 +3317,7 @@ const performSeed: () => Promise = async () => { [electronicsLab.shopId], [printer.machineryId], [workPackage3.id, workPackage4.id], - [], + ['https://docs.google.com/document/d/1_example'], [ { days: [DayOfWeek.WEDNESDAY], diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index cd5b626857..3fa93bbb43 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -24,6 +24,7 @@ calendarRouter.post( body('recurring').isBoolean(), body('requiredMembers').isBoolean(), body('optionalMembers').isBoolean(), + body('teams').isBoolean(), body('location').isBoolean(), body('zoomLink').isBoolean(), body('shop').isBoolean(), @@ -37,6 +38,30 @@ calendarRouter.post( CalendarController.createEventType ); +calendarRouter.post( + '/event-type/:eventTypeId/edit', + nonEmptyString(body('name')), + body('calendarIds').isArray(), + body('calendarIds.*').isString(), + body('initialDateScheduled').isBoolean(), + body('allDay').isBoolean(), + body('recurring').isBoolean(), + body('requiredMembers').isBoolean(), + body('optionalMembers').isBoolean(), + body('teams').isBoolean(), + body('location').isBoolean(), + body('zoomLink').isBoolean(), + body('shop').isBoolean(), + body('machinery').isBoolean(), + body('workPackage').isBoolean(), + body('questionDocument').isBoolean(), + body('documents').isBoolean(), + body('description').isBoolean(), + body('onlyHeadsOrAbove').isBoolean(), + validateInputs, + CalendarController.editEventType +); + calendarRouter.post( '/event/create', nonEmptyString(body('title')), @@ -165,29 +190,6 @@ calendarRouter.post( CalendarController.editShop ); -calendarRouter.post( - '/event-type/:eventTypeId/edit', - nonEmptyString(body('name')), - body('calendarIds').isArray(), - body('calendarIds.*').isString(), - body('initialDateScheduled').isBoolean(), - body('allDay').isBoolean(), - body('recurring').isBoolean(), - body('requiredMembers').isBoolean(), - body('optionalMembers').isBoolean(), - body('location').isBoolean(), - body('zoomLink').isBoolean(), - body('shop').isBoolean(), - body('machinery').isBoolean(), - body('workPackage').isBoolean(), - body('questionDocument').isBoolean(), - body('documents').isBoolean(), - body('description').isBoolean(), - body('onlyHeadsOrAbove').isBoolean(), - validateInputs, - CalendarController.editEventType -); - calendarRouter.post('/event-type/:eventTypeId/delete', CalendarController.deleteEventType); calendarRouter.post('/:calendarId/delete', CalendarController.deleteCalendar); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index ed1a577d81..23cb330aef 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -55,6 +55,7 @@ export default class CalendarService { * @param allDay Determines if this event type is all day. * @param requiredMembers Determines if this event type has required members. * @param optionalMembers Determines if this event type has optional members. + * @param teams Determines if this event type has teams. * @param location Determines if this event type has a location. * @param zoomLink Determines if this event type has a zoom link. * @param shop Determines if a shop is associated with this event type. @@ -81,6 +82,7 @@ export default class CalendarService { allDay: boolean, requiredMembers: boolean, optionalMembers: boolean, + teams: boolean, location: boolean, zoomLink: boolean, shop: boolean, @@ -128,6 +130,7 @@ export default class CalendarService { allDay, requiredMembers, optionalMembers, + teams, location, zoomLink, shop, @@ -270,6 +273,9 @@ export default class CalendarService { if (foundEventType.requiredMembers && requiredMemberIds.length === 0) { throw new InvalidEventTypeConfigurationException('at least one required member'); } + if (foundEventType.teams && teamIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one team'); + } if (foundEventType.optionalMembers && optionalMemberIds.length === 0) { throw new InvalidEventTypeConfigurationException('at least one optional member'); } @@ -515,6 +521,9 @@ export default class CalendarService { if (foundEventType.requiredMembers && requiredMemberIds.length === 0) { throw new InvalidEventTypeConfigurationException('at least one required member'); } + if (foundEventType.teams && teamIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one team'); + } if (foundEventType.optionalMembers && optionalMemberIds.length === 0) { throw new InvalidEventTypeConfigurationException('at least one optional member'); } @@ -1250,6 +1259,7 @@ export default class CalendarService { * @param allDay Determines if this event type is all day. * @param requiredMembers Determines if this event type has required members. * @param optionalMembers Determines if this event type has optional members. + * @param teams Determines if this event type has teams. * @param location Determines if this event type has a location. * @param zoomLink Determines if this event type has a zoom link. * @param shop Determines if a shop is associated with this event type. @@ -1277,6 +1287,7 @@ export default class CalendarService { allDay: boolean, requiredMembers: boolean, optionalMembers: boolean, + teams: boolean, location: boolean, zoomLink: boolean, shop: boolean, @@ -1335,6 +1346,7 @@ export default class CalendarService { allDay, requiredMembers, optionalMembers, + teams, location, zoomLink, shop, diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 9fd965d272..7b115b2203 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -51,6 +51,7 @@ export const eventTypeTransformer = (eventType: Prisma.EventTypeGetPayload { false, false, false, + false, false ); }); @@ -247,6 +248,7 @@ describe('Calendar Tests', () => { true, true, true, + false, true, false, false, @@ -271,6 +273,7 @@ describe('Calendar Tests', () => { true, true, true, + false, true, true, false, @@ -288,6 +291,7 @@ describe('Calendar Tests', () => { expect(result.allDay).toBe(true); expect(result.requiredMembers).toBe(true); expect(result.optionalMembers).toBe(true); + expect(result.teams).toBe(false); expect(result.location).toBe(true); expect(result.zoomLink).toBe(true); expect(result.shop).toBe(false); @@ -622,6 +626,7 @@ describe('Calendar Tests', () => { false, false, false, + false, true, true ); @@ -649,6 +654,7 @@ describe('Calendar Tests', () => { false, false, false, + false, false ) ).rejects.toThrow(new AccessDeniedAdminOnlyException('edit event type')); @@ -676,6 +682,7 @@ describe('Calendar Tests', () => { true, true, true, + true, true ) ).rejects.toThrow(new NotFoundException('Calendar', invalidCalendarId)); @@ -721,6 +728,7 @@ describe('Calendar Tests', () => { false, false, false, + false, false ) ).rejects.toThrow(new InvalidOrganizationException('Calendar')); @@ -740,6 +748,7 @@ describe('Calendar Tests', () => { true, false, true, + false, true, false, false, @@ -765,6 +774,7 @@ describe('Calendar Tests', () => { false, true, true, + false, true, false, true, @@ -783,6 +793,7 @@ describe('Calendar Tests', () => { expect(result.eventTypeId).toBe(eventType.eventTypeId); expect(result.requiredMembers).toBe(true); expect(result.optionalMembers).toBe(true); + expect(result.teams).toBe(false); expect(result.location).toBe(true); expect(result.zoomLink).toBe(false); expect(result.shop).toBe(true); @@ -1951,6 +1962,7 @@ describe('Calendar Tests', () => { true, true, true, + false, true, false, false, @@ -2008,6 +2020,7 @@ describe('Calendar Tests', () => { true, true, true, + false, true, false, false, diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 490e00cd98..f196448013 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -70,6 +70,7 @@ export interface EventType { recurring: boolean; requiredMembers: boolean; optionalMembers: boolean; + teams: boolean; location: boolean; zoomLink: boolean; shop: boolean; From f74120d10857444e9bc9d3c22f582c3977ec085f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 2 Nov 2025 19:59:31 -0500 Subject: [PATCH 182/477] cleanup --- src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx | 1 - src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx index eae83f5005..27504d4513 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx @@ -5,7 +5,6 @@ import { Route, Switch } from 'react-router-dom'; import { routes } from '../../utils/routes'; import DesignReviewDetails from '../CalendarPage/DesignReviewDetailPage/DesignReviewDetails'; -import NewCalendarPage from './NewCalendarPage'; import CalendarTab from './CalendarTab'; const NewCalendar: React.FC = () => { diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index b23ec55603..0629e7158a 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -18,8 +18,6 @@ import LoadingIndicator from '../../components/LoadingIndicator'; import DRCSummaryModal from '../CalendarPage/DesignReviewSummaryModal'; import { useAllTeamTypes } from '../../hooks/team-types.hooks'; import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; -import FullPageTabs from '../../components/FullPageTabs'; -import { routes } from '../../utils/routes'; const NewCalendarPage = () => { const theme = useTheme(); From aced27cc0c43939121d140fb8ec006354b2d4fb8 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 2 Nov 2025 20:26:48 -0500 Subject: [PATCH 183/477] found some lint --- .../src/pages/NewCalendarPage/NewCalendarPage.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 0629e7158a..65ecdf2acf 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -34,7 +34,6 @@ const NewCalendarPage = () => { const [unconfirmedDesignReview, setUnconfirmedDesignReview] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); - const [tabIndex, setTabIndex] = useState(0); if (isLoading || !allDesignReviews) return ; if (isError) return ; @@ -188,16 +187,10 @@ const NewCalendarPage = () => { - From bca59a93c3b19a3c37bdab2e5aadd80d518894f0 Mon Sep 17 00:00:00 2001 From: Santiordon Date: Tue, 4 Nov 2025 22:35:05 -0500 Subject: [PATCH 184/477] #3706 Add default page --- src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx | 3 ++- .../src/pages/NewCalendarPage/YourEventsPage.tsx | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index c39d27bd48..6f97d0c1ca 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -1,5 +1,6 @@ import { routes } from '../../utils/routes'; import NewCalendarPage from './NewCalendarPage'; +import YourEventsPage from './YourEventsPage'; import PageLayout from '../../components/PageLayout'; import { Box } from '@mui/material'; import FullPageTabs from '../../components/FullPageTabs'; @@ -35,7 +36,7 @@ const CalendarTab: React.FC = () => { } > - {tabIndex === 1 ? : tabIndex === 0 ? : } + {tabIndex === 1 ? : tabIndex === 0 ? : } ); }; diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx new file mode 100644 index 0000000000..c615bd7ce3 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -0,0 +1,10 @@ +/* + * This file is part of NER's FinishLine and licensed under GNU AGPLv3. + * See the LICENSE file in the repository root folder for details. + */ + +const YourEventsPage = () => { + return
New Calendar Page
; +}; + +export default YourEventsPage; From 1cf8deeb760c83e7dfe195fb1c3f89f15be1012b Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Tue, 4 Nov 2025 22:56:19 -0500 Subject: [PATCH 185/477] initial edit shop modal --- src/frontend/src/apis/calendar.api.ts | 6 ++ src/frontend/src/hooks/calendar.hooks.ts | 17 ++++- .../ScheduleConfig/AddShopModal.tsx | 13 ++++ .../AdminToolsScheduleConfig.tsx | 65 ++++++++++++++++--- .../ScheduleConfig/EditShopModal.tsx | 14 ++++ .../{CreateShopModal.tsx => ShopModal.tsx} | 44 +++++++++---- src/frontend/src/utils/urls.ts | 2 + 7 files changed, 139 insertions(+), 22 deletions(-) create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AddShopModal.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EditShopModal.tsx rename src/frontend/src/pages/AdminToolsPage/ScheduleConfig/{CreateShopModal.tsx => ShopModal.tsx} (66%) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 84919e0437..34146fc7eb 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -13,3 +13,9 @@ export const postCreateShop = (payload: { name: string; description: string }) = transformResponse: (data) => JSON.parse(data) as Shop }); }; + +export const editShop = (shopId: string, payload: { name: string; description: string }) => { + return axios.post(apiUrls.calendarEditShop(shopId), payload, { + transformResponse: (data) => JSON.parse(data) as Shop + }); +}; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 49a28aee38..ac11dd1775 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,6 +1,6 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; import { Shop } from 'shared'; -import { getAllShops, postCreateShop } from '../apis/calendar.api'; +import { getAllShops, postCreateShop, editShop } from '../apis/calendar.api'; export const SHOPS_KEY = ['shops'] as const; @@ -24,3 +24,18 @@ export const useCreateShop = () => { } ); }; + +export const useEditShop = (shopId: string) => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + const { data } = await editShop(shopId, payload); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries(SHOPS_KEY); + } + } + ); +}; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AddShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AddShopModal.tsx new file mode 100644 index 0000000000..f2194dae73 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AddShopModal.tsx @@ -0,0 +1,13 @@ +import ShopModal, { ShopFormValues } from './ShopModal'; + +interface CreateShopModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: ShopFormValues) => Promise | unknown; +} + +const CreateShopModal: React.FC = (props) => { + return ; +}; + +export default CreateShopModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 0131ddce4b..89ea673614 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -1,10 +1,22 @@ import React, { useState } from 'react'; -import { Box, Grid, Typography, Paper, Table, TableBody, TableCell, TableHead, TableRow, Button } from '@mui/material'; +import { + Box, + Grid, + Typography, + Paper, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Button, + IconButton, + Tooltip +} from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; -import { useAllShops, useCreateShop } from '../../../hooks/calendar.hooks'; -import CreateShopModal from './CreateShopModal'; -import { IconButton, Tooltip } from '@mui/material'; +import { useAllShops, useCreateShop, useEditShop } from '../../../hooks/calendar.hooks'; +import ShopModal from './ShopModal'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; @@ -12,7 +24,12 @@ const AdminToolsScheduleConfig: React.FC = () => { const { data: shops, isLoading, isError, error } = useAllShops(); const { mutateAsync: createShopMutate } = useCreateShop(); + const [editingShopId, setEditingShopId] = useState(null); + const editShopMutation = useEditShop(editingShopId ?? ''); + const [openCreate, setOpenCreate] = useState(false); + const [openEdit, setOpenEdit] = useState(false); + const [editingShop, setEditingShop] = useState(null); if (isLoading) return ; if (isError) return ; @@ -46,7 +63,7 @@ const AdminToolsScheduleConfig: React.FC = () => { - {/* Shops table */} + {/* Shops Table */} @@ -82,7 +99,15 @@ const AdminToolsScheduleConfig: React.FC = () => { - + { + setEditingShop(shop); + setEditingShopId(shop.shopId); + setOpenEdit(true); + }} + > @@ -117,15 +142,39 @@ const AdminToolsScheduleConfig: React.FC = () => { - {/* Create Shop Modal */} - setOpenCreate(false)} + title="Add Shop" + initialValues={{ name: '', description: '' }} onSubmit={async ({ name, description }) => { await createShopMutate({ name, description }); setOpenCreate(false); }} /> + + {/* Edit Shop Modal */} + { + setOpenEdit(false); + setEditingShop(null); + setEditingShopId(null); + }} + title="Edit Shop" + initialValues={{ + name: editingShop?.name ?? '', + description: editingShop?.description ?? '' + }} + onSubmit={async ({ name, description }) => { + if (!editingShopId) return; + await editShopMutation.mutateAsync({ name, description }); + setOpenEdit(false); + setEditingShop(null); + setEditingShopId(null); + }} + /> ); }; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EditShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EditShopModal.tsx new file mode 100644 index 0000000000..a5530aa468 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EditShopModal.tsx @@ -0,0 +1,14 @@ +import ShopModal, { ShopFormValues } from './ShopModal'; + +export interface EditShopModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: ShopFormValues) => Promise | unknown; + initialValues: { name: string; description: string }; +} + +const EditShopModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { + return ; +}; + +export default EditShopModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx similarity index 66% rename from src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx rename to src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx index bfb6849abd..075411ae66 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/CreateShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx @@ -5,8 +5,9 @@ import { useToast } from '../../../hooks/toasts.hooks'; import { useForm } from 'react-hook-form'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; +import React from 'react'; -export interface CreateShopFormValues { +export interface ShopFormValues { name: string; description: string; } @@ -16,13 +17,15 @@ const schema = yup.object({ description: yup.string().required('Description is required') }); -interface CreateShopModalProps { +export interface BaseShopModalProps { open: boolean; onClose: () => void; - onSubmit: (data: CreateShopFormValues) => Promise | unknown; + onSubmit: (data: ShopFormValues) => Promise | unknown; + initialValues?: Partial; + title: string; } -export const CreateShopModal: React.FC = ({ open, onClose, onSubmit }) => { +const ShopModal: React.FC = ({ open, onClose, onSubmit, initialValues, title }) => { const toast = useToast(); const { @@ -30,30 +33,44 @@ export const CreateShopModal: React.FC = ({ open, onClose, control, reset, formState: { errors } - } = useForm({ + } = useForm({ resolver: yupResolver(schema), - defaultValues: { name: '', description: '' } + defaultValues: { + name: initialValues?.name ?? '', + description: initialValues?.description ?? '' + } }); - const onFormSubmit = async (data: CreateShopFormValues) => { + // keep defaults in sync when switching between shops while the modal is open + React.useEffect(() => { + reset({ + name: initialValues?.name ?? '', + description: initialValues?.description ?? '' + }); + }, [initialValues, reset]); + + const onFormSubmit = async (data: ShopFormValues) => { try { await onSubmit(data); + onClose(); + reset({ name: '', description: '' }); } catch (e: unknown) { if (e instanceof Error) toast.error(e.message); } - onClose(); - reset({ name: '', description: '' }); }; return ( { + onClose(); + reset({ name: '', description: '' }); + }} + title={title} reset={() => reset({ name: '', description: '' })} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} - formId="create-shop-form" + formId="shop-form" showCloseButton > @@ -76,4 +93,5 @@ export const CreateShopModal: React.FC = ({ open, onClose, ); }; -export default CreateShopModal; + +export default ShopModal; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 2ac1ba262a..a43b681b62 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -439,6 +439,7 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; const calendarCreateShop = () => `${calendar()}/shop/create`; +const calendarEditShop = (shopId: string) => `${calendar()}/shop/${shopId}/edit`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -743,6 +744,7 @@ export const apiUrls = { calendarShops, calendarCreateShop, + calendarEditShop, version }; From aa229309a7516a5ffd5edf993cc1e5bdd5a6a20b Mon Sep 17 00:00:00 2001 From: Santiordon Date: Wed, 5 Nov 2025 16:03:40 -0500 Subject: [PATCH 186/477] #3706 Add primitive UI and components for Demo --- .../YourEventsComponents/TableCellHuge.tsx | 35 ++++++ .../pages/NewCalendarPage/YourEventsPage.tsx | 115 +++++++++++++++++- 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 src/frontend/src/pages/NewCalendarPage/YourEventsComponents/TableCellHuge.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/TableCellHuge.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/TableCellHuge.tsx new file mode 100644 index 0000000000..124d67a26e --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/TableCellHuge.tsx @@ -0,0 +1,35 @@ +import { TableCell, Typography } from '@mui/material'; + +interface TableCellHugeProps { + title: string; +} + +/** + * Build the Table Cell for the header of the table. + * @param title The title of the table cell + **/ +const TableCellHuge: React.FC = ({ title }) => { + return ( + + + {title} + + + ); +}; + +export default TableCellHuge; diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index c615bd7ce3..753e57a615 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -2,9 +2,122 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ +import { + Box, + Button, + Paper, + Tab, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TablePagination, + TableRow, + Typography +} from '@mui/material'; +import PageTitle from '../../layouts/PageTitle/PageTitle'; +import TableCellHuge from './YourEventsComponents/TableCellHuge'; +import { useState } from 'react'; + +interface YourEventsHeadCells { + id: string; + label: string; +} + +const headCells: readonly YourEventsHeadCells[] = [ + { + id: 'eventsName', + label: 'Events Name' + }, + { + id: 'date', + label: 'Date' + }, + { + id: 'time', + label: 'Time' + }, + { + id: 'location', + label: 'Location' + }, + { + id: 'approvalBy', + label: 'Approval By' + }, + { + id: 'approvalStatus', + label: 'Approval Status' + } +]; const YourEventsPage = () => { - return
New Calendar Page
; + return ( + + + + + + + {headCells.map((headCell) => ( + + ))} + + + + {[...Array(100)].map((_, i) => ( + + {headCells.map((headCell) => ( + + {headCell.label} Data {i + 1} + + ))} + + ))} + + + + + + +
+
+
+ ); }; export default YourEventsPage; From 85b2330da46ca528810af751d7674bf6c28398b8 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 5 Nov 2025 17:57:37 -0500 Subject: [PATCH 187/477] #3674 Adding exception so shops cant be the same name --- src/backend/src/services/calendar.services.ts | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 6e4c5ef41a..dcf832dc1d 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -20,7 +20,8 @@ import { AccessDeniedException, DeletedException, InvalidOrganizationException, - NotFoundException + NotFoundException, + HttpException } from '../utils/errors.utils'; import { userHasPermission } from '../utils/users.utils'; import { eventTypeTransformer } from '../transformers/calendar.transformer'; @@ -501,6 +502,18 @@ export default class CalendarService { throw new AccessDeniedAdminOnlyException('create shop'); } + const existing = await prisma.shop.findFirst({ + where: { + organizationId: organization.organizationId, + dateDeleted: null, + name: { equals: name, mode: 'insensitive' } + } + }); + + if (existing) { + throw new HttpException(400, "Can't have two shops with the same name"); + } + const newShop = await prisma.shop.create({ data: { name, @@ -543,12 +556,22 @@ export default class CalendarService { if (existing.dateDeleted) throw new DeletedException('Shop', shopId); if (existing.organizationId !== organization.organizationId) throw new InvalidOrganizationException('Shop'); + const duplicate = await prisma.shop.findFirst({ + where: { + organizationId: organization.organizationId, + dateDeleted: null, + name: { equals: name, mode: 'insensitive' }, + NOT: { shopId } + } + }); + + if (duplicate) { + throw new HttpException(400, "Can't have two shops with the same name"); + } + const updatedShop = await prisma.shop.update({ where: { shopId }, - data: { - name, - description - }, + data: { name, description }, ...getShopQueryArgs(organization.organizationId) }); From eee5122f90f9691504da8a70fdf18c90db1a8f7d Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 5 Nov 2025 19:20:16 -0500 Subject: [PATCH 188/477] #3674 fixing exception and unique names in schema --- .../20251101233144_calendar/migration.sql | 15 --------------- src/backend/src/prisma/schema.prisma | 4 ---- src/backend/src/services/calendar.services.ts | 4 ++-- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index 2804446255..06ef54b69f 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -173,15 +173,6 @@ CREATE TABLE "public"."_CalendarToEventType" ( CONSTRAINT "_CalendarToEventType_AB_pkey" PRIMARY KEY ("A","B") ); --- CreateIndex -CREATE UNIQUE INDEX "Shop_name_key" ON "public"."Shop"("name"); - --- CreateIndex -CREATE UNIQUE INDEX "Shop_name_organizationId_key" ON "public"."Shop"("name", "organizationId"); - --- CreateIndex -CREATE UNIQUE INDEX "Machinery_name_organizationId_key" ON "public"."Machinery"("name", "organizationId"); - -- CreateIndex CREATE INDEX "ShopMachinery_machineryId_idx" ON "public"."ShopMachinery"("machineryId"); @@ -191,12 +182,6 @@ CREATE UNIQUE INDEX "ShopMachinery_shopId_machineryId_key" ON "public"."ShopMach -- CreateIndex CREATE INDEX "ScheduleSlot_initialDateScheduled_endDate_idx" ON "public"."ScheduleSlot"("initialDateScheduled", "endDate"); --- CreateIndex -CREATE UNIQUE INDEX "Calendar_name_organizationId_key" ON "public"."Calendar"("name", "organizationId"); - --- CreateIndex -CREATE UNIQUE INDEX "EventType_name_organizationId_key" ON "public"."EventType"("name", "organizationId"); - -- CreateIndex CREATE INDEX "_EventToScheduleSlot_B_index" ON "public"."_EventToScheduleSlot"("B"); diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index a4ba308563..c707cf99e1 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -983,7 +983,6 @@ model Shop { organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) - @@unique([name, organizationId], name: "uniqueShop") } model Machinery { @@ -1000,7 +999,6 @@ model Machinery { organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) - @@unique([name, organizationId], name: "uniqueMachinery") } model ShopMachinery { @@ -1083,7 +1081,6 @@ model Calendar { organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) - @@unique([name, organizationId], name: "uniqueCalendar") } model EventType { @@ -1113,7 +1110,6 @@ model EventType { organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) - @@unique([name, organizationId], name: "uniqueEventType") } model Team_Type { diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index dcf832dc1d..181d0f5e12 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -511,7 +511,7 @@ export default class CalendarService { }); if (existing) { - throw new HttpException(400, "Can't have two shops with the same name"); + throw new HttpException(409, "Can't have two shops with the same name"); } const newShop = await prisma.shop.create({ @@ -566,7 +566,7 @@ export default class CalendarService { }); if (duplicate) { - throw new HttpException(400, "Can't have two shops with the same name"); + throw new HttpException(409, "Can't have two shops with the same name"); } const updatedShop = await prisma.shop.update({ From e3a7cb5214ff3e42af07ed549b4bce9a4c28b4cd Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Wed, 5 Nov 2025 20:11:21 -0500 Subject: [PATCH 189/477] #3674 adding checks --- src/backend/src/services/calendar.services.ts | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 181d0f5e12..6d2b2fb642 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -104,6 +104,17 @@ export default class CalendarService { } } + const duplicate = await prisma.eventType.findFirst({ + where: { + organizationId: organization.organizationId, + dateDeleted: null, + name: { equals: name, mode: 'insensitive' } + } + }); + if (duplicate) { + throw new HttpException(409, "Can't have two event types with the same name"); + } + const newEventType = await prisma.eventType.create({ data: { name, @@ -172,6 +183,16 @@ export default class CalendarService { throw new InvalidOrganizationException('Shop'); } + const duplicate = await prisma.machinery.findFirst({ + where: { + organizationId: organization.organizationId, + dateDeleted: null, + name: { equals: name, mode: 'insensitive' } + } + }); + if (duplicate) { + throw new HttpException(409, "Can't have two machinery with the same name"); + } const newMachinery = await prisma.machinery.create({ data: { name, @@ -364,6 +385,18 @@ export default class CalendarService { return new Date(initial.getTime() + weeks * 7 * 24 * 60 * 60 * 1000); }; + const duplicate = await prisma.event.findFirst({ + where: { + dateDeleted: null, + title: { equals: title, mode: 'insensitive' }, + // scope to org via related eventType + eventType: { organizationId: organization.organizationId } + } + }); + if (duplicate) { + throw new HttpException(409, "Can't have two events with the same title"); + } + const newEvent = await prisma.event.create({ data: { userCreatedId: submitter.userId, @@ -472,6 +505,19 @@ export default class CalendarService { throw new InvalidOrganizationException('Shop'); } + const duplicate = await prisma.machinery.findFirst({ + where: { + organizationId: organization.organizationId, + dateDeleted: null, + name: { equals: name, mode: 'insensitive' }, + // exclude the current machinery + NOT: { machineryId } + } + }); + if (duplicate) { + throw new HttpException(409, "Can't have two machinery with the same name"); + } + // Update the machinery and its shop machinery relationship const updatedMachinery = await prisma.machinery.update({ where: { machineryId }, @@ -600,6 +646,17 @@ export default class CalendarService { throw new AccessDeniedAdminOnlyException('create calendar'); } + const duplicate = await prisma.calendar.findFirst({ + where: { + organizationId: organization.organizationId, + dateDeleted: null, + name: { equals: name, mode: 'insensitive' } + } + }); + if (duplicate) { + throw new HttpException(409, "Can't have two calendars with the same name"); + } + const newCalendar = await prisma.calendar.create({ data: { name, @@ -651,6 +708,19 @@ export default class CalendarService { throw new AccessDeniedException('Only admins can edit calendars'); } + const duplicate = await prisma.calendar.findFirst({ + where: { + organizationId: organization.organizationId, + dateDeleted: null, + name: { equals: name, mode: 'insensitive' }, + NOT: { calendarId } + } + }); + + if (duplicate) { + throw new HttpException(409, "Can't have two calendars with the same name"); + } + const newCalendar = await prisma.calendar.update({ where: { calendarId }, data: { From 54b823089d749587546adf8feba45d753c5ffd0d Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 5 Nov 2025 23:47:00 -0500 Subject: [PATCH 190/477] #3634 Updated machinery edit to only allow delete machinery via delete and not have quantity 0, and for relationships not actual machines --- src/backend/src/routes/calendar.routes.ts | 2 + src/backend/src/services/calendar.services.ts | 90 ++++++++----------- .../Machinery/CreateMachineryModal.tsx | 4 +- .../Machinery/MachineryFormModal.tsx | 17 ++-- 4 files changed, 56 insertions(+), 57 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index a317c370dc..3ef42ef464 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -146,6 +146,8 @@ calendarRouter.post('/shop/:shopId/delete', nonEmptyString(param('shopId')), val calendarRouter.get('/shops', CalendarController.getAllShops); +calendarRouter.get('/machinery', CalendarController.getAllMachinery); + // no restrictions filtering, in case multiple filters need to be sent calendarRouter.post( '/events/filter', diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 70309feb56..555eccdbd8 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -403,7 +403,7 @@ export default class CalendarService { /** * Edits an existing machinery name. If the new name matches another existing machinery, - * all shop relationships are merged into that machinery and the old machinery is deleted. + * all shop relationships are merged into that machinery. The machinery itself is kept (not deleted). * * @param submitter The user submitting the request, who must be a head or above. * @param machineryId The ID of the machinery to edit. @@ -496,10 +496,8 @@ export default class CalendarService { } } - // Delete the old machinery (all relationships have been moved) - await tx.machinery.delete({ - where: { machineryId } - }); + // Note: Machinery is kept even if all relationships are moved + // Only shop-machinery relationships are deleted, not the machinery itself // Return the consolidated machinery const resultMachinery = await tx.machinery.findUnique({ @@ -637,35 +635,41 @@ export default class CalendarService { }); } - // If this was a different machinery, clean up if it has no more shops - if (existingMachineryWithSameName.machineryId !== machineryId) { - const remainingShops = await tx.shopMachinery.findMany({ - where: { machineryId } - }); - if (remainingShops.length === 0) { - await tx.machinery.delete({ - where: { machineryId } - }); - } - } - } else if (quantity === 0) { - // Same relationship, delete if quantity is 0 - await tx.shopMachinery.delete({ - where: { shopMachineryId: existingShopMachinery.shopMachineryId } - }); + // Note: Machinery is kept even if it has no more shops + // Only shop-machinery relationships are deleted, not the machinery itself } else if (shopMachineryToUpdate) { - // Edit operation - set/replace quantity - await tx.shopMachinery.update({ - where: { shopMachineryId: existingShopMachinery.shopMachineryId }, - data: { quantity } + // Edit operation: editing into same machine name + same shop after consolidation + // Delete the old relationship and add quantity to existing one + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } }); + + if (quantity === 0) { + // If quantity is 0, just delete the existing relationship too + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } else { + // Add quantity to existing relationship + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); + } } else { - // Add operation - increment quantity - const newQuantity = existingShopMachinery.quantity + quantity; - await tx.shopMachinery.update({ - where: { shopMachineryId: existingShopMachinery.shopMachineryId }, - data: { quantity: newQuantity } - }); + // Add operation - increment quantity (quantity can be 0 to delete) + if (quantity === 0) { + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } else { + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); + } } const resultMachinery = await tx.machinery.findUnique({ @@ -722,15 +726,8 @@ export default class CalendarService { }); } - // Clean up old machinery if it has no more shops - const remainingShops = await tx.shopMachinery.findMany({ - where: { machineryId } - }); - if (remainingShops.length === 0) { - await tx.machinery.delete({ - where: { machineryId } - }); - } + // Note: Machinery is kept even if it has no more shops + // Only shop-machinery relationships are deleted, not the machinery itself const resultMachinery = await tx.machinery.findUnique({ where: { machineryId: existingMachineryWithSameName.machineryId }, @@ -835,17 +832,8 @@ export default class CalendarService { } } - // Clean up machinery if it has no more shops after deletion - if (quantity === 0) { - const remainingShops = await tx.shopMachinery.findMany({ - where: { machineryId } - }); - if (remainingShops.length === 0) { - await tx.machinery.delete({ - where: { machineryId } - }); - } - } + // Note: Machinery is kept even if quantity is 0 and it has no more shops + // Only shop-machinery relationships are deleted, not the machinery itself const updatedMachineryResult = await tx.machinery.findUnique({ where: { machineryId }, diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx index f7c462bccd..963444dfe8 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/CreateMachineryModal.tsx @@ -27,7 +27,9 @@ const CreateMachineryModal = ({ open, onClose }: CreateMachineryModalProps) => { shopId, quantity }); - queryClient.invalidateQueries(MACHINERY_KEY); + // Invalidate and refetch to ensure UI updates immediately + await queryClient.invalidateQueries(MACHINERY_KEY); + await queryClient.refetchQueries(MACHINERY_KEY); return result; }; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx index 54c1cdc819..a6482a9a38 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Machinery/MachineryFormModal.tsx @@ -71,12 +71,19 @@ export const MachineryFormModal: React.FC = ({ open, on const onFormSubmit = async (data: MachineryFormValues) => { try { await onSubmit(data); + // Only close and reset on success + onClose(); + if (!initialValues) { + reset(defaultValues); + } } catch (e: unknown) { - if (e instanceof Error) toast.error(e.message); - } - onClose(); - if (!initialValues) { - reset(defaultValues); + // Show error but don't close modal + if (e instanceof Error) { + toast.error(e.message); + } else { + toast.error('An error occurred while saving the machinery'); + } + // Don't close modal on error so user can fix and retry } }; From 1a7110d9a036a75b727b5b627901e602867d3676 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Thu, 6 Nov 2025 00:02:31 -0500 Subject: [PATCH 191/477] #3634 Fixed linting issues and added relationship adjustment to quantity merging ShopMachineries --- src/backend/src/services/calendar.services.ts | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 555eccdbd8..b45810293a 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -637,39 +637,52 @@ export default class CalendarService { // Note: Machinery is kept even if it has no more shops // Only shop-machinery relationships are deleted, not the machinery itself - } else if (shopMachineryToUpdate) { - // Edit operation: editing into same machine name + same shop after consolidation - // Delete the old relationship and add quantity to existing one - await tx.shopMachinery.delete({ - where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } - }); - + } else if ( + shopMachineryToUpdate && + shopMachineryToUpdate.shopMachineryId === existingShopMachinery.shopMachineryId + ) { + // Same relationship - just update the quantity (edit operation) if (quantity === 0) { - // If quantity is 0, just delete the existing relationship too await tx.shopMachinery.delete({ where: { shopMachineryId: existingShopMachinery.shopMachineryId } }); } else { - // Add quantity to existing relationship - const newQuantity = existingShopMachinery.quantity + quantity; await tx.shopMachinery.update({ where: { shopMachineryId: existingShopMachinery.shopMachineryId }, - data: { quantity: newQuantity } + data: { quantity } }); } - } else { - // Add operation - increment quantity (quantity can be 0 to delete) + } else if (shopMachineryToUpdate) { + // Different relationship - delete old and add to existing + await tx.shopMachinery.delete({ + where: { shopMachineryId: shopMachineryToUpdate.shopMachineryId } + }); + if (quantity === 0) { + // If quantity is 0, just delete the existing relationship too await tx.shopMachinery.delete({ where: { shopMachineryId: existingShopMachinery.shopMachineryId } }); } else { + // Add quantity to existing relationship const newQuantity = existingShopMachinery.quantity + quantity; await tx.shopMachinery.update({ where: { shopMachineryId: existingShopMachinery.shopMachineryId }, data: { quantity: newQuantity } }); } + } else if (quantity === 0) { + // Add operation - if quantity is 0, delete the relationship + await tx.shopMachinery.delete({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId } + }); + } else { + // Add operation - increment quantity + const newQuantity = existingShopMachinery.quantity + quantity; + await tx.shopMachinery.update({ + where: { shopMachineryId: existingShopMachinery.shopMachineryId }, + data: { quantity: newQuantity } + }); } const resultMachinery = await tx.machinery.findUnique({ From bcc86bbef64c46315d3fec1b140962fd36ed1f52 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Fri, 7 Nov 2025 09:20:03 -0500 Subject: [PATCH 192/477] #3674 Fixing requested changes --- src/frontend/src/hooks/calendar.hooks.ts | 8 +-- .../ScheduleConfig/AddShopModal.tsx | 2 +- .../AdminToolsScheduleConfig.tsx | 9 +-- .../ScheduleConfig/EditShopModal.tsx | 4 +- .../ScheduleConfig/ShopModal.tsx | 55 ++++++++++++------- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index ac11dd1775..15bcd2c209 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -2,10 +2,8 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; import { Shop } from 'shared'; import { getAllShops, postCreateShop, editShop } from '../apis/calendar.api'; -export const SHOPS_KEY = ['shops'] as const; - export const useAllShops = () => - useQuery(SHOPS_KEY, async () => { + useQuery(['shops'], async () => { const res = await getAllShops(); return res.data; }); @@ -19,7 +17,7 @@ export const useCreateShop = () => { }, { onSuccess: () => { - qc.invalidateQueries(SHOPS_KEY); + qc.invalidateQueries(['shops']); } } ); @@ -34,7 +32,7 @@ export const useEditShop = (shopId: string) => { }, { onSuccess: () => { - qc.invalidateQueries(SHOPS_KEY); + qc.invalidateQueries(['shops']); } } ); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AddShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AddShopModal.tsx index f2194dae73..6e78a9ec89 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AddShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AddShopModal.tsx @@ -7,7 +7,7 @@ interface CreateShopModalProps { } const CreateShopModal: React.FC = (props) => { - return ; + return ; }; export default CreateShopModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 89ea673614..5f62ecb442 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -24,7 +24,7 @@ const AdminToolsScheduleConfig: React.FC = () => { const { data: shops, isLoading, isError, error } = useAllShops(); const { mutateAsync: createShopMutate } = useCreateShop(); - const [editingShopId, setEditingShopId] = useState(null); + const [editingShopId, setEditingShopId] = useState(); const editShopMutation = useEditShop(editingShopId ?? ''); const [openCreate, setOpenCreate] = useState(false); @@ -146,8 +146,6 @@ const AdminToolsScheduleConfig: React.FC = () => { setOpenCreate(false)} - title="Add Shop" - initialValues={{ name: '', description: '' }} onSubmit={async ({ name, description }) => { await createShopMutate({ name, description }); setOpenCreate(false); @@ -160,9 +158,8 @@ const AdminToolsScheduleConfig: React.FC = () => { onClose={() => { setOpenEdit(false); setEditingShop(null); - setEditingShopId(null); + setEditingShopId(undefined); }} - title="Edit Shop" initialValues={{ name: editingShop?.name ?? '', description: editingShop?.description ?? '' @@ -172,7 +169,7 @@ const AdminToolsScheduleConfig: React.FC = () => { await editShopMutation.mutateAsync({ name, description }); setOpenEdit(false); setEditingShop(null); - setEditingShopId(null); + setEditingShopId(undefined); }} /> diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EditShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EditShopModal.tsx index a5530aa468..5a3ed2192b 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EditShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EditShopModal.tsx @@ -4,11 +4,11 @@ export interface EditShopModalProps { open: boolean; onClose: () => void; onSubmit: (data: ShopFormValues) => Promise | unknown; - initialValues: { name: string; description: string }; + initialValues: Partial; } const EditShopModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { - return ; + return ; }; export default EditShopModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx index 075411ae66..585670c6e3 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx @@ -22,10 +22,9 @@ export interface BaseShopModalProps { onClose: () => void; onSubmit: (data: ShopFormValues) => Promise | unknown; initialValues?: Partial; - title: string; } -const ShopModal: React.FC = ({ open, onClose, onSubmit, initialValues, title }) => { +const ShopModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { const toast = useToast(); const { @@ -35,19 +34,28 @@ const ShopModal: React.FC = ({ open, onClose, onSubmit, init formState: { errors } } = useForm({ resolver: yupResolver(schema), - defaultValues: { - name: initialValues?.name ?? '', - description: initialValues?.description ?? '' - } + defaultValues: { name: '', description: '' } }); - // keep defaults in sync when switching between shops while the modal is open + const frozenValuesRef = React.useRef({ name: '', description: '' }); + React.useEffect(() => { - reset({ - name: initialValues?.name ?? '', - description: initialValues?.description ?? '' - }); - }, [initialValues, reset]); + if (open) { + // whatever initialValues are at the time of opening + frozenValuesRef.current = { + name: initialValues?.name ?? '', + description: initialValues?.description ?? '' + }; + reset(frozenValuesRef.current); + } else { + // when closed, clear everything + frozenValuesRef.current = { name: '', description: '' }; + reset(frozenValuesRef.current); + } + }, [open, initialValues, reset]); + + const computedTitle = + frozenValuesRef.current.name !== '' || frozenValuesRef.current.description !== '' ? 'Edit Shop' : 'Create Shop'; const onFormSubmit = async (data: ShopFormValues) => { try { @@ -66,7 +74,7 @@ const ShopModal: React.FC = ({ open, onClose, onSubmit, init onClose(); reset({ name: '', description: '' }); }} - title={title} + title={computedTitle} reset={() => reset({ name: '', description: '' })} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} @@ -82,13 +90,20 @@ const ShopModal: React.FC = ({ open, onClose, onSubmit, init {errors.name?.message} - - - Description:* - - - {errors.description?.message} - + + + Description:* + + + {errors.description?.message} + ); From c8a4d6710df8440ea64f3d2153e149be4e224bdd Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Fri, 7 Nov 2025 09:25:05 -0500 Subject: [PATCH 193/477] #3674 fixing prettier --- .../ScheduleConfig/ShopModal.tsx | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx index 585670c6e3..8d86fdf72b 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/ShopModal.tsx @@ -90,20 +90,20 @@ const ShopModal: React.FC = ({ open, onClose, onSubmit, init {errors.name?.message} - - - Description:* - - - {errors.description?.message} - + + + Description:* + + + {errors.description?.message} + ); From fe267b3efb6f0dd9e042881d9c6600dc6f835f1d Mon Sep 17 00:00:00 2001 From: sam gunss Date: Fri, 7 Nov 2025 19:15:51 -0500 Subject: [PATCH 194/477] #3700: Add new event button --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 65ecdf2acf..63027a1253 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -3,7 +3,7 @@ * See the LICENSE file in the repository root folder for details. */ import { useState } from 'react'; -import { Box, Grid, Stack, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material'; +import { Box, Grid, Stack, Tooltip, Typography, useMediaQuery, useTheme, Button, IconButton } from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { DesignReview, DesignReviewStatus } from 'shared'; import MonthSelector from '../CalendarPage/CalendarComponents/MonthSelector'; @@ -18,6 +18,7 @@ import LoadingIndicator from '../../components/LoadingIndicator'; import DRCSummaryModal from '../CalendarPage/DesignReviewSummaryModal'; import { useAllTeamTypes } from '../../hooks/team-types.hooks'; import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; +import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; const NewCalendarPage = () => { const theme = useTheme(); @@ -133,7 +134,32 @@ const NewCalendarPage = () => { - + + {/* New Event Button (does not do anything yet) */} + {isExtraSmallView ? ( + + {}}> + + + + ) : ( + + )} From 8f7701c31ff570afee6402355abe90c240543b44 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 9 Nov 2025 21:14:35 -0500 Subject: [PATCH 195/477] #3569 requested changes + naisha insight --- .../src/controllers/calendar.controllers.ts | 14 +- .../20251101233144_calendar/migration.sql | 1 + src/backend/src/prisma/schema.prisma | 3 + src/backend/src/prisma/seed.ts | 142 +++--- src/backend/src/routes/calendar.routes.ts | 5 +- .../src/routes/design-reviews.routes.ts | 6 +- src/backend/src/services/calendar.services.ts | 191 ++++---- src/backend/src/utils/calendar.utils.ts | 192 +++++++- src/backend/src/utils/validation.utils.ts | 2 +- src/backend/tests/unit/calendar.test.ts | 457 ++++++++++-------- 10 files changed, 646 insertions(+), 367 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 035d82a39c..1523990839 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -22,7 +22,8 @@ export default class CalendarController { questionDocument, documents, description, - onlyHeadsOrAbove + onlyHeadsOrAbove, + requiresConfirmation } = req.body; const eventType = await CalendarService.createEventType( @@ -44,7 +45,8 @@ export default class CalendarController { questionDocument, documents, description, - onlyHeadsOrAbove + onlyHeadsOrAbove, + requiresConfirmation ); res.status(200).json(eventType); } catch (error: unknown) { @@ -193,7 +195,8 @@ export default class CalendarController { questionDocument, documents, description, - onlyHeadsOrAbove + onlyHeadsOrAbove, + requiresConfirmation } = req.body; const eventType = await CalendarService.editEventType( @@ -216,7 +219,8 @@ export default class CalendarController { questionDocument, documents, description, - onlyHeadsOrAbove + onlyHeadsOrAbove, + requiresConfirmation ); res.status(200).json(eventType); } catch (error: unknown) { @@ -298,6 +302,7 @@ export default class CalendarController { requiredMemberIds, optionalMemberIds, teamIds, + status, shopIds, machineryIds, workPackageIds, @@ -315,6 +320,7 @@ export default class CalendarController { req.organization, requiredMemberIds, optionalMemberIds, + status, teamIds, shopIds, machineryIds, diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index 6b3b7d54b7..cecba2baf9 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -111,6 +111,7 @@ CREATE TABLE "public"."EventType" ( "documents" BOOLEAN NOT NULL DEFAULT FALSE, "description" BOOLEAN NOT NULL DEFAULT FALSE, "onlyHeadsOrAboveForEventCreation" BOOLEAN NOT NULL DEFAULT FALSE, + "requiresConfirmation" BOOLEAN NOT NULL DEFAULT FALSE, "organizationId" TEXT NOT NULL, CONSTRAINT "EventType_pkey" PRIMARY KEY ("eventTypeId") diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index b3f408e3d8..836f227924 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1055,6 +1055,8 @@ model Event { eventTypeId String eventType EventType @relation(fields: [eventTypeId], references: [eventTypeId]) approved Boolean @default(false) + // when approval is false, approved by holds who needs to approve the event + // when approval is true, approved by holds who actually approved the event approvedByUserId String? approvedBy User? @relation(fields: [approvedByUserId], references: [userId], name: "eventApprover") scheduledTimes ScheduleSlot[] @@ -1117,6 +1119,7 @@ model EventType { documents Boolean description Boolean onlyHeadsOrAboveForEventCreation Boolean + requiresConfirmation Boolean events Event[] organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index ba74aa2208..1a51885770 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3199,13 +3199,14 @@ const performSeed: () => Promise = async () => { false, true, true, + true, + false, + false, + false, false, false, false, - true, - true, false, - true, false ); @@ -3222,18 +3223,19 @@ const performSeed: () => Promise = async () => { true, false, true, - false, - false, + true, false, false, true, true, true, + false, + true, true ); // manufacturing event type - await CalendarService.createEventType( + const manufacturingEventType = await CalendarService.createEventType( thomasEmrax, 'Manufacturing', [], @@ -3249,6 +3251,7 @@ const performSeed: () => Promise = async () => { true, true, true, + true, false, false, true, @@ -3256,7 +3259,7 @@ const performSeed: () => Promise = async () => { ); // bay time event type - await CalendarService.createEventType( + const bayTimeEventType = await CalendarService.createEventType( thomasEmrax, 'Bay Time', [], @@ -3269,125 +3272,126 @@ const performSeed: () => Promise = async () => { false, false, false, - true, false, true, false, false, - true, - true + false, + false, + false, + false ); - // Add these event creations after the event type creations in the seed script await CalendarService.createEvent( thomasEmrax, - 'Impact Attenuator Design Review', - designReviewEventType.eventTypeId, + 'Weekly Team Sync', + meetingEventType.eventTypeId, ner, - [joeShmoe.userId, joeBlow.userId], - [batman.userId], [], - [advancedShop.shopId], - [printer.machineryId, hammer.machineryId], - [workPackage1.id], - ['https://docs.google.com/document/d/1_example'], + [], + [justiceLeague.teamId], + [], + [], + [], + [], [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], - startTime: new Date(), + days: [DayOfWeek.MONDAY], + startTime: new Date('2025-10-21T10:00:00.000Z'), + endTime: new Date('2025-10-21T11:00:00.000Z'), recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-20T00:00:00.000Z'), + initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), allDay: false } ], - 'https://docs.google.com/document/d/1_example', + undefined, 'Conference Room A', 'https://zoom.us/j/123456789', - 'Review design specifications for the impact attenuator' + undefined ); await CalendarService.createEvent( - batman, - 'Wiring Harness Installation Planning', + thomasEmrax, + 'Impact Attenuator Design Review', designReviewEventType.eventTypeId, ner, - [regina.userId, janis.userId], - [cady.userId], + [joeShmoe.userId, joeBlow.userId], + [batman.userId], [], - [electronicsLab.shopId], - [printer.machineryId], - [workPackage3.id, workPackage4.id], - ['https://docs.google.com/document/d/1_example'], + [], + [], + [workPackage1.id], + ['doc1', 'doc2'], [ { - days: [DayOfWeek.WEDNESDAY], + days: [DayOfWeek.TUESDAY], startTime: new Date('2025-10-22T14:00:00.000Z'), - endTime: new Date('2025-10-22T15:30:00.000Z'), - recurrenceNumber: 2, + endTime: new Date('2025-10-22T16:00:00.000Z'), + recurrenceNumber: 1, initialDateScheduled: new Date('2025-10-22T00:00:00.000Z'), allDay: false } ], 'https://docs.google.com/document/d/2_example', - 'Electronics Lab', + 'Conference Room B', 'https://zoom.us/j/987654321', - 'Plan the installation process for the wiring harness' + undefined ); await CalendarService.createEvent( - aang, - 'Appa Plush Design Brainstorm', - meetingEventType.eventTypeId, + batman, + 'Wiring Harness Manufacturing', + manufacturingEventType.eventTypeId, ner, - [katara.userId, sokka.userId], - [toph.userId], - [justiceLeague.teamId], - [], + [regina.userId, janis.userId], + [cady.userId], [], - [workPackage5.id], + [electronicsLab.shopId], + [printer.machineryId], + [workPackage3.id], [], [ { - days: [DayOfWeek.FRIDAY], - startTime: new Date('2025-10-24T10:00:00.000Z'), - endTime: new Date('2025-10-24T11:00:00.000Z'), + days: [DayOfWeek.WEDNESDAY], + startTime: new Date('2025-10-23T09:00:00.000Z'), + endTime: new Date('2025-10-23T12:00:00.000Z'), recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-24T00:00:00.000Z'), + initialDateScheduled: new Date('2025-10-23T00:00:00.000Z'), allDay: false } ], 'https://docs.google.com/document/d/3_example', - 'Design Studio', - 'https://zoom.us/j/456789123', - 'Brainstorm design ideas for Appa plush prototypes' + undefined, + undefined, + undefined ); await CalendarService.createEvent( - lexLuther, - 'Laser Cannon Prototype Review', - meetingEventType.eventTypeId, + aang, + 'Composite Layup Bay Time', + bayTimeEventType.eventTypeId, ner, - [zatanna.userId, superman.userId], - [wonderwoman.userId], - [orioles.teamId], - [testingFacility.shopId], - [ironMachine.machineryId, hammer.machineryId], - [project3WP1.id], + [katara.userId, sokka.userId], + [], + [], + [], + [ironMachine.machineryId], + [], [], [ { - days: [DayOfWeek.MONDAY], - startTime: new Date('2025-10-27T13:00:00.000Z'), - endTime: new Date('2025-10-27T14:30:00.000Z'), + days: [DayOfWeek.THURSDAY], + startTime: new Date('2025-10-24T13:00:00.000Z'), + endTime: new Date('2025-10-24T17:00:00.000Z'), recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-27T00:00:00.000Z'), + initialDateScheduled: new Date('2025-10-24T00:00:00.000Z'), allDay: false } ], - 'https://docs.google.com/document/d/4_example', - 'Testing Facility', - 'https://zoom.us/j/789123456', - 'Review progress and test results for laser cannon prototype' + undefined, + undefined, + undefined, + undefined ); }; diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 3fa93bbb43..fdc614be8e 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,6 +1,6 @@ import express from 'express'; import { body, param } from 'express-validator'; -import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek } from '../utils/validation.utils'; +import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek, isEventStatus } from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; const calendarRouter = express.Router(); @@ -34,6 +34,7 @@ calendarRouter.post( body('documents').isBoolean(), body('description').isBoolean(), body('onlyHeadsOrAbove').isBoolean(), + body('requiresConfirmation').isBoolean(), validateInputs, CalendarController.createEventType ); @@ -58,6 +59,7 @@ calendarRouter.post( body('documents').isBoolean(), body('description').isBoolean(), body('onlyHeadsOrAbove').isBoolean(), + body('requiresConfirmation').isBoolean(), validateInputs, CalendarController.editEventType ); @@ -105,6 +107,7 @@ calendarRouter.post( nonEmptyString(body('optionalMemberIds.*')), body('teamIds').isArray(), body('teamIds.*').isString(), + isEventStatus(body('status')), body('location').optional().isString(), body('zoomLink').optional().isURL(), body('shopIds').isArray(), diff --git a/src/backend/src/routes/design-reviews.routes.ts b/src/backend/src/routes/design-reviews.routes.ts index fc034c1faa..3b08a7185f 100644 --- a/src/backend/src/routes/design-reviews.routes.ts +++ b/src/backend/src/routes/design-reviews.routes.ts @@ -1,6 +1,6 @@ import express from 'express'; import { body } from 'express-validator'; -import { intMinZero, nonEmptyString, isDate, isDesignReviewStatus, validateInputs } from '../utils/validation.utils'; +import { intMinZero, nonEmptyString, isDate, isEventStatus, validateInputs } from '../utils/validation.utils'; import DesignReviewsController from '../controllers/design-reviews.controllers'; const designReviewsRouter = express.Router(); @@ -39,7 +39,7 @@ designReviewsRouter.post( nonEmptyString(body('zoomLink')).isURL().optional(), nonEmptyString(body('location')).optional(), nonEmptyString(body('docTemplateLink')).optional(), - isDesignReviewStatus(body('status')), + isEventStatus(body('status')), body('attendees').isArray(), nonEmptyString(body('attendees.*')), body('meetingTimes').isArray(), @@ -60,7 +60,7 @@ designReviewsRouter.post( designReviewsRouter.post( '/:designReviewId/set-status', - isDesignReviewStatus(body('status')), + isEventStatus(body('status')), validateInputs, DesignReviewsController.setStatus ); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 23cb330aef..22c930bfee 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -21,7 +21,6 @@ import { AccessDeniedException, DeletedException, HttpException, - InvalidEventTypeConfigurationException, InvalidOrganizationException, NotFoundException } from '../utils/errors.utils'; @@ -38,7 +37,12 @@ import { shopTransformer } from '../transformers/calendar.transformer'; import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; import { getCalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; import { getEventQueryArgs } from '../prisma-query-args/event.query-args'; -import { buildScheduledTimesOverlap, isUserOnEvent } from '../utils/calendar.utils'; +import { + buildScheduledTimesOverlap, + checkEventConflicts, + isUserOnEvent, + validateEventTypeConfiguration +} from '../utils/calendar.utils'; import { UserWithSettings } from '../utils/auth.utils'; import { getUserScheduleSettingsQueryArgs } from '../prisma-query-args/user.query-args'; @@ -91,7 +95,8 @@ export default class CalendarService { questionDocument: boolean, documents: boolean, description: boolean, - onlyHeadsOrAbove: boolean + onlyHeadsOrAbove: boolean, + requiresConfirmation: boolean ): Promise { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create event type'); @@ -140,6 +145,7 @@ export default class CalendarService { documents, description, onlyHeadsOrAboveForEventCreation: onlyHeadsOrAbove, + requiresConfirmation, organizationId: organization.organizationId }, ...getEventTypeQueryArgs(organization.organizationId) @@ -262,7 +268,7 @@ export default class CalendarService { } if (foundEventType.onlyHeadsOrAboveForEventCreation) { - const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isHead || isAdmin); + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isHead); if (!hasPermission) { throw new AccessDeniedException('Only admins and heads can create events under this event type'); @@ -270,42 +276,20 @@ export default class CalendarService { } // Validate event follows event type configuration - if (foundEventType.requiredMembers && requiredMemberIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one required member'); - } - if (foundEventType.teams && teamIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one team'); - } - if (foundEventType.optionalMembers && optionalMemberIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one optional member'); - } - if (foundEventType.location && !location) { - throw new InvalidEventTypeConfigurationException('a location'); - } - if (foundEventType.zoomLink && !zoomLink) { - throw new InvalidEventTypeConfigurationException('a zoom link'); - } - if (foundEventType.shop && shopIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one shop'); - } - if (foundEventType.machinery && machineryIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one machinery'); - } - if (foundEventType.workPackage && workPackageIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one work package'); - } - if (foundEventType.questionDocument && !questionDocument) { - throw new InvalidEventTypeConfigurationException('a question document'); - } - if (foundEventType.documents && documentIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one document'); - } - if (foundEventType.description && !description) { - throw new InvalidEventTypeConfigurationException('a description'); - } - if (foundEventType.initialDateScheduled && scheduleSlot.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one schedule slot'); - } + validateEventTypeConfiguration(foundEventType, { + requiredMemberIds, + optionalMemberIds, + teamIds, + shopIds, + machineryIds, + workPackageIds, + documentIds, + scheduleSlot, + location, + zoomLink, + questionDocument, + description + }); // Validate required memberIds if (requiredMemberIds.length > 0) { @@ -404,6 +388,9 @@ export default class CalendarService { } } + // Check for conflicts + const { hasConflict, approverUserId } = await checkEventConflicts(scheduleSlot, organization, location, undefined); + const computeEndDate = (initial: Date, recurrenceNumber: number) => { const weeks = Math.max(1, recurrenceNumber ?? 0); return new Date(initial.getTime() + weeks * 7 * 24 * 60 * 60 * 1000); @@ -445,9 +432,9 @@ export default class CalendarService { allDay: s.allDay })) }, - status: Event_Status.UNCONFIRMED, - approved: false, - approvedByUserId: null, + status: foundEventType.requiresConfirmation ? Event_Status.UNCONFIRMED : Event_Status.CONFIRMED, + approved: !hasConflict, + approvedByUserId: hasConflict ? approverUserId : null, location, zoomLink, questionDocument, @@ -468,6 +455,7 @@ export default class CalendarService { * @param organization The organization for which the event type is being created. * @param requiredMemberIds An array of required member ids that are invited to the event. * @param optionalMemberIds An array of optional member ids that are invited to the event. + * @param status see Event_Status enum * @param shopIds An array of shops associated with the event. * @param machineryIds An array of machinery associated with the event. * @param workPackageIds An array of work packages associated with the event. @@ -490,6 +478,7 @@ export default class CalendarService { organization: Organization, requiredMemberIds: string[], optionalMemberIds: string[], + status: Event_Status, teamIds: string[], shopIds: string[], machineryIds: string[], @@ -503,7 +492,8 @@ export default class CalendarService { ): Promise { // validate eventId const foundEvent = await prisma.event.findUnique({ - where: { eventId } + where: { eventId }, + ...getEventQueryArgs(organization.organizationId) }); if (!foundEvent) throw new NotFoundException('Event', eventId); @@ -518,44 +508,23 @@ export default class CalendarService { if (foundEventType.dateDeleted) throw new DeletedException('Event Type', eventTypeId); // Validate event follows event type configuration - if (foundEventType.requiredMembers && requiredMemberIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one required member'); - } - if (foundEventType.teams && teamIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one team'); - } - if (foundEventType.optionalMembers && optionalMemberIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one optional member'); - } - if (foundEventType.location && !location) { - throw new InvalidEventTypeConfigurationException('a location'); - } - if (foundEventType.zoomLink && !zoomLink) { - throw new InvalidEventTypeConfigurationException('a zoom link'); - } - if (foundEventType.shop && shopIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one shop'); - } - if (foundEventType.machinery && machineryIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one machinery'); - } - if (foundEventType.workPackage && workPackageIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one work package'); - } - if (foundEventType.questionDocument && !questionDocument) { - throw new InvalidEventTypeConfigurationException('a question document'); - } - if (foundEventType.documents && documentIds.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one document'); - } - if (foundEventType.description && !description) { - throw new InvalidEventTypeConfigurationException('a description'); - } - if (foundEventType.initialDateScheduled && scheduleSlot.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one schedule slot'); - } - if (foundEventType.name === 'Design Review') { - // question document is required if the status is scheduled or done + validateEventTypeConfiguration(foundEventType, { + requiredMemberIds, + optionalMemberIds, + teamIds, + shopIds, + machineryIds, + workPackageIds, + documentIds, + scheduleSlot, + location, + zoomLink, + questionDocument, + description + }); + + // question document is required if the status is scheduled or done + if (foundEventType.requiresConfirmation) { if (foundEvent.status === Event_Status.SCHEDULED || foundEvent.status === Event_Status.DONE) { if (questionDocument == null) { throw new HttpException(400, 'doc template link is required for scheduled and done design reviews'); @@ -568,14 +537,14 @@ export default class CalendarService { } if (foundEventType.onlyHeadsOrAboveForEventCreation) { - const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isHead || isAdmin); + const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isHead); if (!hasPermission) { throw new AccessDeniedException('Only admins and heads can edit this event!'); } } else { const hasPermission = - (await userHasPermission(submitter.userId, organization.organizationId, isHead || isAdmin)) || + (await userHasPermission(submitter.userId, organization.organizationId, isHead)) || submitter.userId === foundEvent.userCreatedId; if (!hasPermission) { @@ -718,7 +687,25 @@ export default class CalendarService { return new Date(initial.getTime() + weeks * 7 * 24 * 60 * 60 * 1000); }; - if (haveDifferentSlots(existingSlots, scheduleSlot)) { + const scheduleChanged = haveDifferentSlots(existingSlots, scheduleSlot); + const locationChanged = foundEvent.location !== location; + + let hasConflict = false; + let approverUserId: string | undefined; + + if (scheduleChanged || locationChanged) { + const { hasConflict: conflict, approverUserId: approver } = await checkEventConflicts( + scheduleSlot, + organization, + location, + eventId + ); + + hasConflict = conflict; + approverUserId = approver; + } + + if (scheduleChanged) { await tx.scheduleSlot.deleteMany({ where: { ScheduledEvents: { some: { eventId } } } }); @@ -743,6 +730,22 @@ export default class CalendarService { const updatedRequiredMembers = getPrismaQueryUserIds(await getUsers(requiredMemberIds)); const updatedOptionalMembers = getPrismaQueryUserIds(await getUsers(optionalMemberIds)); + let newStatus = status; + + // If schedule or location changed and event type requires confirmation, reset to UNCONFIRMED + if ((scheduleChanged || locationChanged) && foundEventType.requiresConfirmation) { + newStatus = Event_Status.UNCONFIRMED; + } else { + // If all required members are confirmed, set the status to SCHEDULED + const allRequiredMembersConfirmed = updatedRequiredMembers.every((member) => + foundEvent.confirmedMembers.map((user) => user.userId).includes(member.userId) + ); + + if (status === Event_Status.CONFIRMED && allRequiredMembersConfirmed) { + newStatus = Event_Status.SCHEDULED; + } + } + // Update the event with new data return await tx.event.update({ where: { eventId }, @@ -758,6 +761,7 @@ export default class CalendarService { teams: { set: teamIds.map((teamId) => ({ teamId })) }, + status: newStatus, shops: { set: shopIds.map((shopId) => ({ shopId })) }, @@ -767,6 +771,11 @@ export default class CalendarService { workPackages: { set: workPackageIds.map((workPackageId) => ({ workPackageId })) }, + // If schedule/location changed and there's a conflict, set approved=false and track who needs to approve + // Otherwise keep existing approval state + approved: scheduleChanged || locationChanged ? !hasConflict : foundEvent.approved, + approvedByUserId: + scheduleChanged || locationChanged ? (hasConflict ? approverUserId : null) : foundEvent.approvedByUserId, documentIds, location, zoomLink, @@ -801,10 +810,12 @@ export default class CalendarService { if (!event) throw new NotFoundException('Event', eventId); if (event.dateDeleted) throw new DeletedException('Event', eventId); - const hasPermission = await userHasPermission(submitter.userId, organization.organizationId, isAdmin || isHead); + const hasPermission = + (await userHasPermission(submitter.userId, organization.organizationId, isHead)) || + event.approvedByUserId === submitter.userId; if (!hasPermission) { - throw new AccessDeniedException('Only admins or heads can approve events!'); + throw new AccessDeniedException('Only admins or heads or the owner of the conflicting event can this approve event!'); } const approvedEvent = await prisma.event.update({ @@ -1296,7 +1307,8 @@ export default class CalendarService { questionDocument: boolean, documents: boolean, description: boolean, - onlyHeadsOrAbove: boolean + onlyHeadsOrAbove: boolean, + requiresConfirmation: boolean ): Promise { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('edit event type'); @@ -1355,7 +1367,8 @@ export default class CalendarService { questionDocument, documents, description, - onlyHeadsOrAboveForEventCreation: onlyHeadsOrAbove + onlyHeadsOrAboveForEventCreation: onlyHeadsOrAbove, + requiresConfirmation }, ...getEventTypeQueryArgs(organization.organizationId) }); diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index c9680309fb..08283fdf75 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -1,5 +1,7 @@ -import { Prisma } from '@prisma/client'; -import { User, Event } from 'shared'; +import { Prisma, EventType, Organization } from '@prisma/client'; +import { User, ScheduleSlotCreateArgs, Event } from 'shared'; +import { InvalidEventTypeConfigurationException } from './errors.utils'; +import prisma from '../prisma/prisma'; export function buildScheduledTimesOverlap(start?: Date, end?: Date): Prisma.ScheduleSlotListRelationFilter | undefined { if (!start && !end) return undefined; @@ -16,3 +18,189 @@ export const isUserOnEvent = (user: User, event: Event): boolean => { const optionalMembers = event.optionalMembers.map((user) => user.userId); return requiredMembers.includes(user.userId) || optionalMembers.includes(user.userId); }; + +/** + * Validates that an event's data matches its event type configuration. + * Throws an exception if required fields are missing or if fields are provided that the event type doesn't allow. + * + * @param eventType The event type to validate against + * @param eventData The event data to validate + * @throws InvalidEventTypeConfigurationException if validation fails + */ +export function validateEventTypeConfiguration( + eventType: EventType, + eventData: { + requiredMemberIds: string[]; + optionalMemberIds: string[]; + teamIds: string[]; + shopIds: string[]; + machineryIds: string[]; + workPackageIds: string[]; + documentIds: string[]; + scheduleSlot: ScheduleSlotCreateArgs[]; + location?: string; + zoomLink?: string; + questionDocument?: string; + description?: string; + } +): void { + // Check required fields + if (eventType.requiredMembers && eventData.requiredMemberIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one required member'); + } + if (eventType.location && !eventData.location) { + throw new InvalidEventTypeConfigurationException('a location'); + } + if (eventType.zoomLink && !eventData.zoomLink) { + throw new InvalidEventTypeConfigurationException('a zoom link'); + } + if (eventType.shop && eventData.shopIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one shop'); + } + if (eventType.machinery && eventData.machineryIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one machinery'); + } + if (eventType.workPackage && eventData.workPackageIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one work package'); + } + if (eventType.questionDocument && !eventData.questionDocument) { + throw new InvalidEventTypeConfigurationException('a question document'); + } + if (eventType.documents && eventData.documentIds.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one document'); + } + if (eventType.description && !eventData.description) { + throw new InvalidEventTypeConfigurationException('a description'); + } + if (eventType.initialDateScheduled && eventData.scheduleSlot.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one schedule slot'); + } + + // Check disallowed fields (inverse validation) + if (!eventType.requiredMembers && eventData.requiredMemberIds.length > 0) { + throw new InvalidEventTypeConfigurationException('Event type does not allow required members'); + } + if (!eventType.optionalMembers && eventData.optionalMemberIds.length > 0) { + throw new InvalidEventTypeConfigurationException('Event type does not allow optional members'); + } + if (!eventType.location && eventData.location) { + throw new InvalidEventTypeConfigurationException('Event type does not allow a location'); + } + if (!eventType.zoomLink && eventData.zoomLink) { + throw new InvalidEventTypeConfigurationException('Event type does not allow a zoom link'); + } + if (!eventType.shop && eventData.shopIds.length > 0) { + throw new InvalidEventTypeConfigurationException('Event type does not allow shops'); + } + if (!eventType.machinery && eventData.machineryIds.length > 0) { + throw new InvalidEventTypeConfigurationException('Event type does not allow machinery'); + } + if (!eventType.workPackage && eventData.workPackageIds.length > 0) { + throw new InvalidEventTypeConfigurationException('Event type does not allow work packages'); + } + if (!eventType.questionDocument && eventData.questionDocument) { + throw new InvalidEventTypeConfigurationException('Event type does not allow a question document'); + } + if (!eventType.documents && eventData.documentIds.length > 0) { + throw new InvalidEventTypeConfigurationException('Event type does not allow documents'); + } + if (!eventType.description && eventData.description) { + throw new InvalidEventTypeConfigurationException('Event type does not allow a description'); + } + if (!eventType.initialDateScheduled && eventData.scheduleSlot.length > 0) { + throw new InvalidEventTypeConfigurationException('Event type does not allow schedule slots'); + } +} + +/** + * Checks if there are any scheduling conflicts with existing events. + * A conflict occurs when events overlap in both time and location. + * + * @param eventId The event ID to exclude from conflict check (for edits) + * @param scheduleSlots The schedule slots to check + * @param location The location to check + * @param organization The organization + * @returns An object with hasConflict boolean and the user who should approve (if any) + */ +export async function checkEventConflicts( + scheduleSlots: ScheduleSlotCreateArgs[], + organization: Organization, + location?: string, + eventId?: string +): Promise<{ hasConflict: boolean; approverUserId?: string }> { + // No conflict if there's no location + if (!location) { + return { hasConflict: false }; + } + + // No conflict if there are no schedule slots + if (scheduleSlots.length === 0) { + return { hasConflict: false }; + } + + // Find all events in the same organization with the same location + const potentialConflicts = await prisma.event.findMany({ + where: { + eventId: eventId ? { not: eventId } : undefined, // Exclude current event if editing + location, + dateDeleted: null, + eventType: { + organizationId: organization.organizationId + } + }, + include: { + scheduledTimes: true + }, + orderBy: { + dateCreated: 'asc' // Earlier events have priority + } + }); + + // Check each schedule slot against existing events + for (const newSlot of scheduleSlots) { + for (const event of potentialConflicts) { + for (const existingSlot of event.scheduledTimes) { + // Check if there's a day overlap + const dayOverlap = newSlot.days.some((day) => existingSlot.days.includes(day)); + + if (!dayOverlap) continue; + + // Check if there's a date range overlap + const newStartDate = new Date(newSlot.initialDateScheduled); + const newEndDate = new Date(newStartDate.getTime() + (newSlot.recurrenceNumber ?? 0) * 7 * 24 * 60 * 60 * 1000); + const existingStartDate = new Date(existingSlot.initialDateScheduled); + const existingEndDate = new Date(existingSlot.endDate); + + const dateOverlap = newStartDate <= existingEndDate && newEndDate >= existingStartDate; + + if (!dateOverlap) continue; + + // If both are all-day events, they conflict + if (newSlot.allDay && existingSlot.allDay) { + return { hasConflict: true, approverUserId: event.userCreatedId }; + } + + // If one is all-day and the other isn't, they conflict + if (newSlot.allDay || existingSlot.allDay) { + return { hasConflict: true, approverUserId: event.userCreatedId }; + } + + // Check time overlap (both have specific times) + if (newSlot.startTime && newSlot.endTime && existingSlot.startTime && existingSlot.endTime) { + const newStart = new Date(newSlot.startTime).getTime(); + const newEnd = new Date(newSlot.endTime).getTime(); + const existingStart = new Date(existingSlot.startTime).getTime(); + const existingEnd = new Date(existingSlot.endTime).getTime(); + + const timeOverlap = newStart < existingEnd && newEnd > existingStart; + + if (timeOverlap) { + return { hasConflict: true, approverUserId: event.userCreatedId }; + } + } + } + } + } + + return { hasConflict: false }; +} diff --git a/src/backend/src/utils/validation.utils.ts b/src/backend/src/utils/validation.utils.ts index e20fd61a57..a8d090c06c 100644 --- a/src/backend/src/utils/validation.utils.ts +++ b/src/backend/src/utils/validation.utils.ts @@ -153,7 +153,7 @@ export const isMaterialStatus = (validationObject: ValidationChain): ValidationC ]); }; -export const isDesignReviewStatus = (validationObject: ValidationChain): ValidationChain => { +export const isEventStatus = (validationObject: ValidationChain): ValidationChain => { return validationObject .isString() .isIn([Event_Status.CONFIRMED, Event_Status.DONE, Event_Status.SCHEDULED, Event_Status.UNCONFIRMED]); diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index a820a89b1a..0f6df40c44 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,4 +1,4 @@ -import { Calendar, Organization, User } from '@prisma/client'; +import { Calendar, Event_Status, Organization, User } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; import { AccessDeniedAdminOnlyException, @@ -10,7 +10,7 @@ import { import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; -import { DayOfWeek, EventType, Machinery, ScheduleSlot, ScheduleSlotCreateArgs, Shop, Event } from 'shared'; +import { DayOfWeek, EventType, Machinery, ScheduleSlotCreateArgs, Shop, Event } from 'shared'; describe('Calendar Tests', () => { let orgId: string; @@ -59,21 +59,22 @@ describe('Calendar Tests', () => { 'Team Meeting', [calendar.calendarId], organization, - false, + true, false, true, true, true, + true, + true, + true, + true, + true, false, - false, - false, - false, - false, - false, - false, - false, - false, - false + true, + true, + true, + true, + true ); }); @@ -257,6 +258,7 @@ describe('Calendar Tests', () => { true, false, true, + false, false ) ).rejects.toThrow(new AccessDeniedAdminOnlyException('create event type')); @@ -282,6 +284,7 @@ describe('Calendar Tests', () => { false, false, true, + false, false ); @@ -628,7 +631,8 @@ describe('Calendar Tests', () => { false, false, true, - true + true, + false ); }); @@ -655,6 +659,7 @@ describe('Calendar Tests', () => { false, false, false, + false, false ) ).rejects.toThrow(new AccessDeniedAdminOnlyException('edit event type')); @@ -683,6 +688,7 @@ describe('Calendar Tests', () => { true, true, true, + true, true ) ).rejects.toThrow(new NotFoundException('Calendar', invalidCalendarId)); @@ -729,6 +735,7 @@ describe('Calendar Tests', () => { false, false, false, + false, false ) ).rejects.toThrow(new InvalidOrganizationException('Calendar')); @@ -757,7 +764,8 @@ describe('Calendar Tests', () => { false, false, false, - true + true, + false ) ).rejects.toThrow(new NotFoundException('Event Type', nonExistentId)); }); @@ -783,6 +791,7 @@ describe('Calendar Tests', () => { false, true, false, + false, false ); @@ -892,7 +901,7 @@ describe('Calendar Tests', () => { expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); - expect(result.approved).toBe(false); + expect(result.approved).toBe(true); expect(result.approvedBy).toBe(undefined); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); @@ -961,44 +970,66 @@ describe('Calendar Tests', () => { }); it('succeeds with minimal inputs', async () => { - const scheduleSlots = [] as ScheduleSlot[]; + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; const result = await CalendarService.createEvent( adminUser, 'Minimal Event', eventType.eventTypeId, organization, - [adminUser.userId], [member.userId], + [adminUser.userId], [], + [shop.shopId], + [machinery.machineryId], [], - [], - [], - [], - scheduleSlots + [document], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ); expect(result.title).toBe('Minimal Event'); expect(result.eventTypeId).toBe(eventType.eventTypeId); expect(result.requiredMembers).toHaveLength(1); - expect(result.requiredMembers[0].userId).toBe(adminUser.userId); + expect(result.requiredMembers[0].userId).toBe(member.userId); expect(result.optionalMembers).toHaveLength(1); - expect(result.optionalMembers[0].userId).toBe(member.userId); - expect(result.shops).toHaveLength(0); - expect(result.machinery).toHaveLength(0); + expect(result.optionalMembers[0].userId).toBe(adminUser.userId); + expect(result.shops).toHaveLength(1); + expect(result.machinery).toHaveLength(1); expect(result.workPackages).toHaveLength(0); - expect(result.documentIds).toHaveLength(0); - expect(result.scheduledTimes).toHaveLength(0); - expect(result.approved).toBe(false); + expect(result.documentIds).toHaveLength(1); + expect(result.scheduledTimes).toHaveLength(1); + expect(result.approved).toBe(true); expect(result.approvedBy).toBeUndefined(); - expect(result.questionDocument).toBeUndefined(); - expect(result.location).toBeUndefined(); - expect(result.zoomLink).toBeUndefined(); - expect(result.description).toBeUndefined(); + expect(result.questionDocument).toBe('https://example.com/questions.pdf'); + expect(result.location).toBe('Conference Room A'); + expect(result.zoomLink).toBe('https://zoom.us/j/123456789'); + expect(result.description).toBe('Weekly team synchronization meeting'); }); it('fails if memberIds are invalid', async () => { - const scheduleSlots = [] as ScheduleSlot[]; + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; await expect( CalendarService.createEvent( @@ -1009,17 +1040,30 @@ describe('Calendar Tests', () => { ['non-existent-user-id'], [adminUser.userId], [], - [], - [], - [], - [], - scheduleSlots + [shop.shopId], + [machinery.machineryId], + [], + [document], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Invalid' ) ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); }); it('fails if memberIds belong to a different organization', async () => { - const scheduleSlots = [] as ScheduleSlot[]; + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; await expect( CalendarService.createEvent( @@ -1030,17 +1074,30 @@ describe('Calendar Tests', () => { [otherOrgUser.userId], [adminUser.userId], [], - [], - [], - [], - [], - scheduleSlots + [shop.shopId], + [machinery.machineryId], + [], + [document], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Invalid' ) ).rejects.toThrow(new NotFoundException('User', otherOrgUser.userId)); }); - it('fails if shopIds are invalid', async () => { - const scheduleSlots = [] as ScheduleSlot[]; + it('fails if shopIds are inputted', async () => { + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; await expect( CalendarService.createEvent( @@ -1052,16 +1109,29 @@ describe('Calendar Tests', () => { [member.userId], [], ['non-existent-shop-id'], - [], - [], - [], - scheduleSlots + [machinery.machineryId], + [], + [document], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Invalid' ) ).rejects.toThrow(new NotFoundException('Shop', 'non-existent-shop-id')); }); it('fails if shopIds belong to a different organization', async () => { - const scheduleSlots = [] as ScheduleSlot[]; + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; await expect( CalendarService.createEvent( @@ -1073,37 +1143,29 @@ describe('Calendar Tests', () => { [member.userId], [], [otherOrgShop.shopId], - [], - [], - [], - scheduleSlots + [machinery.machineryId], + [], + [document], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Invalid' ) ).rejects.toThrow(new NotFoundException('Shop', otherOrgShop.shopId)); }); - it('fails if machineryIds are invalid', async () => { - const scheduleSlots = [] as ScheduleSlot[]; - - await expect( - CalendarService.createEvent( - adminUser, - 'Invalid Machinery', - eventType.eventTypeId, - organization, - [adminUser.userId], - [member.userId], - [], - [], - ['non-existent-machinery-id'], - [], - [], - scheduleSlots - ) - ).rejects.toThrow(new NotFoundException('Machinery', 'non-existent-machinery-id')); - }); - it('fails if machineryIds belong to a different organization', async () => { - const scheduleSlots = [] as ScheduleSlot[]; + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; await expect( CalendarService.createEvent( @@ -1114,36 +1176,19 @@ describe('Calendar Tests', () => { [adminUser.userId], [member.userId], [], - [], + [shop.shopId], [otherOrgMachinery.machineryId], [], - [], - scheduleSlots + [document], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Invalid' ) ).rejects.toThrow(new NotFoundException('Machinery', otherOrgMachinery.machineryId)); }); - it('fails if workPackageIds are invalid', async () => { - const scheduleSlots = [] as ScheduleSlot[]; - - await expect( - CalendarService.createEvent( - adminUser, - 'Invalid Work Packages', - eventType.eventTypeId, - organization, - [adminUser.userId], - [member.userId], - [], - [], - [], - ['non-existent-work-package-id'], - [], - scheduleSlots - ) - ).rejects.toThrow(new NotFoundException('Work Package', 'non-existent-work-package-id')); - }); - it('fails if shopIds are deleted', async () => { const deletedShop = await CalendarService.createShop(adminUser, 'Deleted Shop', 'Deleted shop', organization); await prisma.shop.update({ @@ -1151,7 +1196,16 @@ describe('Calendar Tests', () => { data: { dateDeleted: new Date() } }); - const scheduleSlots = [] as ScheduleSlot[]; + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; await expect( CalendarService.createEvent( @@ -1163,10 +1217,14 @@ describe('Calendar Tests', () => { [member.userId], [], [deletedShop.shopId], - [], - [], - [], - scheduleSlots + [machinery.machineryId], + [], + [document], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Invalid' ) ).rejects.toThrow(new NotFoundException('Shop', deletedShop.shopId)); }); @@ -1185,7 +1243,16 @@ describe('Calendar Tests', () => { data: { dateDeleted: new Date() } }); - const scheduleSlots = [] as ScheduleSlot[]; + const scheduleSlots = [ + { + days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + startTime: new Date('2025-10-13T09:00:00Z'), + endTime: new Date('2025-10-13T10:00:00Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-13'), + allDay: false + } + ]; await expect( CalendarService.createEvent( @@ -1196,11 +1263,15 @@ describe('Calendar Tests', () => { [adminUser.userId], [member.userId], [], - [], + [shop.shopId], [deletedMachinery.machineryId], [], - [], - scheduleSlots + [document], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Invalid' ) ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); }); @@ -1251,9 +1322,9 @@ describe('Calendar Tests', () => { [adminUser.userId], [], [shop.shopId], + [machinery.machineryId], [], - [], - [], + [document], scheduleSlots, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1312,9 +1383,9 @@ describe('Calendar Tests', () => { [adminUser.userId], [], [shop.shopId], + [machinery.machineryId], [], - [], - [], + [document], scheduleSlots, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1343,9 +1414,9 @@ describe('Calendar Tests', () => { [adminUser.userId], [], [shop.shopId], + [machinery.machineryId], [], - [], - [], + [document], scheduleSlots2, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1405,9 +1476,9 @@ describe('Calendar Tests', () => { [member2.userId], [], [shop.shopId], + [machinery.machineryId], [], - [], - [], + [document], scheduleSlots, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1436,9 +1507,9 @@ describe('Calendar Tests', () => { [member2.userId], [], [shop.shopId], + [machinery.machineryId], [], - [], - [], + [document], scheduleSlots2, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1621,8 +1692,12 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - ['doc1'], - scheduleSlots + ['document'], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ); }); @@ -1635,6 +1710,7 @@ describe('Calendar Tests', () => { organization, [adminUser.userId], [member.userId], + Event_Status.UNCONFIRMED, [], [], [], @@ -1659,6 +1735,7 @@ describe('Calendar Tests', () => { organization, [adminUser.userId], [member.userId], + Event_Status.UNCONFIRMED, [], [], [], @@ -1678,12 +1755,17 @@ describe('Calendar Tests', () => { organization, ['non-existent-user-id'], [adminUser.userId], + Event_Status.UNCONFIRMED, [], - [], - [], - [], - [], - scheduleSlots + [shop.shopId], + [machinery.machineryId], + [], + ['document'], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ) ).rejects.toThrow(new NotFoundException('User', 'non-existent-user-id')); }); @@ -1697,12 +1779,17 @@ describe('Calendar Tests', () => { organization, [adminUser.userId], [member.userId], + Event_Status.UNCONFIRMED, [], ['non-existent-shop-id'], - [], - [], - [], - scheduleSlots + [machinery.machineryId], + [], + ['document'], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ) ).rejects.toThrow(new NotFoundException('Shop', 'non-existent-shop-id')); }); @@ -1722,12 +1809,17 @@ describe('Calendar Tests', () => { organization, [adminUser.userId], [member.userId], + Event_Status.UNCONFIRMED, [], [deletedShop.shopId], - [], - [], - [], - scheduleSlots + [machinery.machineryId], + [], + ['document'], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ) ).rejects.toThrow(new NotFoundException('Shop', deletedShop.shopId)); }); @@ -1741,12 +1833,17 @@ describe('Calendar Tests', () => { organization, [adminUser.userId], [member.userId], + Event_Status.UNCONFIRMED, [], - [], + [shop.shopId], ['non-existent-machinery-id'], [], - [], - scheduleSlots + ['document'], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ) ).rejects.toThrow(new NotFoundException('Machinery', 'non-existent-machinery-id')); }); @@ -1772,35 +1869,21 @@ describe('Calendar Tests', () => { organization, [adminUser.userId], [member.userId], + Event_Status.UNCONFIRMED, [], - [], + [shop.shopId], [deletedMachinery.machineryId], [], - [], - scheduleSlots + ['document'], + scheduleSlots, + 'https://example.com/questions.pdf', + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'Weekly team synchronization meeting' ) ).rejects.toThrow(new NotFoundException('Machinery', deletedMachinery.machineryId)); }); - it('fails if workPackageIds are invalid', async () => { - await expect( - CalendarService.editEvent( - adminUser, - event.eventId, - 'Updated Title', - organization, - [adminUser.userId], - [member.userId], - [], - [], - [], - ['non-existent-wp-id'], - [], - scheduleSlots - ) - ).rejects.toThrow(new NotFoundException('Work Package', 'non-existent-wp-id')); - }); - it('succeeds for admin and updates event', async () => { const newMember = await createTestUser(alfred, orgId); const newScheduleSlots: ScheduleSlotCreateArgs[] = [ @@ -1821,9 +1904,10 @@ describe('Calendar Tests', () => { organization, [newMember.userId], [adminUser.userId], + Event_Status.UNCONFIRMED, [], - [], - [], + [shop.shopId], + [machinery.machineryId], [], ['doc2', 'doc3'], newScheduleSlots, @@ -1840,42 +1924,13 @@ describe('Calendar Tests', () => { expect(result.optionalMembers).toHaveLength(1); expect(result.optionalMembers[0].userId).toBe(adminUser.userId); expect(result.documentIds).toEqual(['doc2', 'doc3']); - expect(result.approved).toBe(false); + expect(result.approved).toBe(true); expect(result.approvedBy).toBe(undefined); expect(result.questionDocument).toBe('https://updated.com/questions.pdf'); expect(result.location).toBe('Updated Location'); expect(result.zoomLink).toBe('https://zoom.us/updated'); expect(result.description).toBe('Updated description'); }); - - it('succeeds and updates with minimal fields', async () => { - const result = await CalendarService.editEvent( - adminUser, - event.eventId, - 'Minimal Update', - organization, - [adminUser.userId], - [member.userId], - [], - [], - [], - [], - [], - [] - ); - - expect(result.eventId).toBe(event.eventId); - expect(result.title).toBe('Minimal Update'); - expect(result.requiredMembers).toHaveLength(1); - expect(result.requiredMembers[0].userId).toBe(adminUser.userId); - expect(result.optionalMembers).toHaveLength(1); - expect(result.optionalMembers[0].userId).toBe(member.userId); - expect(result.shops).toHaveLength(0); - expect(result.machinery).toHaveLength(0); - expect(result.workPackages).toHaveLength(0); - expect(result.documentIds).toHaveLength(0); - expect(result.approved).toBe(false); - }); }); describe('Delete Event', () => { @@ -1903,11 +1958,15 @@ describe('Calendar Tests', () => { [adminUser.userId], [member.userId], [], + [shop.shopId], + [machinery.machineryId], [], - [], - [], - [], - scheduleSlots + ['doc2', 'doc3'], + scheduleSlots, + 'https://updated.com/questions.pdf', + 'Updated Location', + 'https://zoom.us/updated', + 'Updated description' ); }); @@ -1971,7 +2030,8 @@ describe('Calendar Tests', () => { false, false, false, - true + true, + false ); }); @@ -2029,7 +2089,8 @@ describe('Calendar Tests', () => { false, false, false, - true + true, + false ); await expect(CalendarService.deleteEventType(adminUser, otherOrgEventType.eventTypeId, organization)).rejects.toThrow( From 121dc95b12b9106f8bdc5ddfd76bc08fec30de12 Mon Sep 17 00:00:00 2001 From: sam gunss Date: Sun, 9 Nov 2025 21:36:00 -0500 Subject: [PATCH 196/477] minimized view button fix --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 63027a1253..2b1c1435e1 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -134,36 +134,35 @@ const NewCalendarPage = () => { - + {/* New Event Button (does not do anything yet) */} - {isExtraSmallView ? ( - - {}}> - - - - ) : ( - - )} - {unconfirmedDRSDropdown} + + {unconfirmedDRSDropdown} + From f00fae55f956050bed790a68fc3230ca55bec983 Mon Sep 17 00:00:00 2001 From: sam gunss Date: Sun, 9 Nov 2025 21:48:10 -0500 Subject: [PATCH 197/477] prettier checks --- .../src/pages/NewCalendarPage/NewCalendarPage.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 2b1c1435e1..d094e5fb7c 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -134,7 +134,7 @@ const NewCalendarPage = () => { - + {/* New Event Button (does not do anything yet) */} - - - - {unconfirmedDRSDropdown} From 7e11ae620b88fed5b36219ca08d76e6fdc112c41 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 11 Nov 2025 19:47:45 -0500 Subject: [PATCH 207/477] #3569 cut down query args --- .../src/prisma-query-args/event.query-args.ts | 36 ++++++++++++++----- .../src/transformers/calendar.transformer.ts | 10 +++--- src/shared/src/types/calendar-types.ts | 32 +++++++++++++---- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/src/backend/src/prisma-query-args/event.query-args.ts b/src/backend/src/prisma-query-args/event.query-args.ts index 9604d98684..5a3384e656 100644 --- a/src/backend/src/prisma-query-args/event.query-args.ts +++ b/src/backend/src/prisma-query-args/event.query-args.ts @@ -1,9 +1,5 @@ import { Prisma } from '@prisma/client'; import { getUserQueryArgs, getUserWithSettingsQueryArgs } from './user.query-args'; -import { getShopQueryArgs } from './shop.query-args'; -import { getMachineryQueryArgs } from './machinery.query-args'; -import { getWorkPackagePreviewQueryArgs } from './work-packages.query-args'; -import { getTeamPreviewQueryArgs } from './teams.query-args'; export type EventQueryArgs = ReturnType; @@ -15,10 +11,34 @@ export const getEventQueryArgs = (organizationId: string) => optionalMembers: getUserQueryArgs(organizationId), confirmedMembers: getUserWithSettingsQueryArgs(organizationId), deniedMembers: getUserQueryArgs(organizationId), - teams: getTeamPreviewQueryArgs(organizationId), - shops: getShopQueryArgs(organizationId), - machinery: getMachineryQueryArgs(organizationId), - workPackages: getWorkPackagePreviewQueryArgs(), + teams: { + select: { + teamName: true, + teamId: true + } + }, + shops: { + select: { + name: true, + shopId: true + } + }, + machinery: { + select: { + name: true, + machineryId: true + } + }, + workPackages: { + select: { + wbsElement: { + select: { + name: true + } + }, + workPackageId: true + } + }, approvalRequiredBy: getUserQueryArgs(organizationId), scheduledTimes: true } diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 235287d90d..b5e27875f3 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -6,8 +6,6 @@ import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { CalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; import { EventQueryArgs } from '../prisma-query-args/event.query-args'; import { ShopQueryArgs } from '../prisma-query-args/shop.query-args'; -import { workPackagePreviewTransformer } from './work-packages.transformer'; -import { teamPreviewTransformer } from './teams.transformer'; export const shopTransformer = (shop: Prisma.ShopGetPayload): Shop => { return { @@ -100,10 +98,10 @@ export const eventTransformer = (event: Prisma.EventGetPayload): optionalMembers: event.optionalMembers.map(userTransformer), confirmedMembers: event.confirmedMembers.map(userWithScheduleSettingsTransformer), deniedMembers: event.deniedMembers.map(userTransformer), - teams: event.teams.map(teamPreviewTransformer), - shops: event.shops.map(shopTransformer), - machinery: event.machinery.map(machineryTransformer), - workPackages: event.workPackages.map(workPackagePreviewTransformer), + teams: event.teams, + shops: event.shops, + machinery: event.machinery, + workPackages: event.workPackages, documentIds: event.documentIds, scheduledTimes: event.scheduledTimes.map(scheduleTimesTransformer), approved: event.approved, diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index d9c458a769..cd62124251 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -1,6 +1,26 @@ -import { WorkPackagePreview } from './project-types'; import { User, UserWithScheduleSettings } from './user-types'; -import { TeamPreview } from './team-types'; + +export interface ShopPreview { + shopId: string; + name: string; +} + +export interface MachineryPreview { + machineryId: string; + name: string; +} + +export interface TeamCalendarPreview { + teamId: string; + teamName: string; +} + +export interface WorkPackageCalendarPreview { + workPackageId: string; + wbsElement: { + name: string; + }; +} export enum EventStatus { UNCONFIRMED = 'UNCONFIRMED', @@ -118,12 +138,12 @@ export interface Event { optionalMembers: User[]; confirmedMembers: UserWithScheduleSettings[]; deniedMembers: User[]; - teams: TeamPreview[]; + teams: TeamCalendarPreview[]; location?: string; zoomLink?: string; - shops: Shop[]; - machinery: Machinery[]; - workPackages: WorkPackagePreview[]; + shops: ShopPreview[]; + machinery: MachineryPreview[]; + workPackages: WorkPackageCalendarPreview[]; documentIds: string[]; questionDocument?: string; description?: string; From efbb302dab03527f7483171392e8e81f9f9f840c Mon Sep 17 00:00:00 2001 From: Saul M Date: Wed, 12 Nov 2025 16:34:23 -0500 Subject: [PATCH 208/477] #3676 Added suggestions --- src/frontend/src/hooks/calendar.hooks.ts | 13 +++++++------ .../ScheduleConfig/Shop/DeleteShopModal.tsx | 4 ++-- src/frontend/src/utils/urls.ts | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index ebdbeb4b92..63108f0d27 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -12,6 +12,7 @@ import { } from '../apis/calendar.api'; export const MACHINERY_KEY = ['machinery'] as const; +export const SHOP_KEY = ['shop'] as const; export const useAllShops = () => useQuery(['shops'], async () => { @@ -28,7 +29,7 @@ export const useCreateShop = () => { }, { onSuccess: () => { - qc.invalidateQueries(['shops']); + qc.invalidateQueries(SHOP_KEY); } } ); @@ -43,7 +44,7 @@ export const useEditShop = (shopId: string) => { }, { onSuccess: () => { - qc.invalidateQueries(['shops']); + qc.invalidateQueries(SHOP_KEY); } } ); @@ -105,14 +106,14 @@ export const useAddMachineryToShop = (machineryId: string) => { export const useDeleteShop = () => { const qc = useQueryClient(); - return useMutation<{ name: string }, Error, string>( - async (shopID: string) => { - const { data } = await postDeleteShop(shopID); + return useMutation<{ shopId: string }, Error, string>( + async (shopId: string) => { + const { data } = await postDeleteShop(shopId); return data; }, { onSuccess: () => { - qc.invalidateQueries(['shops']); + qc.invalidateQueries(SHOP_KEY); } } ); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx index 1a6bd99244..8a420a22a0 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx @@ -8,7 +8,7 @@ export interface DeleteShopModalProps { shop: Shop; } -const DeleteCategoryModal = ({ onClose, shop }: DeleteShopModalProps) => { +const DeleteShopModal = ({ onClose, shop }: DeleteShopModalProps) => { const { mutateAsync } = useDeleteShop(); return ( @@ -31,4 +31,4 @@ const DeleteCategoryModal = ({ onClose, shop }: DeleteShopModalProps) => { ); }; -export default DeleteCategoryModal; +export default DeleteShopModal; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 9f8503ba27..4aecaa8d08 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -444,7 +444,7 @@ const calendarCreateMachinery = () => `${calendar()}/machinery/create`; const calendarEditMachinery = (machineryId: string) => `${calendar()}/machinery/${machineryId}/edit`; const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; const calendarEditShop = (shopId: string) => `${calendar()}/shop/${shopId}/edit`; -const calendarDeleteShop = (id: string) => `${calendar()}/shop/${id}/delete`; +const calendarDeleteShop = (shopId: string) => `${calendar()}/shop/${shopId}/delete`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; From 4ba0c8a2dd9bc6ca06107c935320a7afffcbe994 Mon Sep 17 00:00:00 2001 From: Santiordon Date: Wed, 12 Nov 2025 16:55:33 -0500 Subject: [PATCH 209/477] Connect Filter Events --- .editorconfig | 10 ++++++++++ src/frontend/src/apis/calendar.api.ts | 10 +++++++++- src/frontend/src/hooks/calendar.hooks.ts | 20 ++++++++++++++++++-- src/frontend/src/utils/urls.ts | 2 ++ 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..1ed453a371 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true + +[*.{js,json,yml}] +charset = utf-8 +indent_style = space +indent_size = 2 diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 84919e0437..153e11a52a 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,6 +1,8 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; -import { Shop } from 'shared'; +import { Shop, Event } from 'shared'; + +import { FilterArgs } from 'shared'; export const getAllShops = () => { return axios.get(apiUrls.calendarShops(), { @@ -13,3 +15,9 @@ export const postCreateShop = (payload: { name: string; description: string }) = transformResponse: (data) => JSON.parse(data) as Shop }); }; + +export const postFilterEvents = (payload: FilterArgs) => { + return axios.post(apiUrls.calendarFilterEvents(), payload, { + transformResponse: (data) => JSON.parse(data) as Event[] + }); +}; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 49a28aee38..571084c83c 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,8 +1,9 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop } from 'shared'; -import { getAllShops, postCreateShop } from '../apis/calendar.api'; +import { Shop, FilterArgs, Event } from 'shared'; +import { getAllShops, postCreateShop, postFilterEvents } from '../apis/calendar.api'; export const SHOPS_KEY = ['shops'] as const; +export const FILTER_EVENTS_KEY = ['filter_events'] as const; export const useAllShops = () => useQuery(SHOPS_KEY, async () => { @@ -24,3 +25,18 @@ export const useCreateShop = () => { } ); }; + +export const useFilterEvents = () => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + const { data } = await postFilterEvents(payload); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries(FILTER_EVENTS_KEY); + } + } + ); +} \ No newline at end of file diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 2ac1ba262a..d8eb71d6e9 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -439,6 +439,7 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; const calendarCreateShop = () => `${calendar()}/shop/create`; +const calendarFilterEvents = () => `${API_URL}/events/filter`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -743,6 +744,7 @@ export const apiUrls = { calendarShops, calendarCreateShop, + calendarFilterEvents, version }; From 35c17b10b4d6fffc7a54d95bc4b95ab50092fd1d Mon Sep 17 00:00:00 2001 From: Saul M Date: Wed, 12 Nov 2025 20:44:33 -0500 Subject: [PATCH 210/477] #3676 Added more suggestions --- src/frontend/src/hooks/calendar.hooks.ts | 4 ++-- .../AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 63108f0d27..30247c6f79 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -12,10 +12,10 @@ import { } from '../apis/calendar.api'; export const MACHINERY_KEY = ['machinery'] as const; -export const SHOP_KEY = ['shop'] as const; +export const SHOP_KEY = ['shop', 'shops'] as const; export const useAllShops = () => - useQuery(['shops'], async () => { + useQuery(SHOP_KEY, async () => { const res = await getAllShops(); return res.data; }); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx index 8a420a22a0..39e6fb6140 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx @@ -15,7 +15,7 @@ const DeleteShopModal = ({ onClose, shop }: DeleteShopModalProps) => { { From cd38898297bc0b4a04803ff0ae4730799085d602 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Thu, 13 Nov 2025 15:14:20 -0500 Subject: [PATCH 211/477] #3569 add delete event back in route file --- src/backend/src/routes/calendar.routes.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 5742f27731..f2a1301c91 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -144,7 +144,14 @@ calendarRouter.post( CalendarController.markUserConfirmed ); -calendarRouter.post('/:eventId/set-status', isEventStatus(body('status')), validateInputs, CalendarController.setStatus); +calendarRouter.post( + '/event/:eventId/set-status', + isEventStatus(body('status')), + validateInputs, + CalendarController.setStatus +); + +calendarRouter.post('/event/:eventId/delete', CalendarController.deleteEvent); calendarRouter.post('/machinery/create', nonEmptyString(body('name')), validateInputs, CalendarController.createMachinery); From f28c8816f9642945838ae355938b3a0ee19346d1 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Fri, 14 Nov 2025 14:32:51 -0500 Subject: [PATCH 212/477] #3677 Added delete machinery-shop modal --- src/frontend/src/hooks/calendar.hooks.ts | 19 ++++++ .../AdminToolsScheduleConfig.tsx | 61 ++++++++++++++++++- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 8c787564ed..5aa719f82e 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -101,3 +101,22 @@ export const useAddMachineryToShop = (machineryId: string) => { } ); }; + +export const useDeleteShopMachinery = () => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + return await postAddMachineryToShop({ + machineryId: payload.machineryId, + shopId: payload.shopId, + quantity: 0, + originalShopId: payload.shopId + }); + }, + { + onSuccess: () => { + qc.invalidateQueries(MACHINERY_KEY); + } + } + ); +}; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 93c9488037..3c24a5b58c 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -4,12 +4,20 @@ import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; import { IconButton, Tooltip } from '@mui/material'; -import { useAllShops, useCreateShop, useEditShop, useAllMachines } from '../../../hooks/calendar.hooks'; +import { + useAllShops, + useCreateShop, + useEditShop, + useAllMachines, + useDeleteShopMachinery +} from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; +import NERDeleteModal from '../../../components/NERDeleteModal'; +import { useToast } from '../../../hooks/toasts.hooks'; const AdminToolsScheduleConfig: React.FC = () => { const { data: shops, isLoading: shopsLoading, isError: shopsError, error: shopsErrorMsg } = useAllShops(); @@ -18,6 +26,32 @@ const AdminToolsScheduleConfig: React.FC = () => { const [editingShopId, setEditingShopId] = useState(); const editShopMutation = useEditShop(editingShopId ?? ''); + const [shopMachineryToDelete, setShopMachineryToDelete] = useState<{ + machineryId: string; + shopId: string; + machineName: string; + shopName: string; + } | null>(null); + const { mutateAsync: deleteShopMachinery } = useDeleteShopMachinery(); + const toast = useToast(); + + const handleDeleteShopMachinery = async () => { + if (!shopMachineryToDelete) return; + setShopMachineryToDelete(null); + try { + await deleteShopMachinery({ + machineryId: shopMachineryToDelete.machineryId, + shopId: shopMachineryToDelete.shopId + }); + toast.success('Shop-machinery relationship deleted successfully'); + } catch (e: unknown) { + if (e instanceof Error) { + toast.error(e.message, 3000); + } else { + toast.error('Failed to delete shop-machinery relationship', 3000); + } + } + }; const [openCreate, setOpenCreate] = useState(false); const [openCreateMachinery, setOpenCreateMachinery] = useState(false); @@ -187,9 +221,21 @@ const AdminToolsScheduleConfig: React.FC = () => {
- + - + + setShopMachineryToDelete({ + machineryId: machine.machineryId, + shopId: shopMachinery.shop.shopId, + machineName: machine.name, + shopName: shopMachinery.shop.name + }) + } + > @@ -262,6 +308,15 @@ const AdminToolsScheduleConfig: React.FC = () => { setEditingShopId(undefined); }} /> + + {/* Delete Shop-Machinery Relationship Modal */} + setShopMachineryToDelete(null)} + formId="delete-shop-machinery-form" + dataType={`machinery-shop relationship between ${shopMachineryToDelete?.shopName || 'shop'} and ${shopMachineryToDelete?.machineName || 'machine'}`} + onFormSubmit={handleDeleteShopMachinery} + /> ); }; From 79a4aec62c9764e685f0785937bc0b9f3ff1a41e Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Fri, 14 Nov 2025 15:24:34 -0500 Subject: [PATCH 213/477] #3677 Added delete machinery itself, instead of shop-machinery --- src/frontend/src/apis/calendar.api.ts | 11 ++++ src/frontend/src/hooks/calendar.hooks.ts | 14 ++--- .../AdminToolsScheduleConfig.tsx | 51 +++++++------------ src/frontend/src/utils/urls.ts | 2 + 4 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index a953cfb1b5..954b610cee 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -43,6 +43,17 @@ export const postEditMachinery = async (payload: { machineryId: string; name: st return data; }; +export const postDeleteMachinery = async (machineryId: string) => { + const { data } = await axios.post( + apiUrls.calendarDeleteMachinery(machineryId), + {}, + { + transformResponse: (data) => JSON.parse(data) as Machinery + } + ); + return data; +}; + export const postAddMachineryToShop = async (payload: { machineryId: string; shopId: string; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 5aa719f82e..204263af36 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -6,6 +6,7 @@ import { getAllMachinery, postCreateMachinery, postEditMachinery, + postDeleteMachinery, postAddMachineryToShop, editShop } from '../apis/calendar.api'; @@ -102,16 +103,11 @@ export const useAddMachineryToShop = (machineryId: string) => { ); }; -export const useDeleteShopMachinery = () => { +export const useDeleteMachinery = () => { const qc = useQueryClient(); - return useMutation( - async (payload) => { - return await postAddMachineryToShop({ - machineryId: payload.machineryId, - shopId: payload.shopId, - quantity: 0, - originalShopId: payload.shopId - }); + return useMutation( + async (machineryId: string) => { + return await postDeleteMachinery(machineryId); }, { onSuccess: () => { diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 3c24a5b58c..bae99c8e48 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -4,13 +4,7 @@ import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; import { IconButton, Tooltip } from '@mui/material'; -import { - useAllShops, - useCreateShop, - useEditShop, - useAllMachines, - useDeleteShopMachinery -} from '../../../hooks/calendar.hooks'; +import { useAllShops, useCreateShop, useEditShop, useAllMachines, useDeleteMachinery } from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; @@ -26,29 +20,24 @@ const AdminToolsScheduleConfig: React.FC = () => { const [editingShopId, setEditingShopId] = useState(); const editShopMutation = useEditShop(editingShopId ?? ''); - const [shopMachineryToDelete, setShopMachineryToDelete] = useState<{ + const [machineryToDelete, setMachineryToDelete] = useState<{ machineryId: string; - shopId: string; machineName: string; - shopName: string; } | null>(null); - const { mutateAsync: deleteShopMachinery } = useDeleteShopMachinery(); + const { mutateAsync: deleteMachinery } = useDeleteMachinery(); const toast = useToast(); - const handleDeleteShopMachinery = async () => { - if (!shopMachineryToDelete) return; - setShopMachineryToDelete(null); + const handleDeleteMachinery = async () => { + if (!machineryToDelete) return; + setMachineryToDelete(null); try { - await deleteShopMachinery({ - machineryId: shopMachineryToDelete.machineryId, - shopId: shopMachineryToDelete.shopId - }); - toast.success('Shop-machinery relationship deleted successfully'); + await deleteMachinery(machineryToDelete.machineryId); + toast.success('Machinery deleted successfully'); } catch (e: unknown) { if (e instanceof Error) { toast.error(e.message, 3000); } else { - toast.error('Failed to delete shop-machinery relationship', 3000); + toast.error('Failed to delete machinery', 3000); } } }; @@ -221,18 +210,16 @@ const AdminToolsScheduleConfig: React.FC = () => { - + - setShopMachineryToDelete({ + setMachineryToDelete({ machineryId: machine.machineryId, - shopId: shopMachinery.shop.shopId, - machineName: machine.name, - shopName: shopMachinery.shop.name + machineName: machine.name }) } > @@ -309,13 +296,13 @@ const AdminToolsScheduleConfig: React.FC = () => { }} /> - {/* Delete Shop-Machinery Relationship Modal */} + {/* Delete Machinery Modal */} setShopMachineryToDelete(null)} - formId="delete-shop-machinery-form" - dataType={`machinery-shop relationship between ${shopMachineryToDelete?.shopName || 'shop'} and ${shopMachineryToDelete?.machineName || 'machine'}`} - onFormSubmit={handleDeleteShopMachinery} + open={!!machineryToDelete} + onHide={() => setMachineryToDelete(null)} + formId="delete-machinery-form" + dataType={`machine ${machineryToDelete?.machineName || ''}`} + onFormSubmit={handleDeleteMachinery} /> ); diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 2ad0e92847..6737b17845 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -442,6 +442,7 @@ const calendarCreateShop = () => `${calendar()}/shop/create`; const calendarMachinery = () => `${calendar()}/machinery`; const calendarCreateMachinery = () => `${calendar()}/machinery/create`; const calendarEditMachinery = (machineryId: string) => `${calendar()}/machinery/${machineryId}/edit`; +const calendarDeleteMachinery = (machineryId: string) => `${calendar()}/machinery/${machineryId}/delete`; const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; const calendarEditShop = (shopId: string) => `${calendar()}/shop/${shopId}/edit`; @@ -751,6 +752,7 @@ export const apiUrls = { calendarMachinery, calendarCreateMachinery, calendarEditMachinery, + calendarDeleteMachinery, calendarAddMachineryToShop, calendarEditShop, From 91f9f0fd6ac3898bde26a51ae2e331d1401d5723 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Fri, 14 Nov 2025 15:46:03 -0500 Subject: [PATCH 214/477] #3677 trying to run commit see if it fixes weird test bug? --- .../AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index bae99c8e48..6e4f6bc745 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -296,7 +296,7 @@ const AdminToolsScheduleConfig: React.FC = () => { }} /> - {/* Delete Machinery Modal */} + {/* Delete Machinery */} setMachineryToDelete(null)} From e10a553cb4b90b4340868865c5eadbd05a7d83f6 Mon Sep 17 00:00:00 2001 From: Santiordon Date: Sat, 15 Nov 2025 01:18:49 -0500 Subject: [PATCH 215/477] Add Calendar Transformer --- src/backend/src/prisma/seed.ts | 2 +- src/frontend/src/apis/calendar.api.ts | 3 +- .../apis/transformers/calendar.transformer.ts | 14 +- .../pages/NewCalendarPage/YourEventsPage.tsx | 156 ++++++++++++++---- src/frontend/src/utils/urls.ts | 2 +- src/shared/src/types/calendar-types.ts | 4 +- 6 files changed, 144 insertions(+), 37 deletions(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 628adc2e79..974a667aed 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3284,7 +3284,7 @@ const performSeed: () => Promise = async () => { [], [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], + days: [DayOfWeek.THURSDAY], startTime: new Date(), recurrenceNumber: 1, initialDateScheduled: new Date('2025-10-20T00:00:00.000Z'), diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 153e11a52a..e5fd89c7c5 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -3,6 +3,7 @@ import { apiUrls } from '../utils/urls'; import { Shop, Event } from 'shared'; import { FilterArgs } from 'shared'; +import { filterEventsTransformer } from './transformers/calendar.transformer'; export const getAllShops = () => { return axios.get(apiUrls.calendarShops(), { @@ -18,6 +19,6 @@ export const postCreateShop = (payload: { name: string; description: string }) = export const postFilterEvents = (payload: FilterArgs) => { return axios.post(apiUrls.calendarFilterEvents(), payload, { - transformResponse: (data) => JSON.parse(data) as Event[] + transformResponse: (data) => filterEventsTransformer(JSON.parse(data) as Event[]) }); }; diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts index 107d94ef25..f058753ef0 100644 --- a/src/frontend/src/apis/transformers/calendar.transformer.ts +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -1,4 +1,4 @@ -import { Shop } from 'shared'; +import { Event, Shop } from 'shared'; import { userTransformer } from './users.transformers'; export const shopTransformer = (shop: Shop): Shop => { @@ -8,3 +8,15 @@ export const shopTransformer = (shop: Shop): Shop => { userCreated: userTransformer(shop.userCreated) }; }; + +export const filterEventsTransformer = (events: Event[]): any => { + return events.map((event) => ({ + ...event, + dateCreated: new Date(event.dateCreated), + scheduledTimes: event.scheduledTimes.map((schedule) => ({ + ...schedule, + startTime: schedule.startTime ? new Date(schedule.startTime) : undefined, + endTime: schedule.endTime ? new Date(schedule.endTime) : undefined + })) + })); +} \ No newline at end of file diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 753e57a615..65c726ce23 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -5,6 +5,7 @@ import { Box, Button, + Link, Paper, Tab, Table, @@ -18,7 +19,12 @@ import { } from '@mui/material'; import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; -import { useState } from 'react'; +import { useFilterEvents } from '../../hooks/calendar.hooks'; +import { useCurrentUser } from '../../hooks/users.hooks'; +import { useEffect, useState } from 'react'; +import { FilterArgs, ScheduleSlot } from 'shared'; +import { Event } from 'shared'; +import { time } from 'console'; interface YourEventsHeadCells { id: string; @@ -52,7 +58,51 @@ const headCells: readonly YourEventsHeadCells[] = [ } ]; +const earliestSchedules = new Map(); + +const getEarliestSchedule = (event: Event) => { + if (earliestSchedules.has(event.eventId)) { + return earliestSchedules.get(event.eventId)!; + } + + const [result] = event.scheduledTimes + .filter((schedule): schedule is ScheduleSlot & { startTime: Date } => schedule.startTime !== undefined) + .sort((a, b) => a.startTime.getUTCSeconds() - b.startTime.getUTCSeconds()); + + earliestSchedules.set(event.eventId, result); + return result; +}; + const YourEventsPage = () => { + const { mutateAsync: filterEventsMutate } = useFilterEvents(); + const user = useCurrentUser(); + + const [events, setEvents] = useState([] as Event[]); + const [eventsLoading, setEventsLoading] = useState(true); + const [update, setUpdate] = useState(true); + + useEffect(() => { + // Example filter on mount + console.log('Filtering events...'); + const filterArgs: FilterArgs = { + memberIds: [user.userId], + startPeriod: new Date(0), // Adjust as needed + endPeriod: new Date(2099, 11, 31) // Adjust as needed + }; + filterEventsMutate(filterArgs).then((events) => { + setEvents(events); + setEventsLoading(false); + }); + }, [filterEventsMutate, user.userId]); + + // Every second, just setInterval(true) to trigger re-render for time updates + useEffect(() => { + const timer = setInterval(() => { + setUpdate((prev) => !prev); + }, 1000); + return () => clearInterval(timer); + }, []); + return ( @@ -64,7 +114,7 @@ const YourEventsPage = () => { WebkitMaskImage: 'linear-gradient(to bottom, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 86%, rgba(0,0,0,0) 90%)', maskImage: 'linear-gradient(to bottom, rgba(0,0,0,1) 0%, rgba(0,0,0,1) 86%, rgba(0,0,0,0) 90%)', WebkitMaskRepeat: 'no-repeat', - WebkitMaskSize: '100% 100%', + WebkitMaskSize: '100% 100%' }} > @@ -76,42 +126,86 @@ const YourEventsPage = () => { - {[...Array(100)].map((_, i) => ( - - {headCells.map((headCell) => ( - - {headCell.label} Data {i + 1} - - ))} + {eventsLoading ? ( + + + Loading... + + + ) : events.length === 0 ? ( + + + No events found. + - ))} + ) : ( + /* TODO: Pass event data through a transformer to set it to date without needing to call new Date() */ + events.map((event) => { + const earliestSchedule = getEarliestSchedule(event); + const now = new Date(); + const diffMs = earliestSchedule.startTime.getTime() - now.getTime(); + + const seconds = Math.floor(diffMs / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + + // Rough month estimate (30 days) + const months = Math.floor(days / 30); + + const timeAway = { + passed: diffMs <= 0, + months, + days: days % 30, + hours: hours % 24, + minutes: minutes % 60, + seconds: seconds % 60 + }; + + return ( + + {event.title} + + {new Date(earliestSchedule.startTime).toLocaleDateString()}{' '} + {!timeAway.passed ? ` - In ${timeAway.months}m : ${timeAway.days}d` : '- Passed'} + + + {new Date(earliestSchedule.startTime).toLocaleTimeString()}{' '} + {!timeAway.passed ? ` - In ${timeAway.hours}h ${timeAway.minutes}m ${timeAway.seconds}s` : '- Passed'} + + + {event.location ? ( + event.location.includes('https://') ? ( + + {event.location} + + ) : ( + event.location + ) + ) : ( + 'N/A' + )} + + + {event.approvedBy ? `${event.approvedBy.firstName} ${event.approvedBy.lastName}` : 'N/A'} + + {event.approved ? 'Approved' : 'Pending'} + + ); + }) + )} - - + sx={{ + py: 5 + }} + >
diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index d8eb71d6e9..4de9db5b88 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -439,7 +439,7 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; const calendarCreateShop = () => `${calendar()}/shop/create`; -const calendarFilterEvents = () => `${API_URL}/events/filter`; +const calendarFilterEvents = () => `${calendar()}/events/filter`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index e14a4b1dde..41c1c5ac5f 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -49,8 +49,8 @@ export interface FilterArgs { eventTypeIds?: string[]; eventIds?: string[]; approvalStatus?: boolean; - startPeriod?: Date; - endPeriod?: Date; + startPeriod: Date; + endPeriod: Date; } export interface EventType { From 1f49e887c227039fd1573e4e0ded3bf20a62840e Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 15 Nov 2025 20:08:32 -0500 Subject: [PATCH 216/477] #3635 initial calendar modal --- src/frontend/src/apis/calendar.api.ts | 20 +- src/frontend/src/hooks/calendar.hooks.ts | 43 +++- .../AdminToolsScheduleConfig.tsx | 178 ++++++++++++++- .../ScheduleConfig/Calendar/CalendarModal.tsx | 211 ++++++++++++++++++ .../Calendar/CreateCalendarModal.tsx | 14 ++ .../ScheduleConfig/Calendar/EditCalendar.tsx | 15 ++ src/frontend/src/utils/urls.ts | 6 + 7 files changed, 472 insertions(+), 15 deletions(-) create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendar.tsx diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index a953cfb1b5..1a45185659 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,6 +1,24 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; -import { Shop, Machinery } from 'shared'; +import { Shop, Machinery, Calendar } from 'shared'; + +export const getAllCalendars = () => { + return axios.get(apiUrls.calendarCalendars(), { + transformResponse: (data) => JSON.parse(data) as Calendar[] + }); +}; + +export const postCreateCalendar = (payload: { name: string; description: string; color: string }) => { + return axios.post(apiUrls.calendarCreateCalendar(), payload, { + transformResponse: (data) => JSON.parse(data) as Calendar + }); +}; + +export const postEditCalendar = (calendarId: string, payload: { name: string; description: string; color: string }) => { + return axios.post(apiUrls.calendarEditCalendar(calendarId), payload, { + transformResponse: (data) => JSON.parse(data) as Calendar + }); +}; export const getAllShops = () => { return axios.get(apiUrls.calendarShops(), { diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 8c787564ed..34a8dc26b6 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,5 +1,5 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop, Machinery } from 'shared'; +import { Shop, Machinery, Calendar } from 'shared'; import { getAllShops, postCreateShop, @@ -7,11 +7,50 @@ import { postCreateMachinery, postEditMachinery, postAddMachineryToShop, - editShop + editShop, + getAllCalendars, + postEditCalendar, + postCreateCalendar } from '../apis/calendar.api'; export const MACHINERY_KEY = ['machinery'] as const; +export const useAllCalendars = () => + useQuery(['calendars'], async () => { + const res = await getAllCalendars(); + return res.data; + }); + +export const useCreateCalendar = () => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + const { data } = await postCreateCalendar(payload); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries(['calendars']); + } + } + ); +}; + +export const useEditCalendar = (calendarId: string) => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + const { data } = await postEditCalendar(calendarId, payload); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries(['calendars']); + } + } + ); +}; + export const useAllShops = () => useQuery(['shops'], async () => { const res = await getAllShops(); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 93c9488037..a83de61948 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -1,11 +1,32 @@ import React, { useState } from 'react'; -import { Box, Grid, Typography, Paper, Table, TableBody, TableCell, TableHead, TableRow, Button } from '@mui/material'; +import { + Box, + Grid, + Typography, + Paper, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Button, + IconButton, + Tooltip +} from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; -import { IconButton, Tooltip } from '@mui/material'; -import { useAllShops, useCreateShop, useEditShop, useAllMachines } from '../../../hooks/calendar.hooks'; +import { + useAllShops, + useCreateShop, + useEditShop, + useAllMachines, + useAllCalendars, + useCreateCalendar, + useEditCalendar +} from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; +import CalendarModal, { CalendarFormValues } from './Calendar/CalendarModal'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import CreateMachineryModal from './Machinery/CreateMachineryModal'; @@ -25,9 +46,25 @@ const AdminToolsScheduleConfig: React.FC = () => { const [openEdit, setOpenEdit] = useState(false); const [editingShop, setEditingShop] = useState(null); - if (shopsLoading || machinesLoading) return ; + const { + data: calendars, + isLoading: calendarsLoading, + isError: calendarsError, + error: calendarsErrorMsg + } = useAllCalendars(); + + const { mutateAsync: createCalendarMutate } = useCreateCalendar(); + + const [editingCalendarId, setEditingCalendarId] = useState(); + const editCalendarMutation = useEditCalendar(editingCalendarId ?? ''); + + const [openCalendarModal, setOpenCalendarModal] = useState(false); + const [editingCalendar, setEditingCalendar] = useState(null); + + if (shopsLoading || machinesLoading || calendarsLoading) return ; if (shopsError) return ; if (machinesError) return ; + if (calendarsError) return ; return ( @@ -38,12 +75,89 @@ const AdminToolsScheduleConfig: React.FC = () => { - - Calendars - - - ... - + + Calendars + + + + + + + Name + Description + + Color + + + + + + + {!calendars || calendars.length === 0 ? ( + + + No calendars yet. + + + ) : ( + calendars.map((calendar: any) => ( + + {calendar.name} + {calendar.description ?? '—'} + + + + + + + + + { + setEditingCalendar(calendar); + setEditingCalendarId(calendar.calendarId); + setOpenCalendarModal(true); + }} + > + + + + + + + + + + + + + + + + )) + )} + +
@@ -78,6 +192,7 @@ const AdminToolsScheduleConfig: React.FC = () => { + {!shops || shops.length === 0 ? ( @@ -125,15 +240,16 @@ const AdminToolsScheduleConfig: React.FC = () => {
- {/*Machinery Table */} + {/* Machinery Table */} - + Machinery + @@ -147,6 +263,7 @@ const AdminToolsScheduleConfig: React.FC = () => { + {!machines || !Array.isArray(machines) || machines.length === 0 ? ( @@ -218,6 +335,43 @@ const AdminToolsScheduleConfig: React.FC = () => { }} /> + {/* Calendar Modal */} + { + setOpenCalendarModal(false); + setEditingCalendar(null); + setEditingCalendarId(undefined); + }} + initialValues={ + editingCalendar + ? { + name: editingCalendar.name ?? '', + description: editingCalendar.description ?? '', + color: editingCalendar.color ?? '#F97316' + } + : undefined + } + onSubmit={async ({ name, description, color }: CalendarFormValues) => { + const payload = { + name, + description, + color, + colorHexCode: color + } as any; + + if (editingCalendarId) { + await editCalendarMutation.mutateAsync(payload); + } else { + await createCalendarMutate(payload); + } + + setOpenCalendarModal(false); + setEditingCalendar(null); + setEditingCalendarId(undefined); + }} + /> + {/* Create Machine Modal */} setOpenCreateMachinery(false)} /> diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx new file mode 100644 index 0000000000..79873bcf22 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx @@ -0,0 +1,211 @@ +import React from 'react'; +import { Box, FormControl, FormHelperText, Typography, Stack } from '@mui/material'; +import NERFormModal from '../../../../components/NERFormModal'; +import ReactHookTextField from '../../../../components/ReactHookTextField'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { useForm } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import type { Calendar } from 'shared'; + +export interface CalendarFormValues { + name: string; + description: string; + color: string; +} + +const schema = yup.object({ + name: yup.string().required('Calendar Name is required'), + description: yup.string().required('Description is required'), + color: yup.string().required('Color is required') +}); + +export interface BaseCalendarModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: CalendarFormValues) => Promise | Calendar | unknown; + initialValues?: Partial; +} + +const COLOR_OPTIONS: { label: string; value: string }[] = [ + { label: 'Orange', value: '#F97316' }, + { label: 'Red', value: '#EF4444' }, + { label: 'Green', value: '#22C55E' }, + { label: 'Blue', value: '#3B82F6' }, + { label: 'Purple', value: '#A855F7' }, + { label: 'Navy', value: '#1E3A8A' } +]; + +const DEFAULT_COLOR = COLOR_OPTIONS[0].value; + +const CalendarModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { + const toast = useToast(); + + const { + handleSubmit, + control, + reset, + watch, + setValue, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { + name: '', + description: '', + color: DEFAULT_COLOR + } + }); + + const frozenValuesRef = React.useRef({ + name: '', + description: '', + color: DEFAULT_COLOR + }); + + React.useEffect(() => { + if (open) { + frozenValuesRef.current = { + name: initialValues?.name ?? '', + description: initialValues?.description ?? '', + color: initialValues?.color ?? DEFAULT_COLOR + }; + reset(frozenValuesRef.current); + } else { + frozenValuesRef.current = { + name: '', + description: '', + color: DEFAULT_COLOR + }; + reset(frozenValuesRef.current); + } + }, [open, initialValues, reset]); + + const computedTitle = frozenValuesRef.current.name !== '' ? 'Edit Calendar' : 'Add Calendar'; + + const onFormSubmit = async (data: CalendarFormValues) => { + try { + await onSubmit(data); + onClose(); + reset({ + name: '', + description: '', + color: DEFAULT_COLOR + }); + } catch (e: unknown) { + if (e instanceof Error) toast.error(e.message); + } + }; + + const selectedColor = watch('color') || DEFAULT_COLOR; + + const handleColorClick = (value: string) => { + setValue('color', value, { shouldValidate: true }); + }; + + return ( + { + onClose(); + reset({ + name: '', + description: '', + color: DEFAULT_COLOR + }); + }} + title={computedTitle} + reset={() => + reset({ + name: '', + description: '', + color: DEFAULT_COLOR + }) + } + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="calendar-form" + showCloseButton + > + + {/* Calendar Name */} + + + Calendar:* + + + {errors.name?.message} + + + {/* Description */} + + + Description:* + + + {errors.description?.message} + + + {/* Color pills */} + + + Color:* + + + + {COLOR_OPTIONS.map((c) => { + const isSelected = c.value === selectedColor; + return ( + handleColorClick(c.value)} + sx={{ + cursor: 'pointer', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + px: 1.5, + height: 28, + borderRadius: '999px', + backgroundColor: c.value, + border: isSelected ? '2px solid #ef4345' : '2px solid transparent', + boxSizing: 'border-box', + minWidth: 32 + }} + /> + ); + })} + + + Add color + + + + {errors.color?.message} + + + + ); +}; + +export default CalendarModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx new file mode 100644 index 0000000000..7ff8432161 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import CalendarModal, { CalendarFormValues } from './CalendarModal'; + +interface CreateCalendarModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: CalendarFormValues) => Promise | unknown; +} + +const CreateCalendarModal: React.FC = (props) => { + return ; +}; + +export default CreateCalendarModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendar.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendar.tsx new file mode 100644 index 0000000000..2fbb5e6ed4 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendar.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import CalendarModal, { CalendarFormValues } from './CalendarModal'; + +export interface EditCalendarModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: CalendarFormValues) => Promise | unknown; + initialValues: Partial; +} + +const EditCalendarModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { + return ; +}; + +export default EditCalendarModal; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 2ad0e92847..aeb5554c4e 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -444,6 +444,9 @@ const calendarCreateMachinery = () => `${calendar()}/machinery/create`; const calendarEditMachinery = (machineryId: string) => `${calendar()}/machinery/${machineryId}/edit`; const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; const calendarEditShop = (shopId: string) => `${calendar()}/shop/${shopId}/edit`; +const calendarCreateCalendar = () => `${calendar()}/create`; +const calendarEditCalendar = (calendarId: string) => `${calendar()}/${calendarId}/edit`; +const calendarCalendars = () => `${calendar()}/calendars`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -753,6 +756,9 @@ export const apiUrls = { calendarEditMachinery, calendarAddMachineryToShop, calendarEditShop, + calendarCreateCalendar, + calendarEditCalendar, + calendarCalendars, version }; From 8a0c3cdf054871395ca71ff48835dfa348865c08 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 15 Nov 2025 20:56:49 -0500 Subject: [PATCH 217/477] #3635 Slight fixes --- .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index a83de61948..a9e992d409 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -192,7 +192,6 @@ const AdminToolsScheduleConfig: React.FC = () => { - {!shops || shops.length === 0 ? ( @@ -240,16 +239,15 @@ const AdminToolsScheduleConfig: React.FC = () => { - {/* Machinery Table */} + {/*Machinery Table */} - + Machinery -
From 6867957a59fee20e7037eb81c584bdf7d5c4ba6f Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 17 Nov 2025 09:50:05 -0500 Subject: [PATCH 218/477] #3635 additional merge fix --- .../AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 6f5a6ca662..91dfd76eaf 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -10,8 +10,6 @@ import { TableHead, TableRow, Button, - IconButton, - Tooltip } from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; From b35a3f4734ca48316d6e7ca545e6c8a7bb9ce707 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 17 Nov 2025 09:52:27 -0500 Subject: [PATCH 219/477] #3635 prettier fix --- .../AdminToolsScheduleConfig.tsx | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 91dfd76eaf..a4c33fb990 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -1,23 +1,19 @@ import React, { useState } from 'react'; -import { - Box, - Grid, - Typography, - Paper, - Table, - TableBody, - TableCell, - TableHead, - TableRow, - Button, -} from '@mui/material'; +import { Box, Grid, Typography, Paper, Table, TableBody, TableCell, TableHead, TableRow, Button } from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; import { IconButton, Tooltip } from '@mui/material'; -import { useAllShops, useCreateShop, useEditShop, useAllMachines, useDeleteMachinery, useAllCalendars, +import { + useAllShops, + useCreateShop, + useEditShop, + useAllMachines, + useDeleteMachinery, + useAllCalendars, useCreateCalendar, - useEditCalendar} from '../../../hooks/calendar.hooks'; + useEditCalendar +} from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; import CalendarModal, { CalendarFormValues } from './Calendar/CalendarModal'; import EditIcon from '@mui/icons-material/Edit'; From 0461d16aefe0ac64ba2dfb9b15a94ff83ee0e6e5 Mon Sep 17 00:00:00 2001 From: Santiordon Date: Mon, 17 Nov 2025 16:49:19 -0500 Subject: [PATCH 220/477] Add Final modifications to UI --- src/frontend/src/hooks/calendar.hooks.ts | 2 +- src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 1994ba3540..0138807a89 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,5 +1,5 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop, Machinery, FilterArgs } from 'shared'; +import { Shop, Machinery, FilterArgs, Event } from 'shared'; import { getAllShops, postCreateShop, diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 68844d829a..5a2556d5d6 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -24,7 +24,6 @@ import { useCurrentUser } from '../../hooks/users.hooks'; import { useEffect, useState } from 'react'; import { FilterArgs, ScheduleSlot } from 'shared'; import { Event } from 'shared'; -import { time } from 'console'; interface YourEventsHeadCells { id: string; @@ -186,7 +185,7 @@ const YourEventsPage = () => { )} - {event.approved ? `${event.approvalRequiredFrom?.firstName} ${event.approvalRequiredFrom?.lastName}` : 'N/A'} + {!event.approved ? `${event.approvalRequiredFrom?.firstName} ${event.approvalRequiredFrom?.lastName}` : 'N/A'} {event.approved ? 'Approved' : 'Pending'} From e3506910869b7df77a9d5d14701da4d968d5eef2 Mon Sep 17 00:00:00 2001 From: Saul M Date: Tue, 18 Nov 2025 12:20:28 -0500 Subject: [PATCH 221/477] #3676 uses NERDeleteModal --- src/frontend/src/apis/calendar.api.ts | 4 +-- src/frontend/src/hooks/calendar.hooks.ts | 3 +- .../AdminToolsScheduleConfig.tsx | 26 +++++++++++++--- .../ScheduleConfig/Shop/DeleteShopModal.tsx | 31 +++++++------------ 4 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index efb81269cd..3cea978718 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -14,8 +14,8 @@ export const postCreateShop = (payload: { name: string; description: string }) = }); }; -export const postDeleteShop = async (name: string) => { - return axios.post(apiUrls.calendarDeleteShop(name)); +export const postDeleteShop = async (id: string) => { + return axios.post(apiUrls.calendarDeleteShop(id)); }; export const getAllMachinery = () => { diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 30247c6f79..cf07946a23 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -12,7 +12,7 @@ import { } from '../apis/calendar.api'; export const MACHINERY_KEY = ['machinery'] as const; -export const SHOP_KEY = ['shop', 'shops'] as const; +const SHOP_KEY = ['shops'] as const; export const useAllShops = () => useQuery(SHOP_KEY, async () => { @@ -108,6 +108,7 @@ export const useDeleteShop = () => { const qc = useQueryClient(); return useMutation<{ shopId: string }, Error, string>( async (shopId: string) => { + console.log(shopId) const { data } = await postDeleteShop(shopId); return data; }, diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index a234823c4f..7eee9be901 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -4,7 +4,7 @@ import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; import { IconButton, Tooltip } from '@mui/material'; -import { useAllShops, useCreateShop, useEditShop, useAllMachines } from '../../../hooks/calendar.hooks'; +import { useAllShops, useCreateShop, useEditShop, useAllMachines, useDeleteShop } from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; @@ -12,6 +12,7 @@ import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; import DeleteShopModal from './Shop/DeleteShopModal'; import { Shop } from 'shared'; +import NERDeleteModal from '../../../components/NERDeleteModal'; const AdminToolsScheduleConfig: React.FC = () => { const { data: shops, isLoading: shopsLoading, isError: shopsError, error: shopsErrorMsg } = useAllShops(); @@ -26,7 +27,10 @@ const AdminToolsScheduleConfig: React.FC = () => { const [editMachinery, setEditMachinery] = useState<{ machineryId: string; shopId: string } | null>(null); const [openEdit, setOpenEdit] = useState(false); const [editingShop, setEditingShop] = useState(null); + const [deletingShop, setDeletingShop] = useState(false); const [shopToDelete, setShopToDelete] = useState(undefined); + const { mutateAsync } = useDeleteShop(); + if (shopsLoading || machinesLoading) return ; if (shopsError) return ; @@ -117,7 +121,12 @@ const AdminToolsScheduleConfig: React.FC = () => { size="small" color="error" aria-label="delete shop" - onClick={() => setShopToDelete(shop)} + onClick={ + () => { + setShopToDelete(shop); + setDeletingShop(true); + } + } > @@ -228,9 +237,16 @@ const AdminToolsScheduleConfig: React.FC = () => { {/* Delete Shop Modal */} {shopToDelete && ( - { + { + await mutateAsync(shopToDelete.shopId); + setDeletingShop(false); + setShopToDelete(undefined); + }} + dataType={shopToDelete.name} + open={deletingShop} + onHide={() => { + setDeletingShop(false); setShopToDelete(undefined); }} /> diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx index 39e6fb6140..c85cbcbbae 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx @@ -1,33 +1,26 @@ -import { Shop } from 'shared'; -import NERModal from '../../../../components/NERModal'; -import { Typography } from '@mui/material'; import { useDeleteShop } from '../../../../hooks/calendar.hooks'; +import NERDeleteModal from '../../../../components/NERDeleteModal'; +import { Shop } from 'shared'; export interface DeleteShopModalProps { onClose: () => void; shop: Shop; + isOpen: boolean; } -const DeleteShopModal = ({ onClose, shop }: DeleteShopModalProps) => { +const DeleteShopModal = ({ onClose, shop, isOpen }: DeleteShopModalProps) => { const { mutateAsync } = useDeleteShop(); return ( - { - mutateAsync(shop?.shopId); + { + mutateAsync(shop.shopId); onClose(); - }} - showCloseButton - > - - Do you want to delete shop: {shop?.name}? - - + }} + dataType={shop.name} + open={isOpen} + onHide={onClose} + /> ); }; From b20000502b31c2efd5af94f8d548a427ab4aba97 Mon Sep 17 00:00:00 2001 From: Saul M Date: Tue, 18 Nov 2025 12:23:47 -0500 Subject: [PATCH 222/477] #3676 deleted DeleteShopModal --- .../AdminToolsScheduleConfig.tsx | 1 - .../ScheduleConfig/Shop/DeleteShopModal.tsx | 27 ------------------- 2 files changed, 28 deletions(-) delete mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 7eee9be901..944f0c888a 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -10,7 +10,6 @@ import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; -import DeleteShopModal from './Shop/DeleteShopModal'; import { Shop } from 'shared'; import NERDeleteModal from '../../../components/NERDeleteModal'; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx deleted file mode 100644 index c85cbcbbae..0000000000 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Shop/DeleteShopModal.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { useDeleteShop } from '../../../../hooks/calendar.hooks'; -import NERDeleteModal from '../../../../components/NERDeleteModal'; -import { Shop } from 'shared'; - -export interface DeleteShopModalProps { - onClose: () => void; - shop: Shop; - isOpen: boolean; -} - -const DeleteShopModal = ({ onClose, shop, isOpen }: DeleteShopModalProps) => { - const { mutateAsync } = useDeleteShop(); - - return ( - { - mutateAsync(shop.shopId); - onClose(); - }} - dataType={shop.name} - open={isOpen} - onHide={onClose} - /> - ); -}; - -export default DeleteShopModal; From 4b09b93260a9c9fb790bfb5c92d4c3b4cec276c3 Mon Sep 17 00:00:00 2001 From: Saul M Date: Tue, 18 Nov 2025 12:33:36 -0500 Subject: [PATCH 223/477] WIP: local changes --- src/frontend/src/hooks/calendar.hooks.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index cf07946a23..bf8185aa0a 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -108,7 +108,6 @@ export const useDeleteShop = () => { const qc = useQueryClient(); return useMutation<{ shopId: string }, Error, string>( async (shopId: string) => { - console.log(shopId) const { data } = await postDeleteShop(shopId); return data; }, @@ -118,4 +117,4 @@ export const useDeleteShop = () => { } } ); -}; +} \ No newline at end of file From 64b83c46a07d4f4d37313531fffe0b621ca50b23 Mon Sep 17 00:00:00 2001 From: Santiordon Date: Tue, 18 Nov 2025 19:30:26 -0500 Subject: [PATCH 224/477] Remove Comments --- src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 5a2556d5d6..c5553c3932 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -94,7 +94,6 @@ const YourEventsPage = () => { }); }, [filterEventsMutate, user.userId]); - // Every second, just setInterval(true) to trigger re-render for time updates useEffect(() => { const timer = setInterval(() => { setUpdate((prev) => !prev); From dea2cee98fa86f52c99c461760780171dbe1cb52 Mon Sep 17 00:00:00 2001 From: Santiordon Date: Tue, 18 Nov 2025 19:37:28 -0500 Subject: [PATCH 225/477] #3706 Fix Lint and Prettier issues --- .../apis/transformers/calendar.transformer.ts | 2 +- src/frontend/src/hooks/calendar.hooks.ts | 2 +- .../pages/NewCalendarPage/YourEventsPage.tsx | 24 +++++-------------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts index f058753ef0..453db92627 100644 --- a/src/frontend/src/apis/transformers/calendar.transformer.ts +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -19,4 +19,4 @@ export const filterEventsTransformer = (events: Event[]): any => { endTime: schedule.endTime ? new Date(schedule.endTime) : undefined })) })); -} \ No newline at end of file +}; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 246bfb9699..b2e766e8b2 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -132,4 +132,4 @@ export const useFilterEvents = () => { } } ); -} \ No newline at end of file +}; diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index c5553c3932..c1483248f2 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -2,21 +2,7 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { - Box, - Button, - Link, - Paper, - Tab, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TablePagination, - TableRow, - Typography -} from '@mui/material'; +import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material'; import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; import { useFilterEvents } from '../../hooks/calendar.hooks'; @@ -78,14 +64,14 @@ const YourEventsPage = () => { const [events, setEvents] = useState([] as Event[]); const [eventsLoading, setEventsLoading] = useState(true); - const [update, setUpdate] = useState(true); + const [, setUpdate] = useState(true); // Linting... useEffect(() => { // Example filter on mount console.log('Filtering events...'); const filterArgs: FilterArgs = { memberIds: [user.userId], - startPeriod: new Date(0), // Adjust as needed + startPeriod: new Date(0), endPeriod: new Date(2099, 11, 31) // Adjust as needed }; filterEventsMutate(filterArgs).then((events) => { @@ -184,7 +170,9 @@ const YourEventsPage = () => { )} - {!event.approved ? `${event.approvalRequiredFrom?.firstName} ${event.approvalRequiredFrom?.lastName}` : 'N/A'} + {!event.approved + ? `${event.approvalRequiredFrom?.firstName} ${event.approvalRequiredFrom?.lastName}` + : 'N/A'} {event.approved ? 'Approved' : 'Pending'} From 6429a5ec0a4e88bc1c17ac1c1e06d38edfcf1dbf Mon Sep 17 00:00:00 2001 From: Saul M Date: Tue, 18 Nov 2025 20:12:31 -0500 Subject: [PATCH 226/477] #3676 fixed test --- src/frontend/src/hooks/calendar.hooks.ts | 7 ++- .../AdminToolsScheduleConfig.tsx | 60 +++++++++++-------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 950ff9be1c..cb07b8e535 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -115,6 +115,11 @@ export const useDeleteShop = () => { { onSuccess: () => { qc.invalidateQueries(SHOP_KEY); + } + } + ); +}; + export const useDeleteMachinery = () => { const qc = useQueryClient(); return useMutation( @@ -127,4 +132,4 @@ export const useDeleteMachinery = () => { } } ); -} \ No newline at end of file +}; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 818b42e164..f5329508cb 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -4,7 +4,14 @@ import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; import { IconButton, Tooltip } from '@mui/material'; -import { useAllShops, useCreateShop, useEditShop, useAllMachines, useDeleteMachinery, useDeleteShop } from '../../../hooks/calendar.hooks'; +import { + useAllShops, + useCreateShop, + useEditShop, + useAllMachines, + useDeleteMachinery, + useDeleteShop +} from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; @@ -12,6 +19,7 @@ import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; import { Shop } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; +import NERDeleteModal from '../../../components/NERDeleteModal'; const AdminToolsScheduleConfig: React.FC = () => { const { data: shops, isLoading: shopsLoading, isError: shopsError, error: shopsErrorMsg } = useAllShops(); @@ -25,6 +33,7 @@ const AdminToolsScheduleConfig: React.FC = () => { machineName: string; } | null>(null); const { mutateAsync: deleteMachinery } = useDeleteMachinery(); + const { mutateAsync: deleteShop } = useDeleteShop(); const toast = useToast(); const handleDeleteMachinery = async () => { @@ -42,15 +51,27 @@ const AdminToolsScheduleConfig: React.FC = () => { } }; + const handleShopDelete = async () => { + if (!shopToDelete) return; + setShopToDelete(undefined); + try { + await deleteShop(shopToDelete.shopId); + toast.success('Shop deleted successfully'); + } catch (e: unknown) { + if (e instanceof Error) { + toast.error(e.message, 3000); + } else { + toast.error('Failed to delete shop', 3000); + } + } + }; + const [openCreate, setOpenCreate] = useState(false); const [openCreateMachinery, setOpenCreateMachinery] = useState(false); const [editMachinery, setEditMachinery] = useState<{ machineryId: string; shopId: string } | null>(null); const [openEdit, setOpenEdit] = useState(false); const [editingShop, setEditingShop] = useState(null); - const [deletingShop, setDeletingShop] = useState(false); const [shopToDelete, setShopToDelete] = useState(undefined); - const { mutateAsync } = useDeleteShop(); - if (shopsLoading || machinesLoading) return ; if (shopsError) return ; @@ -141,12 +162,9 @@ const AdminToolsScheduleConfig: React.FC = () => { size="small" color="error" aria-label="delete shop" - onClick={ - () => { - setShopToDelete(shop); - setDeletingShop(true); - } - } + onClick={() => { + setShopToDelete(shop); + }} > @@ -266,21 +284,13 @@ const AdminToolsScheduleConfig: React.FC = () => { /> {/* Delete Shop Modal */} - {shopToDelete && ( - { - await mutateAsync(shopToDelete.shopId); - setDeletingShop(false); - setShopToDelete(undefined); - }} - dataType={shopToDelete.name} - open={deletingShop} - onHide={() => { - setDeletingShop(false); - setShopToDelete(undefined); - }} - /> - )} + setShopToDelete(undefined)} + formId="delete-shop-form" + dataType={shopToDelete?.name || ''} + onFormSubmit={handleShopDelete} + /> {/* Create Machine Modal */} setOpenCreateMachinery(false)} /> From c6d72b7ad06e7e8e793af7e1712038ed88630a06 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Thu, 20 Nov 2025 11:16:43 -0500 Subject: [PATCH 227/477] #3635 review changes --- .../ScheduleConfig/Calendar/CalendarModal.tsx | 3 ++- .../Calendar/CreateCalendarModal.tsx | 14 -------------- .../ScheduleConfig/Calendar/EditCalendar.tsx | 15 --------------- 3 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx delete mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendar.tsx diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx index 79873bcf22..818a7931de 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx @@ -81,7 +81,8 @@ const CalendarModal: React.FC = ({ open, onClose, onSubm } }, [open, initialValues, reset]); - const computedTitle = frozenValuesRef.current.name !== '' ? 'Edit Calendar' : 'Add Calendar'; + const computedTitle = initialValues ? 'Edit Calendar' : 'Add Calendar'; + const onFormSubmit = async (data: CalendarFormValues) => { try { diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx deleted file mode 100644 index 7ff8432161..0000000000 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import CalendarModal, { CalendarFormValues } from './CalendarModal'; - -interface CreateCalendarModalProps { - open: boolean; - onClose: () => void; - onSubmit: (data: CalendarFormValues) => Promise | unknown; -} - -const CreateCalendarModal: React.FC = (props) => { - return ; -}; - -export default CreateCalendarModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendar.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendar.tsx deleted file mode 100644 index 2fbb5e6ed4..0000000000 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendar.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import CalendarModal, { CalendarFormValues } from './CalendarModal'; - -export interface EditCalendarModalProps { - open: boolean; - onClose: () => void; - onSubmit: (data: CalendarFormValues) => Promise | unknown; - initialValues: Partial; -} - -const EditCalendarModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { - return ; -}; - -export default EditCalendarModal; From b5063c31ca3fa922ba43174bf2742da2346aad1e Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Thu, 20 Nov 2025 11:42:25 -0500 Subject: [PATCH 228/477] #3635 prettier fix --- .../AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx index 818a7931de..7541eadca8 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx @@ -83,7 +83,6 @@ const CalendarModal: React.FC = ({ open, onClose, onSubm const computedTitle = initialValues ? 'Edit Calendar' : 'Add Calendar'; - const onFormSubmit = async (data: CalendarFormValues) => { try { await onSubmit(data); From 422ef0cce34991cdd2d07d8024bd5c07cbc10c33 Mon Sep 17 00:00:00 2001 From: Saul M Date: Fri, 21 Nov 2025 12:23:11 -0500 Subject: [PATCH 229/477] #3775 added delete calendar modal --- src/frontend/src/apis/calendar.api.ts | 6 +++- src/frontend/src/hooks/calendar.hooks.ts | 18 ++++++++++- .../AdminToolsScheduleConfig.tsx | 31 +++++++++++++++++-- src/frontend/src/utils/urls.ts | 2 ++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 09f89b1dae..49398d8481 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,6 +1,6 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; -import { Shop, Machinery } from 'shared'; +import { Shop, Machinery, Calendar } from 'shared'; export const getAllShops = () => { return axios.get(apiUrls.calendarShops(), { @@ -76,3 +76,7 @@ export const editShop = (shopId: string, payload: { name: string; description: s transformResponse: (data) => JSON.parse(data) as Shop }); }; + +export const postDeleteCalendar = async (id: string) => { + return axios.post(apiUrls.calendarDeleteCalendar(id)); +}; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index cb07b8e535..644c1b0110 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -9,7 +9,8 @@ import { postEditMachinery, postDeleteMachinery, postAddMachineryToShop, - editShop + editShop, + postDeleteCalendar } from '../apis/calendar.api'; export const MACHINERY_KEY = ['machinery'] as const; @@ -133,3 +134,18 @@ export const useDeleteMachinery = () => { } ); }; + +export const useDeleteCalendar = () => { + const qc = useQueryClient(); + return useMutation<{ calendarId: string }, Error, string>( + async (calendarId: string) => { + const { data } = await postDeleteCalendar(calendarId); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries(SHOP_KEY); + } + } + ); +}; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index f5329508cb..b98950e349 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -10,14 +10,15 @@ import { useEditShop, useAllMachines, useDeleteMachinery, - useDeleteShop + useDeleteShop, + useDeleteCalendar } from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; -import { Shop } from 'shared'; +import { Calendar, Shop } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import NERDeleteModal from '../../../components/NERDeleteModal'; @@ -34,6 +35,7 @@ const AdminToolsScheduleConfig: React.FC = () => { } | null>(null); const { mutateAsync: deleteMachinery } = useDeleteMachinery(); const { mutateAsync: deleteShop } = useDeleteShop(); + const { mutateAsync: deleteCalendar } = useDeleteCalendar(); const toast = useToast(); const handleDeleteMachinery = async () => { @@ -66,12 +68,28 @@ const AdminToolsScheduleConfig: React.FC = () => { } }; + const handleCalendarDelete = async () => { + if (!calendarToDelete) return; + setCalendarToDelete(undefined); + try { + await deleteCalendar(calendarToDelete.calendarId); + toast.success('Shop deleted successfully'); + } catch (e: unknown) { + if (e instanceof Error) { + toast.error(e.message, 3000); + } else { + toast.error('Failed to delete shop', 3000); + } + } + }; + const [openCreate, setOpenCreate] = useState(false); const [openCreateMachinery, setOpenCreateMachinery] = useState(false); const [editMachinery, setEditMachinery] = useState<{ machineryId: string; shopId: string } | null>(null); const [openEdit, setOpenEdit] = useState(false); const [editingShop, setEditingShop] = useState(null); const [shopToDelete, setShopToDelete] = useState(undefined); + const [calendarToDelete, setCalendarToDelete] = useState(undefined); if (shopsLoading || machinesLoading) return ; if (shopsError) return ; @@ -272,6 +290,15 @@ const AdminToolsScheduleConfig: React.FC = () => { + {/* Delete Calendars Modal */} + setCalendarToDelete(undefined)} + formId="delete-calendar-form" + dataType={calendarToDelete?.name || ''} + onFormSubmit={handleCalendarDelete} + /> + {/* Add Shop Modal */} `${calendar()}/machiner const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; const calendarEditShop = (shopId: string) => `${calendar()}/shop/${shopId}/edit`; const calendarDeleteShop = (shopId: string) => `${calendar()}/shop/${shopId}/delete`; +const calendarDeleteCalendar = (calendarId: string) => `${calendar()}/shop/${calendarId}/delete`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -757,6 +758,7 @@ export const apiUrls = { calendarAddMachineryToShop, calendarEditShop, calendarDeleteShop, + calendarDeleteCalendar, version }; From 22509f63937f7fd058f2553d648011f6768e23a3 Mon Sep 17 00:00:00 2001 From: Saul M Date: Fri, 21 Nov 2025 12:30:30 -0500 Subject: [PATCH 230/477] #3375 Fixed some text and added CALENDAR_KEY --- src/frontend/src/hooks/calendar.hooks.ts | 3 ++- .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 644c1b0110..d8df696210 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -15,6 +15,7 @@ import { export const MACHINERY_KEY = ['machinery'] as const; const SHOP_KEY = ['shops'] as const; +const CALENDAR_KEY = ['calendars'] as const; export const useAllShops = () => useQuery(SHOP_KEY, async () => { @@ -144,7 +145,7 @@ export const useDeleteCalendar = () => { }, { onSuccess: () => { - qc.invalidateQueries(SHOP_KEY); + qc.invalidateQueries(CALENDAR_KEY); } } ); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index b98950e349..8e34cbef5a 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -73,12 +73,12 @@ const AdminToolsScheduleConfig: React.FC = () => { setCalendarToDelete(undefined); try { await deleteCalendar(calendarToDelete.calendarId); - toast.success('Shop deleted successfully'); + toast.success('Calendar deleted successfully'); } catch (e: unknown) { if (e instanceof Error) { toast.error(e.message, 3000); } else { - toast.error('Failed to delete shop', 3000); + toast.error('Failed to delete calendar', 3000); } } }; From 422dda3452b1c66c685a41cbc9443b4c77c010a5 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Fri, 21 Nov 2025 13:28:10 -0500 Subject: [PATCH 231/477] #3635 requested changed and more --- src/frontend/src/apis/calendar.api.ts | 7 +- src/frontend/src/hooks/calendar.hooks.ts | 4 +- .../AdminToolsScheduleConfig.tsx | 81 +++++++++--------- .../ScheduleConfig/Calendar/CalendarModal.tsx | 82 ++++--------------- .../Calendar/CreateCalendarModal.tsx | 13 +++ .../Calendar/EditCalendarModal.tsx | 14 ++++ 6 files changed, 93 insertions(+), 108 deletions(-) create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendarModal.tsx diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 2c5f9c822b..556c5e19ce 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -8,13 +8,16 @@ export const getAllCalendars = () => { }); }; -export const postCreateCalendar = (payload: { name: string; description: string; color: string }) => { +export const postCreateCalendar = (payload: { name: string; description: string; colorHexCode: string }) => { return axios.post(apiUrls.calendarCreateCalendar(), payload, { transformResponse: (data) => JSON.parse(data) as Calendar }); }; -export const postEditCalendar = (calendarId: string, payload: { name: string; description: string; color: string }) => { +export const postEditCalendar = ( + calendarId: string, + payload: { name: string; description: string; colorHexCode: string } +) => { return axios.post(apiUrls.calendarEditCalendar(calendarId), payload, { transformResponse: (data) => JSON.parse(data) as Calendar }); diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index c709cb315d..fdb47be008 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -26,7 +26,7 @@ export const useAllCalendars = () => export const useCreateCalendar = () => { const qc = useQueryClient(); - return useMutation( + return useMutation( async (payload) => { const { data } = await postCreateCalendar(payload); return data; @@ -41,7 +41,7 @@ export const useCreateCalendar = () => { export const useEditCalendar = (calendarId: string) => { const qc = useQueryClient(); - return useMutation( + return useMutation( async (payload) => { const { data } = await postEditCalendar(calendarId, payload); return data; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 7ff26c8896..1561cb52a2 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -16,7 +16,8 @@ import { useEditCalendar } from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; -import CalendarModal, { CalendarFormValues } from './Calendar/CalendarModal'; +import CreateCalendarModal from './Calendar/CreateCalendarModal'; +import EditCalendarModal from './Calendar/EditCalendarModal'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import CreateMachineryModal from './Machinery/CreateMachineryModal'; @@ -89,7 +90,8 @@ const AdminToolsScheduleConfig: React.FC = () => { const [editingCalendarId, setEditingCalendarId] = useState(); const editCalendarMutation = useEditCalendar(editingCalendarId ?? ''); - const [openCalendarModal, setOpenCalendarModal] = useState(false); + const [openCreateCalendar, setOpenCreateCalendar] = useState(false); + const [openEditCalendar, setOpenEditCalendar] = useState(false); const [editingCalendar, setEditingCalendar] = useState(null); if (shopsLoading || machinesLoading || calendarsLoading) return ; @@ -111,9 +113,7 @@ const AdminToolsScheduleConfig: React.FC = () => { + + +
+ + + Type + + Actions + + + + + {!eventTypes || eventTypes.length === 0 ? ( + + + No event types yet. + + + ) : ( + eventTypes.map((eventType) => ( + + {eventType.name} + + + + + { + setEditingEventType(eventType); + }} + > + + + + + + + + + + + + + + + + )) + )} + +
@@ -345,6 +419,14 @@ const AdminToolsScheduleConfig: React.FC = () => { dataType={`machine ${machineryToDelete?.machineName || ''}`} onFormSubmit={handleDeleteMachinery} /> + + {/* Create Event Type Modal */} + setOpenCreateEventType(false)} /> + + {/* Edit Event Type Modal */} + {editingEventType && ( + setEditingEventType(null)} eventType={editingEventType} /> + )}
); }; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/CreateEventModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/CreateEventModal.tsx new file mode 100644 index 0000000000..69f671200a --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/CreateEventModal.tsx @@ -0,0 +1,29 @@ +import ErrorPage from '../../../ErrorPage'; +import LoadingIndicator from '../../../../components/LoadingIndicator'; +import { useCreateEventType, EVENT_TYPE_KEY } from '../../../../hooks/calendar.hooks'; +import { useQueryClient } from 'react-query'; +import EventFormModal, { EventFormValues } from './EventFormModal'; + +interface CreateEventModalProps { + open: boolean; + onClose: () => void; +} + +const CreateEventModal = ({ open, onClose }: CreateEventModalProps) => { + const { isLoading, isError, error, mutateAsync: createEventType } = useCreateEventType(); + const queryClient = useQueryClient(); + + if (isError) return ; + if (isLoading) return ; + + const onSubmit = async (data: EventFormValues) => { + const result = await createEventType(data); + await queryClient.invalidateQueries(EVENT_TYPE_KEY); + await queryClient.refetchQueries(EVENT_TYPE_KEY); + return result; + }; + + return ; +}; + +export default CreateEventModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx new file mode 100644 index 0000000000..988071ae7f --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx @@ -0,0 +1,61 @@ +import ErrorPage from '../../../ErrorPage'; +import LoadingIndicator from '../../../../components/LoadingIndicator'; +import { useEditEventType, EVENT_TYPE_KEY } from '../../../../hooks/calendar.hooks'; +import { useQueryClient } from 'react-query'; +import { EventType } from 'shared'; +import EventFormModal, { EventFormValues } from './EventFormModal'; + +interface EditEventModalProps { + open: boolean; + onClose: () => void; + eventType: EventType; +} + +const EditEventModal = ({ open, onClose, eventType }: EditEventModalProps) => { + const queryClient = useQueryClient(); + + const { + isLoading: isEditing, + isError: isEditError, + error: editError, + mutateAsync: editEventType + } = useEditEventType(eventType.eventTypeId); + + const isLoading = isEditing; + const isError = isEditError; + const error = editError; + + const eventTypeData: EventFormValues = { + name: eventType.name, + initialDateScheduled: eventType.initialDateScheduled, + allDay: eventType.allDay, + recurring: eventType.recurring, + requiredMembers: eventType.requiredMembers, + optionalMembers: eventType.optionalMembers, + teams: eventType.teams, + location: eventType.location, + zoomLink: eventType.zoomLink, + shop: eventType.shop, + machinery: eventType.machinery, + workPackage: eventType.workPackage, + questionDocument: eventType.questionDocument || false, + documents: eventType.documents, + description: eventType.description, + onlyHeadsOrAbove: eventType.onlyHeadsOrAboveForEventCreation, + requiresConfirmation: false + }; + + if (isError) return ; + if (isLoading) return ; + + const onSubmit = async (data: EventFormValues) => { + const result = await editEventType(data); + await queryClient.invalidateQueries(EVENT_TYPE_KEY); + await queryClient.refetchQueries(EVENT_TYPE_KEY); + return result; + }; + + return ; +}; + +export default EditEventModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx new file mode 100644 index 0000000000..de84e5727b --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx @@ -0,0 +1,624 @@ +import { Box, FormHelperText, Typography, Checkbox } from '@mui/material'; +import NERFormModal from '../../../../components/NERFormModal'; +import ReactHookTextField from '../../../../components/ReactHookTextField'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { useForm, Controller } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import { useEffect, useMemo } from 'react'; +import { EventType } from 'shared'; +import useFormPersist from 'react-hook-form-persist'; +import { FormStorageKey } from '../../../../utils/form'; +import CalendarTodayIcon from '@mui/icons-material/CalendarToday'; +import AccessTimeIcon from '@mui/icons-material/AccessTime'; +import PeopleIcon from '@mui/icons-material/People'; +import LocationOnIcon from '@mui/icons-material/LocationOn'; +import VideocamIcon from '@mui/icons-material/Videocam'; +import BuildIcon from '@mui/icons-material/Build'; +import InventoryIcon from '@mui/icons-material/Inventory'; +import DescriptionIcon from '@mui/icons-material/Description'; +import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; + +export interface EventFormValues { + name: string; + initialDateScheduled: boolean; + allDay: boolean; + recurring: boolean; + requiredMembers: boolean; + optionalMembers: boolean; + teams: boolean; + location: boolean; + zoomLink: boolean; + shop: boolean; + machinery: boolean; + workPackage: boolean; + questionDocument: boolean; + documents: boolean; + description: boolean; + onlyHeadsOrAbove: boolean; + requiresConfirmation: boolean; +} + +const createSchema = yup.object({ + name: yup.string().required('Event Type name is required'), + initialDateScheduled: yup.boolean().required(), + allDay: yup.boolean().required(), + recurring: yup.boolean().required(), + requiredMembers: yup.boolean().required(), + optionalMembers: yup.boolean().required(), + teams: yup.boolean().required(), + location: yup.boolean().required(), + zoomLink: yup.boolean().required(), + shop: yup.boolean().required(), + machinery: yup.boolean().required(), + workPackage: yup.boolean().required(), + questionDocument: yup.boolean().required(), + documents: yup.boolean().required(), + description: yup.boolean().required(), + onlyHeadsOrAbove: yup.boolean().required(), + requiresConfirmation: yup.boolean().required() +}); + +const editSchema = yup.object({ + name: yup.string().required('Event Type name is required'), + initialDateScheduled: yup.boolean().required(), + allDay: yup.boolean().required(), + recurring: yup.boolean().required(), + requiredMembers: yup.boolean().required(), + optionalMembers: yup.boolean().required(), + teams: yup.boolean().required(), + location: yup.boolean().required(), + zoomLink: yup.boolean().required(), + shop: yup.boolean().required(), + machinery: yup.boolean().required(), + workPackage: yup.boolean().required(), + questionDocument: yup.boolean().required(), + documents: yup.boolean().required(), + description: yup.boolean().required(), + onlyHeadsOrAbove: yup.boolean().required(), + requiresConfirmation: yup.boolean().required() +}); + +interface EventFormModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: EventFormValues) => Promise; + initialValues?: EventFormValues; +} + +export const EventFormModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { + const toast = useToast(); + + const defaultValues: EventFormValues = useMemo( + () => ({ + name: '', + initialDateScheduled: true, + allDay: false, + recurring: false, + requiredMembers: false, + optionalMembers: true, + teams: false, + location: true, + zoomLink: true, + shop: false, + machinery: false, + workPackage: false, + questionDocument: false, + documents: false, + description: true, + onlyHeadsOrAbove: false, + requiresConfirmation: false + }), + [] + ); + + const { + handleSubmit, + control, + reset, + formState: { errors }, + watch, + setValue + } = useForm({ + resolver: yupResolver(initialValues ? editSchema : createSchema) as any, + defaultValues: initialValues || defaultValues + }); + + const formStorageKey = initialValues ? FormStorageKey.EDIT_EVENT_TYPE : FormStorageKey.CREATE_EVENT_TYPE; + + useFormPersist(formStorageKey, { + watch, + setValue + }); + + useEffect(() => { + if (initialValues) { + reset(initialValues); + } + }, [initialValues, reset]); + + const onFormSubmit = async (data: EventFormValues) => { + try { + await onSubmit(data); + onClose(); + if (!initialValues) { + reset(defaultValues); + } + } catch (e: unknown) { + if (e instanceof Error) { + toast.error(e.message); + } else { + toast.error('An error occurred while saving the event type'); + } + } + }; + + const handleCancel = () => { + reset(defaultValues); + sessionStorage.removeItem(formStorageKey); + onClose(); + }; + + return ( + reset(initialValues || defaultValues)} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId={initialValues ? 'edit-event-form' : 'create-event-form'} + showCloseButton + > + + {/* Add New Event Type Input */} + + + + + {errors.name?.message} + + + {/* Calendar Display (visual only) */} + + + + + Calendar + + + + + + + Select the fields from this template to be included in the new event type. + + + ( + + )} + /> + + + + Monday, March 17 2:00pm - 3:00pm + + + + + All Day + + + + Recurring + + + + + + {/* Members Field */} + + ( + + )} + /> + + + + + + Ethan Herrell + + × + + {/* Add Member button (visual only) */} + + + Add Member + + + + + + + {/* Location Field */} + + ( + + )} + /> + + + + Location + + + + + {/* Zoom Link Field */} + + ( + + )} + /> + + + + Zoom Link + + + + + {/* Availability Field */} + + ( + + )} + /> + + + + + + Add Availability + + + {/* View Availability button (visual only) */} + + + View Availability + + + + + + + {/* Shop Field */} + + ( + + )} + /> + + + + Select Shop + + + + + + {/* Machinery Field */} + + ( + + )} + /> + + + + Select Machinery + + + + + + {/* Work Package Field */} + + ( + + )} + /> + + + + Select Work Package + + + + + + {/* Documents Field */} + + ( + + )} + /> + + + + Documents + + + + + Competitions.pdf + + × + + + + Upload + + + + + + + {/* Description/Attachment Field */} + + ( + + )} + /> + + + + Add a description or attachment + + + + + + ); +}; + +export default EventFormModal; diff --git a/src/frontend/src/utils/form.ts b/src/frontend/src/utils/form.ts index 09be05e2d0..c67bd0e739 100644 --- a/src/frontend/src/utils/form.ts +++ b/src/frontend/src/utils/form.ts @@ -84,5 +84,7 @@ export enum FormStorageKey { CREATE_FAQ = 'CREATE_FAQ', EDIT_FAQ = 'EDIT_FAQ', CREATE_MACHINERY = 'CREATE_MACHINERY', - EDIT_MACHINERY = 'EDIT_MACHINERY' + EDIT_MACHINERY = 'EDIT_MACHINERY', + CREATE_EVENT_TYPE = 'CREATE_EVENT_TYPE', + EDIT_EVENT_TYPE = 'EDIT_EVENT_TYPE' } diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 22b4b892cb..b25c48e275 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -446,6 +446,10 @@ const calendarDeleteMachinery = (machineryId: string) => `${calendar()}/machiner const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; const calendarEditShop = (shopId: string) => `${calendar()}/shop/${shopId}/edit`; const calendarDeleteShop = (shopId: string) => `${calendar()}/shop/${shopId}/delete`; +const calendarEventTypes = () => `${calendar()}/event-types`; +const calendarCreateEventType = () => `${calendar()}/event-type/create`; +const calendarEditEventType = (eventTypeId: string) => `${calendar()}/event-type/${eventTypeId}/edit`; +const calendarCalendars = () => `${calendar()}/calendars`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -757,6 +761,10 @@ export const apiUrls = { calendarAddMachineryToShop, calendarEditShop, calendarDeleteShop, + calendarEventTypes, + calendarCreateEventType, + calendarEditEventType, + calendarCalendars, version }; From 4d3a7a9f5390d22a6471f516820f706ba9f6025d Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 22 Nov 2025 16:56:29 -0500 Subject: [PATCH 235/477] #3636 Fixed the calenderId assignment to event types --- .../src/controllers/calendar.controllers.ts | 15 +++ .../event-type.query-args.ts | 7 +- src/backend/src/prisma/seed.ts | 4 +- src/backend/src/routes/calendar.routes.ts | 6 ++ src/backend/src/services/calendar.services.ts | 95 ++++++++++++++++++- .../src/transformers/calendar.transformer.ts | 1 + src/backend/tests/unit/calendar.test.ts | 15 ++- src/frontend/src/apis/calendar.api.ts | 2 + src/frontend/src/hooks/calendar.hooks.ts | 4 +- .../ScheduleConfig/Event/EditEventModal.tsx | 1 + .../ScheduleConfig/Event/EventFormModal.tsx | 5 + src/shared/src/types/calendar-types.ts | 1 + 12 files changed, 149 insertions(+), 7 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index cf145d0211..f79da113c2 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -7,6 +7,7 @@ export default class CalendarController { try { const { name, + calendarIds, initialDateScheduled, recurring, allDay, @@ -28,6 +29,7 @@ export default class CalendarController { const eventType = await CalendarService.createEventType( req.currentUser, name, + calendarIds, req.organization, initialDateScheduled, recurring, @@ -191,6 +193,7 @@ export default class CalendarController { const { eventTypeId } = req.params; const { name, + calendarIds, initialDateScheduled, recurring, allDay, @@ -212,6 +215,7 @@ export default class CalendarController { const eventType = await CalendarService.editEventType( eventTypeId, req.currentUser, + calendarIds, req.organization, name, initialDateScheduled, @@ -237,6 +241,17 @@ export default class CalendarController { } } + static async deleteEventType(req: Request, res: Response, next: NextFunction) { + try { + const { eventTypeId } = req.params; + + const eventType = await CalendarService.deleteEventType(req.currentUser, eventTypeId, req.organization); + res.status(200).json(eventType); + } catch (error: unknown) { + next(error); + } + } + static async deleteShop(req: Request, res: Response, next: NextFunction) { try { const { shopId } = req.params; diff --git a/src/backend/src/prisma-query-args/event-type.query-args.ts b/src/backend/src/prisma-query-args/event-type.query-args.ts index 90fab92369..9aa8ec2e29 100644 --- a/src/backend/src/prisma-query-args/event-type.query-args.ts +++ b/src/backend/src/prisma-query-args/event-type.query-args.ts @@ -6,6 +6,11 @@ export type EventTypeQueryArgs = ReturnType; export const getEventTypeQueryArgs = (organizationId: string) => Prisma.validator()({ include: { - userCreated: getUserQueryArgs(organizationId) + userCreated: getUserQueryArgs(organizationId), + calendars: { + select: { + calendarId: true + } + } } }); diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 25c70e7130..e90bfed0d3 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3220,7 +3220,7 @@ const performSeed: () => Promise = async () => { const manufacturingEventType = await CalendarService.createEventType( thomasEmrax, 'Manufacturing', - [], + [calendar.calendarId], ner, true, false, @@ -3244,7 +3244,7 @@ const performSeed: () => Promise = async () => { const bayTimeEventType = await CalendarService.createEventType( thomasEmrax, 'Bay Time', - [], + [calendar.calendarId], ner, true, true, diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 7eb1c94c20..d7c4d293a2 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -17,6 +17,8 @@ calendarRouter.post( calendarRouter.post( '/event-type/create', nonEmptyString(body('name')), + body('calendarIds').isArray(), + body('calendarIds.*').isString(), body('initialDateScheduled').isBoolean(), body('allDay').isBoolean(), body('recurring').isBoolean(), @@ -40,6 +42,8 @@ calendarRouter.post( calendarRouter.post( '/event-type/:eventTypeId/edit', nonEmptyString(body('name')), + body('calendarIds').isArray(), + body('calendarIds.*').isString(), body('initialDateScheduled').isBoolean(), body('allDay').isBoolean(), body('recurring').isBoolean(), @@ -60,6 +64,8 @@ calendarRouter.post( CalendarController.editEventType ); +calendarRouter.post('/event-type/:eventTypeId/delete', validateInputs, CalendarController.deleteEventType); + calendarRouter.post( '/event/create', nonEmptyString(body('title')), diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index f650e4863a..43dd94e2bd 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -52,6 +52,7 @@ export default class CalendarService { * * @param submitter The user submitting the request, who must be an admin. * @param name The name of the event type. + * @param calendarIds An array of the calendars this event type is associated with. * @param organization The organization for which the event type is being created. * @param initialDateScheduled Determines if a date is associated with this event type. * @param recurring Determines if this event type is recurring. @@ -72,10 +73,13 @@ export default class CalendarService { * @returns The created event type. * * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + * @throws NotFoundException If the given calendarIds are not found. + * @throws InvalidOrganizationException If the given calendarIds are not part of the same organization. */ static async createEventType( submitter: User, name: string, + calendarIds: string[], organization: Organization, initialDateScheduled: boolean, recurring: boolean, @@ -98,6 +102,27 @@ export default class CalendarService { throw new AccessDeniedAdminOnlyException('create event type'); } + // Check if calendars with ids exist and belong to the same organization + const existingCalendars = await prisma.calendar.findMany({ + where: { + calendarId: { in: calendarIds } + } + }); + + // Ensure all provided calendars exist + if (existingCalendars.length !== calendarIds.length) { + const foundIds = existingCalendars.map((c) => c.calendarId); + const missingIds = calendarIds.filter((id) => !foundIds.includes(id)); + throw new NotFoundException('Calendar', missingIds.join(', ')); + } + + // Ensure all calendars belong to the given organization + for (const calendar of existingCalendars) { + if (calendar.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Calendar'); + } + } + const duplicate = await prisma.event_Type.findFirst({ where: { organizationId: organization.organizationId, @@ -112,6 +137,9 @@ export default class CalendarService { const newEventType = await prisma.event_Type.create({ data: { name, + calendars: { + connect: calendarIds.map((calendarId) => ({ calendarId })) + }, userCreatedId: submitter.userId, initialDateScheduled, recurring, @@ -1598,8 +1626,9 @@ export default class CalendarService { * * @param eventTypeId The id of the event type of be edited * @param submitter The user submitting the request, who must be an admin. - * @param name The name of the event type. + * @param calendarIds An array of the calendars this event type is associated with. * @param organization The organization for which the event type is being created. + * @param name The name of the event type. * @param initialDateScheduled Determines if a date is associated with this event type. * @param recurring Determines if this event type is recurring. * @param allDay Determines if this event type is all day. @@ -1619,10 +1648,13 @@ export default class CalendarService { * @returns The created event type. * * @throws AccessDeniedAdminOnlyException If the submitter is not an admin. + * @throws NotFoundException If the given calendarIds are not found. + * @throws InvalidOrganizationException If the given calendarIds are not part of the same organization. */ static async editEventType( eventTypeId: string, submitter: User, + calendarIds: string[], organization: Organization, name: string, initialDateScheduled: boolean, @@ -1646,6 +1678,27 @@ export default class CalendarService { throw new AccessDeniedAdminOnlyException('edit event type'); } + // Check if calendars with ids exist and belong to the same organization + const existingCalendars = await prisma.calendar.findMany({ + where: { + calendarId: { in: calendarIds } + } + }); + + // Ensure all provided calendars exist + if (existingCalendars.length !== calendarIds.length) { + const foundIds = existingCalendars.map((c) => c.calendarId); + const missingIds = calendarIds.filter((id) => !foundIds.includes(id)); + throw new NotFoundException('Calendar', missingIds.join(', ')); + } + + // Ensure all calendars belong to the given organization + for (const calendar of existingCalendars) { + if (calendar.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Calendar'); + } + } + // Ensure event type to edit exists const oldEventType = await prisma.event_Type.findUnique({ where: { @@ -1661,6 +1714,9 @@ export default class CalendarService { where: { eventTypeId: oldEventType.eventTypeId }, data: { name, + calendars: { + set: calendarIds.map((calendarId) => ({ calendarId })) + }, initialDateScheduled, recurring, allDay, @@ -1684,6 +1740,43 @@ export default class CalendarService { return eventTypeTransformer(updatedEventType); } + /** + * Deletes an event type by its ID. + * Requires the submitter to be an admin. + * @param submitter The user submitting the request. + * @param eventTypeId The ID of the event type to be deleted. + * @param organization The organization to which the event type belongs. + * @returns The deleted event type object. + * @throws AccessDeniedException If the submitter is not an admin. + * @throws NotFoundException If the event type with the given ID does not exist. + * @throws DeletedException If the event type is already deleted. + * @throws InvalidOrganizationException If the event type does not belong to the given organization. + */ + static async deleteEventType(submitter: User, eventTypeId: string, organization: Organization): Promise { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedException('Only admins can delete event types!'); + } + + const eventType = await prisma.event_Type.findUnique({ + where: { eventTypeId } + }); + + if (!eventType) throw new NotFoundException('Event Type', eventTypeId); + if (eventType.dateDeleted) throw new DeletedException('Event Type', eventTypeId); + + if (eventType.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Event Type'); + } + + const deletedEventType = await prisma.event_Type.update({ + where: { eventTypeId }, + data: { dateDeleted: new Date(), userDeletedId: submitter.userId }, + ...getEventTypeQueryArgs(organization.organizationId) + }); + + return eventTypeTransformer(deletedEventType); + } + /** * Deletes a shop by its ID. * Requires the submitter to be head or above. diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index b5e27875f3..07e4f73fdb 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -44,6 +44,7 @@ export const eventTypeTransformer = (eventType: Prisma.Event_TypeGetPayload c.calendarId) || [], initialDateScheduled: eventType.initialDateScheduled, allDay: eventType.allDay, recurring: eventType.recurring, diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index c055ef8879..c39e0dc974 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -268,7 +268,7 @@ describe('Calendar Tests', () => { const result = await CalendarService.createEventType( await createTestUser(supermanAdmin, orgId), 'Meeting', - [], + [calendar.calendarId], organization, true, false, @@ -2083,10 +2083,21 @@ describe('Calendar Tests', () => { }); const AdminInOtherOrg = await createTestUser(alfred, otherOrg.organizationId); + const otherOrgCalendar = await prisma.calendar.create({ + data: { + name: 'Other Org Calendar', + description: 'Calendar for other org', + colorHexCode: '#ff0000', + userCreated: { connect: { userId: AdminInOtherOrg.userId } }, + dateCreated: new Date(), + organization: { connect: { organizationId: otherOrg.organizationId } } + } + }); + const otherOrgEventType = await CalendarService.createEventType( AdminInOtherOrg, 'Other Org Event Type', - [], + [otherOrgCalendar.calendarId], otherOrg, true, false, diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 699c25fdc8..e4907ad863 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -85,6 +85,7 @@ export const getAllEventTypes = () => { export const postCreateEventType = (payload: { name: string; + calendarIds: string[]; initialDateScheduled: boolean; allDay: boolean; recurring: boolean; @@ -111,6 +112,7 @@ export const postEditEventType = ( eventTypeId: string, payload: { name: string; + calendarIds: string[]; initialDateScheduled: boolean; allDay: boolean; recurring: boolean; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index f343db3c43..b1c44928bd 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,5 +1,5 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop, Machinery, Event, EventType, Calendar } from 'shared'; +import { Shop, Machinery, EventType, Calendar } from 'shared'; import { getAllShops, postCreateShop, @@ -158,6 +158,7 @@ export const useCreateEventType = () => { Error, { name: string; + calendarIds: string[]; initialDateScheduled: boolean; allDay: boolean; recurring: boolean; @@ -195,6 +196,7 @@ export const useEditEventType = (eventTypeId: string) => { Error, { name: string; + calendarIds: string[]; initialDateScheduled: boolean; allDay: boolean; recurring: boolean; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx index 988071ae7f..dbc75d3374 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx @@ -27,6 +27,7 @@ const EditEventModal = ({ open, onClose, eventType }: EditEventModalProps) => { const eventTypeData: EventFormValues = { name: eventType.name, + calendarIds: eventType.calendarIds || [], initialDateScheduled: eventType.initialDateScheduled, allDay: eventType.allDay, recurring: eventType.recurring, diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx index de84e5727b..592428dbd1 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx @@ -21,6 +21,7 @@ import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; export interface EventFormValues { name: string; + calendarIds: string[]; initialDateScheduled: boolean; allDay: boolean; recurring: boolean; @@ -41,6 +42,7 @@ export interface EventFormValues { const createSchema = yup.object({ name: yup.string().required('Event Type name is required'), + calendarIds: yup.array().of(yup.string()).required(), initialDateScheduled: yup.boolean().required(), allDay: yup.boolean().required(), recurring: yup.boolean().required(), @@ -61,6 +63,7 @@ const createSchema = yup.object({ const editSchema = yup.object({ name: yup.string().required('Event Type name is required'), + calendarIds: yup.array().of(yup.string()).required(), initialDateScheduled: yup.boolean().required(), allDay: yup.boolean().required(), recurring: yup.boolean().required(), @@ -92,6 +95,7 @@ export const EventFormModal: React.FC = ({ open, onClose, o const defaultValues: EventFormValues = useMemo( () => ({ name: '', + calendarIds: [], initialDateScheduled: true, allDay: false, recurring: false, @@ -179,6 +183,7 @@ export const EventFormModal: React.FC = ({ open, onClose, o mb: 1 }} > + <>} /> Date: Sat, 22 Nov 2025 17:13:02 -0500 Subject: [PATCH 236/477] #3636 Fix missing state variables and imports in AdminToolsScheduleConfig --- .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 132770a46a..852847c0da 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -13,7 +13,8 @@ import { useDeleteShop, useAllCalendars, useCreateCalendar, - useEditCalendar + useEditCalendar, + useAllEventTypes } from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; import CreateCalendarModal from './Calendar/CreateCalendarModal'; @@ -22,13 +23,9 @@ import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; -<<<<<<< HEAD import CreateEventModal from './Event/CreateEventModal'; import EditEventModal from './Event/EditEventModal'; -import { Shop, EventType } from 'shared'; -======= -import { Calendar, Shop } from 'shared'; ->>>>>>> 5f45f9f7d27aa9f3e48ad53c82abb5d4a17a5a54 +import { Shop, EventType, Calendar } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import NERDeleteModal from '../../../components/NERDeleteModal'; @@ -106,10 +103,14 @@ const AdminToolsScheduleConfig: React.FC = () => { const [openEditCalendar, setOpenEditCalendar] = useState(false); const [editingCalendar, setEditingCalendar] = useState(); - if (shopsLoading || machinesLoading || calendarsLoading) return ; + const [openCreateEventType, setOpenCreateEventType] = useState(false); + const [editingEventType, setEditingEventType] = useState(null); + + if (shopsLoading || machinesLoading || calendarsLoading || eventTypesLoading) return ; if (shopsError) return ; if (machinesError) return ; if (calendarsError) return ; + if (eventTypesError) return ; return ( From e324b6f9b43373034674b2d62c64d9b4b8bb13a5 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 22 Nov 2025 17:17:18 -0500 Subject: [PATCH 237/477] #3636 missing files for calendar added --- .../ScheduleConfig/Calendar/CalendarModal.tsx | 161 ++++++++++++++++++ .../Calendar/CreateCalendarModal.tsx | 13 ++ .../Calendar/EditCalendarModal.tsx | 14 ++ 3 files changed, 188 insertions(+) create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendarModal.tsx diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx new file mode 100644 index 0000000000..a1a8079b45 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CalendarModal.tsx @@ -0,0 +1,161 @@ +import React from 'react'; +import { Box, FormControl, FormHelperText, Typography, Stack } from '@mui/material'; +import NERFormModal from '../../../../components/NERFormModal'; +import ReactHookTextField from '../../../../components/ReactHookTextField'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { useForm } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import type { Calendar } from 'shared'; + +export interface CalendarFormValues { + name: string; + description: string; + colorHexCode: string; +} + +const schema = yup.object({ + name: yup.string().required('Calendar Name is required'), + description: yup.string().required('Description is required'), + colorHexCode: yup.string().required('Color is required') +}); + +export interface BaseCalendarModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: CalendarFormValues) => Promise | Calendar | unknown; + initialValues?: Partial; +} + +const COLOR_OPTIONS: { label: string; value: string }[] = [ + { label: 'Red', value: '#EF4444' }, + { label: 'Orange', value: '#F97316' }, + { label: 'Green', value: '#22C55E' }, + { label: 'Blue', value: '#3B82F6' }, + { label: 'Purple', value: '#A855F7' }, + { label: 'Navy', value: '#1E3A8A' } +]; + +const CalendarModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { + const toast = useToast(); + + const { + handleSubmit, + control, + reset, + watch, + setValue, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { name: '', description: '', colorHexCode: '' } + }); + + const frozenValuesRef = React.useRef({ name: '', description: '', colorHexCode: '' }); + + React.useEffect(() => { + if (open) { + frozenValuesRef.current = { + name: initialValues?.name ?? '', + description: initialValues?.description ?? '', + colorHexCode: initialValues?.colorHexCode ?? '' + }; + reset(frozenValuesRef.current); + } else { + frozenValuesRef.current = { name: '', description: '', colorHexCode: '' }; + reset(frozenValuesRef.current); + } + }, [open, initialValues, reset]); + + const computedTitle = frozenValuesRef.current.name !== '' ? 'Edit Calendar' : 'Create Calendar'; + + const onFormSubmit = async (data: CalendarFormValues) => { + try { + await onSubmit(data); + onClose(); + reset({ name: '', description: '', colorHexCode: '' }); + } catch (e: unknown) { + if (e instanceof Error) toast.error(e.message); + } + }; + + const selectedColor = watch('colorHexCode'); + + const handleColorClick = (value: string) => { + setValue('colorHexCode', value, { shouldValidate: true }); + }; + + return ( + { + onClose(); + reset({ name: '', description: '', colorHexCode: '' }); + }} + title={computedTitle} + reset={() => reset({ name: '', description: '', colorHexCode: '' })} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="calendar-form" + showCloseButton + > + + + + Calendar:* + + + {errors.name?.message} + + + + + Description:* + + + {errors.description?.message} + + + + + Color:* + + + {COLOR_OPTIONS.map((c) => { + const isSelected = c.value === selectedColor; + return ( + handleColorClick(c.value)} + sx={{ + cursor: 'pointer', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + px: 1.5, + height: 28, + borderRadius: '999px', + backgroundColor: c.value, + border: isSelected ? '2px solid #ef4345' : '2px solid transparent', + boxSizing: 'border-box', + minWidth: 32 + }} + /> + ); + })} + + {errors.colorHexCode?.message} + + + + ); +}; + +export default CalendarModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx new file mode 100644 index 0000000000..24851249c1 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/CreateCalendarModal.tsx @@ -0,0 +1,13 @@ +import CalendarModal, { CalendarFormValues } from './CalendarModal'; + +interface CreateCalendarModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: CalendarFormValues) => Promise | unknown; +} + +const CreateCalendarModal: React.FC = (props) => { + return ; +}; + +export default CreateCalendarModal; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendarModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendarModal.tsx new file mode 100644 index 0000000000..902945f4d4 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Calendar/EditCalendarModal.tsx @@ -0,0 +1,14 @@ +import CalendarModal, { CalendarFormValues } from './CalendarModal'; + +export interface EditCalendarModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: CalendarFormValues) => Promise | unknown; + initialValues: Partial; +} + +const EditCalendarModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { + return ; +}; + +export default EditCalendarModal; From 9beab690e3e2f053a7488bdc382065dd39cd2d2e Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 22 Nov 2025 17:23:39 -0500 Subject: [PATCH 238/477] #3636 Revert unrelated changes from main branch --- .../src/controllers/projects.controllers.ts | 5 +- .../reimbursement-requests.controllers.ts | 19 + src/backend/src/routes/projects.routes.ts | 1 + .../routes/reimbursement-requests.routes.ts | 7 +- .../src/services/change-requests.services.ts | 8 +- src/backend/src/services/finance.services.ts | 21 +- src/backend/src/services/projects.services.ts | 19 +- .../reimbursement-requests.services.ts | 36 ++ src/backend/src/services/tasks.services.ts | 7 +- .../unmocked/reimbursement-requests.test.ts | 86 +++- src/frontend/src/apis/finance.api.ts | 10 + .../src/components/SponsorTierPill.tsx | 13 +- src/frontend/src/components/TimeSlot.tsx | 10 +- src/frontend/src/hooks/finance.hooks.ts | 28 +- .../AdminToolsAttendeeDesignReviewInfo.tsx | 4 +- .../AdminToolsPage/AdminToolsSlackIds.tsx | 4 +- .../BOMConfig/ManufacturerTable.tsx | 4 +- .../BOMConfig/MaterialTypeTable.tsx | 4 +- .../AdminToolsPage/BOMConfig/UnitTable.tsx | 4 +- .../FinanceConfig/IndexCodesTable.tsx | 4 +- .../FinanceConfig/SponsorTierTable.tsx | 4 +- .../ProjectsConfig/AbbreviationsTable.tsx | 4 +- .../ProjectsConfig/CarsTable.tsx | 7 +- .../DescriptionBulletTypeTable.tsx | 4 +- .../LinkTypes/LinkTypeFormModal.tsx | 5 +- .../LinkTypes/LinkTypeTable.tsx | 4 +- .../ProjectsConfig/PartTagsTable.tsx | 4 +- .../ProjectsConfig/ProjectTemplateTable.tsx | 4 +- .../WorkPackageTemplateTable.tsx | 4 +- .../ApplicationLinkTable.tsx | 4 +- .../TeamConfig/TeamTypeTable.tsx | 4 +- .../AdminToolsPage/TeamConfig/TeamsTools.tsx | 4 +- .../src/pages/CreditsPage/CreditsPage.tsx | 34 +- .../FinanceComponents/EditSponsorPage.tsx | 4 +- .../ReimbursementRequestInfo.tsx | 11 +- .../FinanceComponents/VendorFormModal.tsx | 10 +- .../AddSABONumberModal.tsx | 9 +- .../ReimbursementRequestDetailsView.tsx | 6 +- .../src/pages/FinancePage/SponsorsTable.tsx | 465 ++++++------------ .../FinancePage/VendorsAndSponsorsPage.tsx | 2 +- .../src/pages/FinancePage/VendorsTable.tsx | 462 +++++------------ .../Availability/AvailabilityEditModal.tsx | 9 +- .../Availability/EditAvailability.tsx | 24 +- .../UserScheduleSettingsView.tsx | 4 +- src/frontend/src/utils/diff-page.utils.ts | 22 +- src/frontend/src/utils/pipes.ts | 11 + 46 files changed, 660 insertions(+), 759 deletions(-) diff --git a/src/backend/src/controllers/projects.controllers.ts b/src/backend/src/controllers/projects.controllers.ts index b896261805..b8361feba6 100644 --- a/src/backend/src/controllers/projects.controllers.ts +++ b/src/backend/src/controllers/projects.controllers.ts @@ -437,13 +437,14 @@ export default class ProjectsController { static async editLinkType(req: Request, res: Response, next: NextFunction) { try { const { linkTypeName } = req.params; - const { iconName, required } = req.body; + const { name: newName, iconName, required } = req.body; const linkTypeUpdated = await ProjectsService.editLinkType( linkTypeName, iconName, required, req.currentUser, - req.organization + req.organization, + newName ); res.status(200).json(linkTypeUpdated); } catch (error: unknown) { diff --git a/src/backend/src/controllers/reimbursement-requests.controllers.ts b/src/backend/src/controllers/reimbursement-requests.controllers.ts index 2ad92f093a..7ca13b0d9b 100644 --- a/src/backend/src/controllers/reimbursement-requests.controllers.ts +++ b/src/backend/src/controllers/reimbursement-requests.controllers.ts @@ -497,6 +497,25 @@ export default class ReimbursementRequestsController { } } + static async setVendorTaxExemptStatus(req: Request, res: Response, next: NextFunction) { + try { + const { vendorId } = req.params; + + const { taxExempt } = req.body; + + const updatedVendor = await ReimbursementRequestService.setVendorTaxExemptStatus( + vendorId, + taxExempt, + req.currentUser, + req.organization + ); + + res.status(200).json(updatedVendor); + } catch (error) { + next(error); + } + } + static async deleteVendor(req: Request, res: Response, next: NextFunction) { try { const { vendorId } = req.params; diff --git a/src/backend/src/routes/projects.routes.ts b/src/backend/src/routes/projects.routes.ts index c822930b37..44d236f32b 100644 --- a/src/backend/src/routes/projects.routes.ts +++ b/src/backend/src/routes/projects.routes.ts @@ -29,6 +29,7 @@ projectRouter.post( ); projectRouter.post( '/link-types/:linkTypeName/edit', + nonEmptyString(body('name').optional()), nonEmptyString(body('iconName')), body('required').isBoolean(), validateInputs, diff --git a/src/backend/src/routes/reimbursement-requests.routes.ts b/src/backend/src/routes/reimbursement-requests.routes.ts index 8412de2094..4a6edcf632 100644 --- a/src/backend/src/routes/reimbursement-requests.routes.ts +++ b/src/backend/src/routes/reimbursement-requests.routes.ts @@ -101,6 +101,11 @@ reimbursementRequestsRouter.post( ReimbursementRequestController.editVendor ); +reimbursementRequestsRouter.post( + '/vendors/:vendorId/setTaxExemptStatus', + ReimbursementRequestController.setVendorTaxExemptStatus +); + reimbursementRequestsRouter.post('/:vendorId/vendors/delete', ReimbursementRequestController.deleteVendor); reimbursementRequestsRouter.post( @@ -167,7 +172,7 @@ reimbursementRequestsRouter.post( body('taxExempt').optional().isBoolean(), body('twoFactorContacts').optional().isArray(), nonEmptyString(body('twoFactorContacts.*')), - nonEmptyString(body('notes')).optional(), + body('notes').optional().isString(), validateInputs, ReimbursementRequestController.createVendor ); diff --git a/src/backend/src/services/change-requests.services.ts b/src/backend/src/services/change-requests.services.ts index ab6a9d1824..17daf2925b 100644 --- a/src/backend/src/services/change-requests.services.ts +++ b/src/backend/src/services/change-requests.services.ts @@ -1141,6 +1141,8 @@ export default class ChangeRequestsService { } } + const isCreatingNewProject = projectProposedChanges && projectNumber === 0; + const changes = await prisma.wbs_Proposed_Changes.create({ data: { scopeChangeRequest: { @@ -1149,7 +1151,7 @@ export default class ChangeRequestsService { } }, name, - status: WBS_Element_Status.ACTIVE, + status: isCreatingNewProject ? WBS_Element_Status.INACTIVE : wbsElement.status, links: { create: validationResult.links.map((linkInfo) => ({ url: linkInfo.url, @@ -1232,11 +1234,13 @@ export default class ChangeRequestsService { managerId ); + const isCreatingNewWorkPackage = workPackageProposedChanges && workPackageNumber === 0; + const changes = await prisma.wbs_Proposed_Changes.create({ data: { scopeChangeRequest: { connect: { scopeCrId: createdCR.scopeChangeRequest!.scopeCrId } }, name, - status: WBS_Element_Status.INACTIVE, + status: isCreatingNewWorkPackage ? WBS_Element_Status.INACTIVE : wbsElement.status, proposedDescriptionBulletChanges: { create: validationResult.descriptionBullets.map((bullet) => ({ detail: bullet.detail, diff --git a/src/backend/src/services/finance.services.ts b/src/backend/src/services/finance.services.ts index 4fc5ab99b9..93c5b3a1ac 100644 --- a/src/backend/src/services/finance.services.ts +++ b/src/backend/src/services/finance.services.ts @@ -1096,15 +1096,20 @@ export default class FinanceServices { if (!tier) throw new NotFoundException('Sponsor Tier', sponsorTierId); - const existingSponsor = await prisma.sponsor.findFirst({ - where: { - name, - organizationId: organization.organizationId - } - }); + if (name !== oldSponsor.name) { + const existingSponsor = await prisma.sponsor.findFirst({ + where: { + name: { + equals: name, + mode: 'insensitive' + }, + organizationId: organization.organizationId + } + }); - if (existingSponsor) { - throw new HttpException(400, `A sponsor with the name "${name}" already exists.`); + if (existingSponsor) { + throw new HttpException(400, `A sponsor with the name "${name}" already exists.`); + } } const updatedSponsor = await prisma.sponsor.update({ diff --git a/src/backend/src/services/projects.services.ts b/src/backend/src/services/projects.services.ts index f0071fec50..e6eeceae2d 100644 --- a/src/backend/src/services/projects.services.ts +++ b/src/backend/src/services/projects.services.ts @@ -621,7 +621,8 @@ export default class ProjectsService { iconName: string, required: boolean, submitter: User, - organization: Organization + organization: Organization, + newName?: string ): Promise { if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) throw new AccessDeniedException('Only an admin can update the linkType'); @@ -638,11 +639,25 @@ export default class ProjectsService { if (!linkType) throw new NotFoundException('Link Type', linkName); + // If attempting to rename, ensure new name does not conflict with an existing LinkType + if (newName && newName !== linkName) { + const existingWithNewName = await prisma.link_Type.findUnique({ + where: { + uniqueLinkType: { + name: newName, + organizationId: organization.organizationId + } + } + }); + + if (existingWithNewName) throw new HttpException(400, 'LinkType with that name already exists in this organization.'); + } + // update the LinkType const linkTypeUpdated = await prisma.link_Type.update({ where: { id: linkType.id }, data: { - name: linkName, + name: newName && newName ? newName : linkName, iconName, required } diff --git a/src/backend/src/services/reimbursement-requests.services.ts b/src/backend/src/services/reimbursement-requests.services.ts index 9f9f38a4a6..b9bf5286ee 100644 --- a/src/backend/src/services/reimbursement-requests.services.ts +++ b/src/backend/src/services/reimbursement-requests.services.ts @@ -1544,6 +1544,42 @@ export default class ReimbursementRequestService { return vendorTransformer(vendor); } + static async setVendorTaxExemptStatus( + vendorId: string, + taxExempt: boolean, + submitter: User, + organization: Organization + ): Promise { + const existingVendor = await prisma.vendor.findUnique({ + where: { vendorId, dateDeleted: null }, + include: { twoFactorContacts: { select: { userId: true } } } + }); + + if (!existingVendor) { + throw new NotFoundException('Vendor', vendorId); + } + + if (existingVendor.organizationId !== organization.organizationId) { + throw new InvalidOrganizationException('Vendor'); + } + + const isUserAuthorized = + existingVendor.addedByUserId === submitter.userId || + (await isUserOnFinanceTeam(submitter, organization.organizationId)) || + (await userHasPermission(submitter.userId, organization.organizationId, isHead)); + if (!isUserAuthorized) { + throw new AccessDeniedException(`You are not a member of the finance team!`); + } + + const updatedVendor = await prisma.vendor.update({ + where: { vendorId }, + data: { taxExempt }, + ...getVendorQueryArgs(organization.organizationId) + }); + + return vendorTransformer(updatedVendor); + } + /** * Deletes the vendor * diff --git a/src/backend/src/services/tasks.services.ts b/src/backend/src/services/tasks.services.ts index 7d1eee018c..f826b24392 100644 --- a/src/backend/src/services/tasks.services.ts +++ b/src/backend/src/services/tasks.services.ts @@ -266,8 +266,11 @@ export default class TasksService { // this checks the current users permissions const isLead = wbsElement.leadId === currentUser.userId || wbsElement.managerId === currentUser.userId; - if (!(await userHasPermission(currentUser.userId, organization.organizationId, isAdmin)) && !isLead) { - throw new AccessDeniedException('Only admin, app-admins, project leads, and project managers can delete tasks'); + const isCreator = task.createdByUserId === currentUser.userId; + if (!(await userHasPermission(currentUser.userId, organization.organizationId, isAdmin)) && !isLead && !isCreator) { + throw new AccessDeniedException( + 'Only admin, app-admins, project leads, project managers, and the task creator can delete tasks' + ); } const deletedTask = await prisma.task.update({ diff --git a/src/backend/tests/unmocked/reimbursement-requests.test.ts b/src/backend/tests/unmocked/reimbursement-requests.test.ts index 39b1db4373..342d44389e 100644 --- a/src/backend/tests/unmocked/reimbursement-requests.test.ts +++ b/src/backend/tests/unmocked/reimbursement-requests.test.ts @@ -1,6 +1,12 @@ import { alfred, robinMember, cyborgMember, theVisitorGuest } from '../test-data/users.test-data'; import ReimbursementRequestService from '../../src/services/reimbursement-requests.services'; -import { AccessDeniedException, DeletedException, HttpException, NotFoundException } from '../../src/utils/errors.utils'; +import { + AccessDeniedException, + DeletedException, + HttpException, + InvalidOrganizationException, + NotFoundException +} from '../../src/utils/errors.utils'; import { createTestReimbursementRequest, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; import { addDaysToDate, IndexCode, ReimbursementRequest, ReimbursementStatusType, AccountCode } from 'shared'; @@ -1041,4 +1047,82 @@ describe('Reimbursement Requests', () => { expect(assignedRRs).toEqual([]); }); }); + + describe('Set vendor tax exempt status', () => { + test('Finance member can set vendor tax exempt status', async () => { + const updatedVendor = await ReimbursementRequestService.setVendorTaxExemptStatus( + createdVendor.vendorId, + true, + financeMember, + org + ); + + expect(updatedVendor).not.toBeNull(); + expect(updatedVendor.taxExempt).toBe(true); + }); + + test('Non-finance member cannot set vendor tax exempt status', async () => { + await expect( + ReimbursementRequestService.setVendorTaxExemptStatus(createdVendor.vendorId, true, regularMember, org) + ).rejects.toThrow(new AccessDeniedException('You are not a member of the finance team!')); + }); + + test('Cannot set tax exempt status for non-existent vendor', async () => { + await expect( + ReimbursementRequestService.setVendorTaxExemptStatus('non-existent-id', true, financeMember, org) + ).rejects.toThrow(new NotFoundException('Vendor', 'non-existent-id')); + }); + + test('Cannot set tax exempt status for vendor in different organization', async () => { + // Create a vendor in a different organization + const otherOrg = await prisma.organization.create({ + data: { + name: 'Other Org', + userCreated: { connect: { userId: financeHead.userId } } + } + }); + + const otherMember: User = await prisma.user.create({ + data: { + firstName: 'Other', + lastName: 'Member', + googleAuthId: '99', + email: 'email@email.other', + roles: { + create: { + roleType: Role_Type.MEMBER, + organization: { + connect: { organizationId: otherOrg.organizationId } + } + } + } + } + }); + + const otherVendor = await ReimbursementRequestService.createVendor( + otherMember, + 'Other Org Vendor', + otherOrg, + false, + [], + 'Some notes' + ); + + await expect( + ReimbursementRequestService.setVendorTaxExemptStatus(otherVendor.vendorId, true, financeMember, org) + ).rejects.toThrow(new InvalidOrganizationException('Vendor')); + }); + + test('head can set vendor tax exempt status', async () => { + const updatedVendor = await ReimbursementRequestService.setVendorTaxExemptStatus( + createdVendor.vendorId, + true, + financeHead, + org + ); + + expect(updatedVendor).not.toBeNull(); + expect(updatedVendor.taxExempt).toBe(true); + }); + }); }); diff --git a/src/frontend/src/apis/finance.api.ts b/src/frontend/src/apis/finance.api.ts index 886911357e..1da8b5de25 100644 --- a/src/frontend/src/apis/finance.api.ts +++ b/src/frontend/src/apis/finance.api.ts @@ -441,6 +441,16 @@ export const editVendor = async (id: string, vendorData: EditVendorPayload) => { return axios.post(apiUrls.financeEditVendor(id), vendorData); }; +/** + * API call to set the tax exempt status of a vendor + * @param vendorId id of vendor to set + * @param taxExempt whether the vendor is tax exempt + * @returns updated vendor + */ +export const setTaxExemptStatus = async (vendorId: string, taxExempt: boolean) => { + return axios.post(apiUrls.financeSetVendorTaxExemptStatus(vendorId), { taxExempt }); +}; + /** * API call to delete a given vendor * diff --git a/src/frontend/src/components/SponsorTierPill.tsx b/src/frontend/src/components/SponsorTierPill.tsx index 298e7edf6b..f12db9f05c 100644 --- a/src/frontend/src/components/SponsorTierPill.tsx +++ b/src/frontend/src/components/SponsorTierPill.tsx @@ -7,13 +7,18 @@ const SponsorTierPill = ({ tier }: { tier: SponsorTier }) => { label={tier.name} variant="filled" sx={{ - fontSize: 23, + '& .MuiChip-label': { + fontSize: 'inherit', + lineHeight: '1em' + }, fontWeight: 500, color: 'white', backgroundColor: tier.colorHexCode, - width: 125, - height: 40, - borderRadius: 15 + px: 1.25, + py: 0.25, + borderRadius: '999px', + height: 'auto', + minHeight: 0 }} /> ); diff --git a/src/frontend/src/components/TimeSlot.tsx b/src/frontend/src/components/TimeSlot.tsx index ce450bbecd..f4eff880f5 100644 --- a/src/frontend/src/components/TimeSlot.tsx +++ b/src/frontend/src/components/TimeSlot.tsx @@ -2,7 +2,7 @@ import { Box } from '@mui/system'; import { Icon } from '@mui/material'; interface TimeSlotProps { - text?: string; + text?: React.ReactNode; fontSize?: string; backgroundColor?: string; icon?: string; @@ -13,6 +13,7 @@ interface TimeSlotProps { onMouseOver?: () => void; onClick?: () => void; heightOverride?: string; + widthOverride?: string; selected?: boolean; } @@ -27,14 +28,15 @@ const TimeSlot: React.FC = ({ onMouseUp, onMouseOver, onClick, - heightOverride = undefined, + heightOverride, + widthOverride, selected = false }) => { return ( { }); }; +/** + * Custom react hook to set tax exempt status of a vendor + */ +export const useSetTaxExemptStatus = () => { + const queryClient = useQueryClient(); + return useMutation( + ['vendors', 'taxExemptStatus'], + async ({ vendorId, taxExempt }) => { + const { data } = await setTaxExemptStatus(vendorId, taxExempt); + queryClient.invalidateQueries(['vendors']); + return data; + } + ); +}; + /** * Custom React Hook to get all the reimbursement requests */ @@ -1223,11 +1243,11 @@ export const useGetAllSponsorTiers = () => { }); }; -export const useEditSponsor = (sponsorId: string) => { +export const useEditSponsor = () => { const queryClient = useQueryClient(); - return useMutation( + return useMutation( ['sponsor', 'edit'], - async (formData: SponsorPayload) => { + async ({ sponsorId, ...formData }: EditSponsorPayload) => { const { data } = await editSponsor(sponsorId, formData); return data; }, diff --git a/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx b/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx index 546e4f679d..3aceb0d377 100644 --- a/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx +++ b/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { TextField, FormControl, FormLabel, TableCell, TableRow, Grid, Typography } from '@mui/material'; -import AdminToolTable from './AdminToolTable'; +import NERTable from '../../components/NERTable'; import { useAllTeams } from '../../hooks/teams.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; @@ -86,7 +86,7 @@ const AdminToolsAttendeeDesignReviewInfo: React.FC = () => { Search by team member name - = ({ orga - + {clickedTeam && ( diff --git a/src/frontend/src/pages/AdminToolsPage/BOMConfig/ManufacturerTable.tsx b/src/frontend/src/pages/AdminToolsPage/BOMConfig/ManufacturerTable.tsx index 0019038ed7..9ffbaed770 100644 --- a/src/frontend/src/pages/AdminToolsPage/BOMConfig/ManufacturerTable.tsx +++ b/src/frontend/src/pages/AdminToolsPage/BOMConfig/ManufacturerTable.tsx @@ -6,7 +6,7 @@ import { useDeleteManufacturer, useGetAllManufacturers } from '../../../hooks/bo import { useToast } from '../../../hooks/toasts.hooks'; import { datePipe } from '../../../utils/pipes'; import ErrorPage from '../../ErrorPage'; -import AdminToolTable from '../AdminToolTable'; +import NERTable from '../../../components/NERTable'; import CreateManufacturerModal from './CreateManufacturerFormModal'; import ManufacturerDeleteModal from './ManufacturerDeleteModal'; import { useState } from 'react'; @@ -88,7 +88,7 @@ const ManufacturerTable: React.FC = () => { return ( setCreateModalShow(false)} /> - diff --git a/src/frontend/src/pages/AdminToolsPage/BOMConfig/MaterialTypeTable.tsx b/src/frontend/src/pages/AdminToolsPage/BOMConfig/MaterialTypeTable.tsx index 97da6f6cff..cb7188e6b1 100644 --- a/src/frontend/src/pages/AdminToolsPage/BOMConfig/MaterialTypeTable.tsx +++ b/src/frontend/src/pages/AdminToolsPage/BOMConfig/MaterialTypeTable.tsx @@ -4,7 +4,7 @@ import { datePipe } from '../../../utils/pipes'; import ErrorPage from '../../ErrorPage'; import { NERButton } from '../../../components/NERButton'; import { useState } from 'react'; -import AdminToolTable from '../AdminToolTable'; +import NERTable from '../../../components/NERTable'; import { useGetAllMaterialTypes } from '../../../hooks/bom.hooks'; import CreateMaterialTypeModal from './CreateMaterialTypeFormModal'; @@ -38,7 +38,7 @@ const MaterialTypeTable: React.FC = () => { return ( setCreateModalShow(false)} /> - + { return ( setCreateModalShow(false)} /> - + { indexCode={indexCodeToEdit} /> )} - { {tierToEdit && ( setTierToEdit(null)} sponsorTier={tierToEdit} /> )} - { }} /> Project Name Abbreviations - + { return ( setOpenModal(false)} /> - + setOpenModal(true)}> New Car diff --git a/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/DescriptionBulletTypes/DescriptionBulletTypeTable.tsx b/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/DescriptionBulletTypes/DescriptionBulletTypeTable.tsx index c85712f5c6..1dd96dd1aa 100644 --- a/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/DescriptionBulletTypes/DescriptionBulletTypeTable.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/DescriptionBulletTypes/DescriptionBulletTypeTable.tsx @@ -8,7 +8,7 @@ import { TableCell, TableRow, Typography } from '@mui/material'; import CreateDescriptionBulletTypeModal from './CreateDescriptionBulletTypeModal'; import EditDescriptionBulletTypeModal from './EditDescriptionBulletTypeModel'; import { Box } from '@mui/system'; -import AdminToolTable from '../../AdminToolTable'; +import NERTable from '../../../../components/NERTable'; import { NERButton } from '../../../../components/NERButton'; const DescriptionBulletTypeTable = () => { @@ -69,7 +69,7 @@ const DescriptionBulletTypeTable = () => { /> )} Registered Description Bullet Types - diff --git a/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/LinkTypes/LinkTypeFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/LinkTypes/LinkTypeFormModal.tsx index e3d6088fc7..112b5b131f 100644 --- a/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/LinkTypes/LinkTypeFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/LinkTypes/LinkTypeFormModal.tsx @@ -63,6 +63,7 @@ const LinkTypeFormModal = ({ open, handleClose, defaultValues, onSubmit, linkTyp } handleClose(); }; + const tooltipMessage = ( Click to view possible icon names. For names with multiple words, seperate them with an _. AttachMoney = attach_money @@ -73,7 +74,7 @@ const LinkTypeFormModal = ({ open, handleClose, defaultValues, onSubmit, linkTyp open={open} onHide={handleClose} title={!!defaultValues ? 'Edit LinkType' : 'Create LinkType'} - reset={() => reset({ name: '' })} + reset={reset} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} formId={!!defaultValues ? 'edit-LinkType-form' : 'create-LinkType-form'} @@ -83,7 +84,7 @@ const LinkTypeFormModal = ({ open, handleClose, defaultValues, onSubmit, linkTyp LinkType Name - + {errors.name?.message} diff --git a/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/LinkTypes/LinkTypeTable.tsx b/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/LinkTypes/LinkTypeTable.tsx index 570d6e2334..aae45e2a84 100644 --- a/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/LinkTypes/LinkTypeTable.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/LinkTypes/LinkTypeTable.tsx @@ -6,7 +6,7 @@ import { NERButton } from '../../../../components/NERButton'; import { useState } from 'react'; import CreateLinkTypeModal from './CreateLinkTypeModal'; import EditLinkTypeModal from './EditLinkTypeModal'; -import AdminToolTable from '../../AdminToolTable'; +import NERTable from '../../../../components/NERTable'; import { isAdmin, LinkType } from 'shared'; import { useCurrentUser } from '../../../../hooks/users.hooks'; @@ -65,7 +65,7 @@ const LinkTypeTable = () => { /> )} Registered LinkTypes - + {isAdmin(currentUser.role) && ( { Part Tags setOpenModal(false)} /> - { return ( - + {isAdmin(currentUser.role) && ( history.push(routes.PROJECT_TEMPLATE_NEW)}> diff --git a/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/WorkPackageTemplateTable.tsx b/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/WorkPackageTemplateTable.tsx index 0273f4e534..55c873affe 100644 --- a/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/WorkPackageTemplateTable.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ProjectsConfig/WorkPackageTemplateTable.tsx @@ -1,5 +1,5 @@ import { TableRow, TableCell, Box, IconButton, Typography } from '@mui/material'; -import AdminToolTable from '../AdminToolTable'; +import NERTable from '../../../components/NERTable'; import { NERButton } from '../../../components/NERButton'; import { isAdmin } from 'shared/src/permission-utils'; import { useCurrentUser } from '../../../hooks/users.hooks'; @@ -63,7 +63,7 @@ const WorkPackageTemplateTable = () => { return ( - diff --git a/src/frontend/src/pages/AdminToolsPage/RecruitmentConfig/ApplicationLinkTable.tsx b/src/frontend/src/pages/AdminToolsPage/RecruitmentConfig/ApplicationLinkTable.tsx index b2a665ad14..2bac8a246d 100644 --- a/src/frontend/src/pages/AdminToolsPage/RecruitmentConfig/ApplicationLinkTable.tsx +++ b/src/frontend/src/pages/AdminToolsPage/RecruitmentConfig/ApplicationLinkTable.tsx @@ -5,7 +5,7 @@ import ErrorPage from '../../ErrorPage'; import { useCurrentOrganization } from '../../../hooks/organizations.hooks'; import UpdateApplicationLinkModal from './UpdateApplicationLinkModal'; import { useState } from 'react'; -import AdminToolTable from '../AdminToolTable'; +import NERTable from '../../../components/NERTable'; const ApplicationLinkTable: React.FC = () => { const [showModal, setShowModal] = useState(false); @@ -59,7 +59,7 @@ const ApplicationLinkTable: React.FC = () => { Links Config - + setShowModal(false)} currentApplicationLink={url} /> ); diff --git a/src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamTypeTable.tsx b/src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamTypeTable.tsx index 9408abd0a6..94d4fd937a 100644 --- a/src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamTypeTable.tsx +++ b/src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamTypeTable.tsx @@ -2,7 +2,7 @@ import { TableRow, TableCell, Box, Typography, Icon } from '@mui/material'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; import { NERButton } from '../../../components/NERButton'; -import AdminToolTable from '../AdminToolTable'; +import NERTable from '../../../components/NERTable'; import CreateTeamTypeFormModal from './CreateTeamTypeFormModal'; import { MAX_FILE_SIZE, TeamType } from 'shared'; import EditTeamTypeFormModal from './EditTeamTypeFormModal'; @@ -159,7 +159,7 @@ const TeamTypeTable: React.FC = () => { teamType={editingTeamType} /> )} - diff --git a/src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamsTools.tsx b/src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamsTools.tsx index 299330f34b..de3fc8e358 100644 --- a/src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamsTools.tsx +++ b/src/frontend/src/pages/AdminToolsPage/TeamConfig/TeamsTools.tsx @@ -3,7 +3,7 @@ import { routes } from '../../../utils/routes'; import { Link as RouterLink } from 'react-router-dom'; import { useAllTeams } from '../../../hooks/teams.hooks'; import { fullNamePipe } from '../../../utils/pipes'; -import AdminToolTable from '../AdminToolTable'; +import NERTable from '../../../components/NERTable'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; @@ -41,7 +41,7 @@ const TeamsTools = () => { - diff --git a/src/frontend/src/pages/CreditsPage/CreditsPage.tsx b/src/frontend/src/pages/CreditsPage/CreditsPage.tsx index af2885fb4f..cbb86b4309 100644 --- a/src/frontend/src/pages/CreditsPage/CreditsPage.tsx +++ b/src/frontend/src/pages/CreditsPage/CreditsPage.tsx @@ -110,7 +110,7 @@ const CreditsPage: React.FC = () => { { name: 'Sharon Yang', color: '#ed8a5f' }, { name: 'Jonah Chang', color: '#9AAB89' }, { name: 'Ha Nguyen', color: '#ff9812' }, - { name: 'Sathvik Charugundla', color: '#ff0000' }, + { name: 'Sathvik Charugundla', color: '#00fff2ff' }, { name: 'Samantha Moy', color: '#d287fa' }, { name: 'Benjamin Zhu', color: '#ccccff' }, { name: 'Stephanie Xu', color: '#ffcd42' }, @@ -203,6 +203,7 @@ const CreditsPage: React.FC = () => { { name: 'Visisht Kamalapuram', color: '#3083AA' }, { name: 'Jay Jung', color: '##344739' }, { name: 'Elton Yu', color: '#f202a2' }, + { name: 'Raphael Bessin', color: '#14855fff' }, { name: 'Will Anderson', color: '#ebb145' }, { name: 'Alex Park', color: '#CCCCFF' }, { @@ -300,6 +301,15 @@ const CreditsPage: React.FC = () => { } } }, + { name: 'Edgar Buttner', color: '#9E9764' }, + { + name: 'John Cassidy', + color: '#8378ffff', + sx: { + textShadow: '0px 0px 10px rgba(195, 165, 193, 1)' + } + }, + { name: 'Gahan Patel', color: '#0000FF' }, { name: 'Mimo Olowu', color: 'white', sx: { px: 1, backgroundColor: '#ac59eb', borderRadius: 2 } }, { name: 'Saul Manzanares', color: '#AF34FA' }, { name: 'Richard Feng', color: '#FFFF', sx: { textShadow: '0 0 2px rgba(0,26,255), 0 0 5px rgba(255,255,255)' } }, @@ -316,6 +326,13 @@ const CreditsPage: React.FC = () => { } } }, + { + name: 'Anthony Basko', + color: '#c0aed0ff', + sx: { + textShadow: '0px 0px 3px rgba(152, 119, 233, 1), 0px .5px rgba(53, 37, 66, 1)' + } + }, { name: 'Santiago Ordonez Merizalde', color: 'transparent', @@ -337,6 +354,21 @@ const CreditsPage: React.FC = () => { filter: 'drop-shadow(0 0 4px rgba(190, 80, 255, 0.6))' } }, + { + name: 'Tony Feng', + color: 'transparent', + sx: { + textShadow: '0 0 5px #a7f3eaff, 0 0 10px #fb99e9ff, 0 0 30px #97eb97ff', + background: 'linear-gradient(90deg, white, violet, blue, red, white)', + '-webkit-background-clip': 'text', + backgroundSize: '800% 800%', + animation: 'gradient 30s infinite linear', + '@keyframes gradient': { + '0%': { backgroundPosition: '400% 200%' }, + '100%': { backgroundPosition: '0% 200%' } + } + } + }, { name: 'Josh Len', color: '#000000ff' } ]; diff --git a/src/frontend/src/pages/FinancePage/FinanceComponents/EditSponsorPage.tsx b/src/frontend/src/pages/FinancePage/FinanceComponents/EditSponsorPage.tsx index f629e8e29a..ff0d936218 100644 --- a/src/frontend/src/pages/FinancePage/FinanceComponents/EditSponsorPage.tsx +++ b/src/frontend/src/pages/FinancePage/FinanceComponents/EditSponsorPage.tsx @@ -18,7 +18,7 @@ interface EditSponsorPageProps { } const EditSponsorPage = ({ showPage, handleClose, sponsor }: EditSponsorPageProps) => { - const { isLoading, mutateAsync } = useEditSponsor(sponsor.sponsorId); + const { isLoading, mutateAsync } = useEditSponsor(); const defaultSponsorTasks: CreateSponsorTask[] = sponsor.sponsorTasks?.map((task) => ({ @@ -54,7 +54,7 @@ const EditSponsorPage = ({ showPage, handleClose, sponsor }: EditSponsorPageProp const onSubmit = async (formData: SponsorPayload) => { try { setSubmitError(null); - await mutateAsync({ ...formData }); + await mutateAsync({ sponsorId: sponsor.sponsorId, ...formData }); handleClose(); } catch (err: unknown) { if (err instanceof Error) { diff --git a/src/frontend/src/pages/FinancePage/FinanceComponents/ReimbursementRequestInfo.tsx b/src/frontend/src/pages/FinancePage/FinanceComponents/ReimbursementRequestInfo.tsx index 835884f79e..a254e7bef8 100644 --- a/src/frontend/src/pages/FinancePage/FinanceComponents/ReimbursementRequestInfo.tsx +++ b/src/frontend/src/pages/FinancePage/FinanceComponents/ReimbursementRequestInfo.tsx @@ -14,7 +14,14 @@ import { Link as RouterLink, useLocation } from 'react-router-dom'; import { useState } from 'react'; import { isGuest, ReimbursementRequest } from 'shared'; import { ReimbursementRequestRow, ReimbursementStatusType } from 'shared/src/types/reimbursement-requests-types'; -import { undefinedPipe, fullNamePipe, centsToDollar, datePipe, dateUndefinedPipe } from '../../../utils/pipes'; +import { + undefinedPipe, + fullNamePipe, + centsToDollar, + datePipe, + dateUndefinedPipe, + formatSaboIdPipe +} from '../../../utils/pipes'; import { createReimbursementRequestRowData, vendorDescendingComparator, @@ -291,7 +298,7 @@ const ReimbursementRequestInfo = ({ {currentTab !== 0 && {fullNamePipe(row.submitter)}} {`$${centsToDollar(row.amount)}`} {undefinedPipe(row.identifier)} - {undefinedPipe(row.saboId)} + {formatSaboIdPipe(row.saboId)} {datePipe(row.dateSubmitted)} {dateUndefinedPipe(row.dateSubmittedToSabo)} {currentTab === 1 && {fullNamePipe(row.financeMemberAssigned)}} diff --git a/src/frontend/src/pages/FinancePage/FinanceComponents/VendorFormModal.tsx b/src/frontend/src/pages/FinancePage/FinanceComponents/VendorFormModal.tsx index 6c83301a4b..81453691ca 100644 --- a/src/frontend/src/pages/FinancePage/FinanceComponents/VendorFormModal.tsx +++ b/src/frontend/src/pages/FinancePage/FinanceComponents/VendorFormModal.tsx @@ -38,7 +38,7 @@ const VendorFormModal = ({ showModal, handleClose, defaultValues, onSubmit }: Ve discountCode: yup.string().optional(), taxExempt: yup.boolean().required('Tax Exemption Status is Required'), twoFactorContacts: yup.array(), - note: yup.string().optional() + notes: yup.string().optional() }); const { @@ -55,7 +55,7 @@ const VendorFormModal = ({ showModal, handleClose, defaultValues, onSubmit }: Ve discountCode: defaultValues?.discountCode ?? undefined, taxExempt: defaultValues?.taxExempt, twoFactorContacts: defaultValues?.twoFactorContacts.map((user) => user.userId) ?? [], - note: defaultValues?.notes ?? '' + notes: defaultValues?.notes ?? '' } }); @@ -84,7 +84,7 @@ const VendorFormModal = ({ showModal, handleClose, defaultValues, onSubmit }: Ve open={showModal} onHide={handleClose} title={!!defaultValues ? 'Edit Vendor' : 'Add Vendor'} - reset={() => reset({ name: '', username: '', password: '', discountCode: '', twoFactorContacts: [], note: '' })} + reset={() => reset({ name: '', username: '', password: '', discountCode: '', twoFactorContacts: [], notes: '' })} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} formId={!!defaultValues ? 'edit-vendor-form' : 'create-vendor-form'} @@ -219,8 +219,8 @@ const VendorFormModal = ({ showModal, handleClose, defaultValues, onSubmit }: Ve Notes on Vendor: - - {errors.note?.message} + + {errors.notes?.message} diff --git a/src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/AddSABONumberModal.tsx b/src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/AddSABONumberModal.tsx index bd5a517252..ecea59bfaf 100644 --- a/src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/AddSABONumberModal.tsx +++ b/src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/AddSABONumberModal.tsx @@ -7,12 +7,15 @@ import ReactHookTextField from '../../../components/ReactHookTextField'; import { useSetSaboNumber } from '../../../hooks/finance.hooks'; import { useToast } from '../../../hooks/toasts.hooks'; -const schema = yup.object().shape({ +const schema = yup.object({ saboNumber: yup .number() .typeError('The SABO number should be a valid number') - .required() - .test('length', 'The SABO number must be at least 5 digits', (num) => String(num).length >= 5) + .required('The SABO number is required') + .test('exact-5-digits', 'The SABO number must be exactly 5 digits', function () { + const original = this.originalValue?.toString().trim(); + return /^\d{5}$/.test(original || ''); + }) }); interface AddSABONumberModalProps { diff --git a/src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/ReimbursementRequestDetailsView.tsx b/src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/ReimbursementRequestDetailsView.tsx index 2ec66e707d..9b6f71c96a 100644 --- a/src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/ReimbursementRequestDetailsView.tsx +++ b/src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/ReimbursementRequestDetailsView.tsx @@ -3,7 +3,7 @@ * See the LICENSE file in the repository root folder for details. */ -import { accountCodePipe, displayEnum } from '../../../utils/pipes'; +import { accountCodePipe, displayEnum, formatSaboIdPipe } from '../../../utils/pipes'; import { Assignment, ChangeCircle, Edit, Pending } from '@mui/icons-material'; import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; @@ -40,7 +40,7 @@ import { } from '../../../hooks/finance.hooks'; import { useToast } from '../../../hooks/toasts.hooks'; import { useCurrentUser } from '../../../hooks/users.hooks'; -import { centsToDollar, fullNamePipe, undefinedPipe } from '../../../utils/pipes'; +import { centsToDollar, fullNamePipe } from '../../../utils/pipes'; import { imageDownloadUrl, imageFileUrl, @@ -479,7 +479,7 @@ const ReimbursementRequestDetailsView: React.FC { const { data: sponsors, isLoading: sponsorIsLoading, isError: sponsorIsError, error: sponsorError } = useGetAllSponsors(); - const [currentPage, setCurrentPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(14); const [showAddSponsor, setShowAddSponsor] = useState(false); const [sponsorToEdit, setSponsorToEdit] = useState(undefined); const [sponsorToDelete, setSponsorToDelete] = useState(undefined); const [showDeleteModal, setShowDeleteModal] = useState(false); const [selectedSponsor, setSelectedSponsor] = useState(null); const [isTasksModalOpen, setIsTasksModalOpen] = useState(false); + const currentUser = useCurrentUser(); + const { mutateAsync: editSponsorMutateAsync } = useEditSponsor(); - if (!sponsors || sponsorIsLoading) { - return ; - } - if (sponsorIsError) { - return ; - } + const canEditSponsors = isAtLeastRank(RoleEnum.HEAD, currentUser.role) || !!currentUser.isFinance; - sponsors.sort((a, b) => a.name.localeCompare(b.name)); - const startIdx = currentPage * rowsPerPage; - const currentSponsors = sponsors.slice(startIdx, startIdx + rowsPerPage); - - const handleChangePage = (_event: unknown, newPage: number) => { - setCurrentPage(newPage); - }; + if (!sponsors || sponsorIsLoading) return ; + if (sponsorIsError) return ; - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setCurrentPage(0); - }; + // ensure a predictable ordering + sponsors.sort((a, b) => a.name.localeCompare(b.name)); const openTasksModal = (sponsor: Sponsor) => { setSelectedSponsor(sponsor); @@ -58,142 +49,131 @@ const SponsorsTable = () => { setIsTasksModalOpen(false); }; - const sponsorTableRows = currentSponsors.map((sponsor, index) => ( - - - - {sponsor.name} - - - - {sponsor.activeStatus ? 'Active' : 'Inactive'} - - - {sponsor.sponsorContact} - - - - - - - - - {`$${sponsor.sponsorValue}`} - - - - {datePipe(sponsor.joinDate)} - - - - {sponsor.discountCode} - - - - {sponsor.taxExempt ? 'Yes' : 'No'} - - - - - openTasksModal(sponsor)}> - View Tasks - - - - - >) => ( + ) => { + e.stopPropagation(); + await editSponsorMutateAsync({ + ...(p.row as MapRowResult).raw, + activeStatus: !p.value + } as unknown as Parameters[0]); }} - > - - - - - - )); +
+ ); + } + } + ]; + + const mapRow = (s: Sponsor) => ({ + ...s, + id: s.sponsorId, + raw: s + }); return ( @@ -211,10 +191,11 @@ const SponsorsTable = () => { setSponsorToEdit(undefined); }} sponsor={sponsorToEdit} - > + /> } - > + /> )} + {sponsorToDelete && ( { sponsor={sponsorToDelete} /> )} - - - - - - Sponsor - - - Sponsor Status - - - Contacts - - - Sponsor Tier - - - Sponsor Value - - - Sponsor Join Date - - - Discount - - - Tax Exempt - - - Sponsor Tasks - - - Tasks - - - - {sponsorTableRows} - - - - setShowAddSponsor(false)} /> - setShowAddSponsor(true)} - sx={{ - borderRadius: '8px', - color: '#ededed', - backgroundColor: '#ef4345', - padding: '2px 20px', - display: 'inline-flex', - fontSize: '20px', - fontWeight: 700, - textTransform: 'none', - marginBottom: '7px', - '&:hover': { - backgroundColor: '#c74340' - } - }} - > - {' '} - Add Sponsor - - } - footerInfoBoxes={[# of Sponsors: {sponsors.length}]} - totalItems={sponsors.length} - currentPage={currentPage} - rowsPerPage={rowsPerPage} - onPageChange={handleChangePage} - onRowsPerPageChange={handleChangeRowsPerPage} - rowsPerPageOptions={[10, 14, 25, 50, 100]} - /> - + setSponsorToEdit(s)} + onAdd={() => setShowAddSponsor(true)} + searchFields={['name' as keyof MapRowResult]} + paperSx={{ + borderRadius: '10px 10px 0 0', + overflow: 'hidden', + height: 'calc(100vh - 120px)', + display: 'flex', + flexDirection: 'column' + }} + canEditRow={() => canEditSponsors} + /> + setShowAddSponsor(false)} /> {selectedSponsor && ( { } > - {tabIndex === 0 ? : } + {tabIndex === 0 ? : } ); diff --git a/src/frontend/src/pages/FinancePage/VendorsTable.tsx b/src/frontend/src/pages/FinancePage/VendorsTable.tsx index f6f7efeaab..62743c7078 100644 --- a/src/frontend/src/pages/FinancePage/VendorsTable.tsx +++ b/src/frontend/src/pages/FinancePage/VendorsTable.tsx @@ -1,371 +1,131 @@ -import React, { useState } from 'react'; -import { - TableRow, - TableCell, - Box, - Table as MuiTable, - TableHead, - TableBody, - Typography, - Button, - useTheme, - TableContainer, - Paper -} from '@mui/material'; -import EditIcon from '@mui/icons-material/Edit'; -import DeleteIcon from '@mui/icons-material/Delete'; +import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; +import type { MapRowResult } from '../../components/NERDataGrid'; +import type { MouseEvent } from 'react'; +import { useGetAllVendors, useSetTaxExemptStatus } from '../../hooks/finance.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; -import { useGetAllVendors } from '../../hooks/finance.hooks'; import ErrorPage from '../ErrorPage'; -import { NERButton } from '../../components/NERButton'; -import { Vendor } from 'shared'; +import { Box, Checkbox, IconButton } from '@mui/material'; +import NERDataGrid from '../../components/NERDataGrid'; +import { fullNamePipe } from '../../utils/pipes'; +import { useMemo, useState } from 'react'; +import { Delete } from '@mui/icons-material'; import DeleteVendorModal from './FinanceComponents/DeleteVendorModal'; -import CreateVendorModal from './FinanceComponents/CreateVendorModal'; import EditVendorModal from './FinanceComponents/EditVendorModal'; -import { datePipe, fullNamePipe } from '../../utils/pipes'; -import PaginationFooter from '../../components/PaginationFooter'; - -interface VendorTableProps { - isHeadAndAbove?: boolean; -} - -interface ScrollableCellProps { - children: React.ReactNode; - maxWidth?: number; -} - -const VendorTable = ({ isHeadAndAbove = false }: VendorTableProps) => { - const { data: vendors, isLoading: vendorIsLoading, isError: vendorIsError, error: vendorError } = useGetAllVendors(); - const [createModalShow, setCreateModalShow] = useState(false); - const [vendorToEdit, setVendorToEdit] = useState(undefined); - const [vendorToDelete, setVendorToDelete] = useState(undefined); - const [currentPage, setCurrentPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(14); - const theme = useTheme(); - - if (!vendors || vendorIsLoading) { - return ; - } - if (vendorIsError) { - return ; - } - - const ScrollableCell = ({ children, maxWidth = 150 }: ScrollableCellProps) => ( - - - {children} - - - ); +import { isAtLeastRank, RoleEnum, Vendor } from 'shared'; +import CreateVendorModal from './FinanceComponents/CreateVendorModal'; +import { useCurrentUser } from '../../hooks/users.hooks'; - vendors.sort((a, b) => a.name.localeCompare(b.name)); - const startIdx = currentPage * rowsPerPage; - const currentVendors = vendors.slice(startIdx, startIdx + rowsPerPage); +const VendorsTable: React.FC = () => { + const { data: vendors, isLoading: vendorsLoading, isError: vendorsIsError, error: vendorsError } = useGetAllVendors(); + const { mutateAsync: taxExemptMutateAsync } = useSetTaxExemptStatus(); + const [vendorToDelete, setVendorToDelete] = useState(); + const [vendorToEdit, setVendorToEdit] = useState(); + const [showCreateModal, setShowCreateModal] = useState(false); + const currentUser = useCurrentUser(); - const handleChangePage = (_event: unknown, newPage: number) => { - setCurrentPage(newPage); - }; + const canEditAllVendors = useMemo(() => { + return isAtLeastRank(RoleEnum.HEAD, currentUser.role) || currentUser.isFinance; + }, [currentUser.isFinance, currentUser.role]); - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setCurrentPage(0); - }; + const mapRow = (v: Vendor) => ({ + ...v, + id: v.vendorId, + name: v.name, + username: v.username, + password: v.password, + discountCode: v.discountCode, + taxExempt: v.taxExempt, + twoFactorContactsDisplay: v.twoFactorContacts.map(fullNamePipe).join(', '), + raw: v + }); - const vendorTableRows = currentVendors.map((vendor, index) => ( - - - - - {isHeadAndAbove ? ( - <> - ) => { + const vendor = (params.row as MapRowResult).raw as Vendor; + return ( + ) => { + e.stopPropagation(); + await taxExemptMutateAsync({ vendorId: vendor.vendorId, taxExempt: !params.value }); }} - > - - - + ); + } + }, + { field: 'twoFactorContactsDisplay', headerName: '2FA Contacts', flex: 1 }, + { + field: 'actions', + headerName: 'Delete', + width: 100, + sortable: false, + filterable: false, + renderCell: (params: GridRenderCellParams) => { + const vendor = (params.row as MapRowResult).raw as Vendor; + return ( + ) => { + e.stopPropagation(); + setVendorToDelete(vendor); }} > - - + + + ); + } + } + ]; - - - - - - - - - - - - - - - - - ) : ( - <> - - - - - - - - )} - - )); + if (vendorsLoading || !vendors) return ; + if (vendorsIsError) return ; return ( - - setCreateModalShow(false)} /> + + setShowCreateModal(false)} /> + {vendorToDelete && setVendorToDelete(undefined)} vendor={vendorToDelete} />} + + setShowCreateModal(true)} + onRowClick={(vendor) => setVendorToEdit(vendor)} + // allow if the current user can edit all vendors or if they added this vendor + canEditRow={(row) => { + const v = (row as MapRowResult).raw as Vendor; + const addedBy = (v as unknown as { addedByUserId?: string }).addedByUserId; + return Boolean(canEditAllVendors || addedBy === currentUser.userId); + }} + initialSortModel={[{ field: 'name', sort: 'asc' }]} + headerHeight={56} + rowHeight={52} + pageSizeDefault={10} + searchFields={['name' as keyof MapRowResult]} + paperSx={{ + borderRadius: '10px 10px 0 0', + overflow: 'hidden', + height: 'calc(100vh - 120px)', + display: 'flex', + flexDirection: 'column' + }} + /> + {vendorToEdit && ( - { - setVendorToEdit(undefined); - }} - vendor={vendorToEdit} - /> - )} - {vendorToDelete && ( - { - setVendorToDelete(undefined); - }} - vendor={vendorToDelete} - /> + setVendorToEdit(undefined)} vendor={vendorToEdit} /> )} - - - - - - - Vendor - - {isHeadAndAbove ? ( - <> - - Username - - - Password - - - Discount - - - 2FA Contacts - - - Notes - - - ) : ( - <> - - Date Added - - - Added By - - - )} - - - {vendorTableRows} - - - - { - setCreateModalShow(true); - }} - sx={{ - borderRadius: '8px', - color: '#ededed', - backgroundColor: '#ef4345', - padding: '2px 20px', - display: 'inline-flex', - fontSize: '20px', - fontWeight: 700, - textTransform: 'none', - marginBottom: '7px', - '&:hover': { - backgroundColor: '#c74340' - } - }} - > - Add Vendor - - ) - } - footerInfoBoxes={[# of Vendors: {vendors.length}]} - totalItems={vendors.length} - currentPage={currentPage} - rowsPerPage={rowsPerPage} - onPageChange={handleChangePage} - onRowsPerPageChange={handleChangeRowsPerPage} - rowsPerPageOptions={[10, 14, 25, 50, 100]} - /> ); }; -export default VendorTable; +export default VendorsTable; diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal.tsx index 44128bc1d5..bd0f39c29e 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal.tsx @@ -32,7 +32,14 @@ const AvailabilityEditModal: React.FC = ({ }; return ( - + = ({ Invert Availability - + {currentlyDisplayedAvailabilities.map((availability) => ( + {getDayOfWeek(availability.dateSet)}
{datePipe(availability.dateSet)} + + } /> ))} {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( - + {currentlyDisplayedAvailabilities.map((availability, dayIndex) => { const backgroundColor = availability.availability.includes(timeIndex) ? HeatmapColors[3] : HeatmapColors[0]; return ( handleMouseDown(e, availability, timeIndex)} onMouseEnter={(e) => handleMouseEnter(e, availability, timeIndex)} onMouseUp={handleMouseUp} diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx index 8c86150398..a83d8ffda9 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx @@ -57,13 +57,13 @@ const UserScheduleSettingsView = ({ return ( setAvailabilityOpen(false)} header={'Availability'} availabilites={scheduleSettings.availabilities} /> setConfirmAvailabilityOpen(false)} header={confirmModalTitle} confirmedAvailabilities={confirmedAvailabilities} diff --git a/src/frontend/src/utils/diff-page.utils.ts b/src/frontend/src/utils/diff-page.utils.ts index 79eabd51fb..28d8040947 100644 --- a/src/frontend/src/utils/diff-page.utils.ts +++ b/src/frontend/src/utils/diff-page.utils.ts @@ -259,8 +259,8 @@ export const getChangesForWorkPackage = ( genChange( 'Start Date', originalWorkPackage?.startDate.getTime() !== proposedChanges?.startDate.getTime(), - originalWorkPackage?.startDate.toLocaleString() ?? '', - proposedChanges?.startDate.toLocaleString() ?? '' + datePipe(originalWorkPackage?.startDate), + datePipe(proposedChanges?.startDate) ) ); @@ -273,6 +273,24 @@ export const getChangesForWorkPackage = ( ) ); + let proposedChangesEndDate; + + if (proposedChanges) { + proposedChangesEndDate = new Date(proposedChanges.startDate); + proposedChangesEndDate.setDate(proposedChangesEndDate.getDate() + proposedChanges.duration * 7); + } + + lines.push( + genChange( + 'End Date', + originalWorkPackage?.endDate && proposedChangesEndDate + ? datePipe(originalWorkPackage.endDate) !== datePipe(proposedChangesEndDate) + : !!originalWorkPackage?.endDate !== !!proposedChangesEndDate, + datePipe(originalWorkPackage?.endDate), + datePipe(proposedChangesEndDate) + ) + ); + lines.push( genListChange( 'Blocked By', diff --git a/src/frontend/src/utils/pipes.ts b/src/frontend/src/utils/pipes.ts index cbeb0c87f7..22b5f95e7e 100644 --- a/src/frontend/src/utils/pipes.ts +++ b/src/frontend/src/utils/pipes.ts @@ -209,3 +209,14 @@ export const labelPipe = (label: string) => { return result; }; + +// Pad SABO ID with leading zeroes +export const formatSaboIdPipe = (saboId: number | undefined): string => { + if (saboId === undefined || saboId === null) return undefinedPipe(saboId as any); + const str = String(saboId); + // Only pad if it's shorter than 5 + if (str.length < 5) { + return str.padStart(5, '0'); + } + return str; +}; From 76a6bc0c18795c98d5e1efb5a2acc7d4e89be0ee Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 22 Nov 2025 17:24:22 -0500 Subject: [PATCH 239/477] #3636 Remove remaining unrelated files --- .../tests/unit/change-requests.test.ts | 287 ++++++++++++++++++ src/frontend/src/components/NERDataGrid.tsx | 160 ++++++++++ .../pages/AdminToolsPage/AdminToolTable.tsx | 39 --- 3 files changed, 447 insertions(+), 39 deletions(-) create mode 100644 src/backend/tests/unit/change-requests.test.ts create mode 100644 src/frontend/src/components/NERDataGrid.tsx delete mode 100644 src/frontend/src/pages/AdminToolsPage/AdminToolTable.tsx diff --git a/src/backend/tests/unit/change-requests.test.ts b/src/backend/tests/unit/change-requests.test.ts new file mode 100644 index 0000000000..d7218dbeec --- /dev/null +++ b/src/backend/tests/unit/change-requests.test.ts @@ -0,0 +1,287 @@ +import { CR_Type, Organization, Scope_CR_Why_Type, User, WBS_Element_Status } from '@prisma/client'; +import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; +import ChangeRequestsService from '../../src/services/change-requests.services'; +import { supermanAdmin } from '../test-data/users.test-data'; +import { ProjectProposedChangesCreateArgs, WorkPackageProposedChangesCreateArgs } from 'shared'; +import prisma from '../../src/prisma/prisma'; + +describe('Change Request Tests', () => { + let orgId: string; + let organization: Organization; + let user: User; + + beforeEach(async () => { + organization = await createTestOrganization(); + orgId = organization.organizationId; + user = await createTestUser(supermanAdmin, orgId); + await prisma.wBS_Element.create({ + data: { + carNumber: 12, + projectNumber: 13, + workPackageNumber: 14, + name: 'test wbs', + organizationId: orgId, + status: WBS_Element_Status.INACTIVE + } + }); + }); + + afterEach(async () => { + await resetUsers(); + }); + + describe('Create Change Request', () => { + it('create change request on an inactive project - project changes', async () => { + const projPropChanges: ProjectProposedChangesCreateArgs = { + name: 'Project name changes', + descriptionBullets: [], + links: [], + budget: 10, + summary: 'Summary', + teamIds: [], + workPackageProposedChanges: [] + }; + + const cr = await ChangeRequestsService.createStandardChangeRequest( + user, + 12, + 13, + 14, + CR_Type.DEFINITION_CHANGE, + 'What', + [ + { + type: Scope_CR_Why_Type.COMPETITION, + explain: 'Explaining' + } + ], + [], + organization, + projPropChanges, + null + ); + + expect(cr.submitter.userId).toEqual(user.userId); + expect(cr.wbsNum?.carNumber).toEqual(12); + expect(cr.wbsNum?.projectNumber).toEqual(13); + expect(cr.wbsNum?.workPackageNumber).toEqual(14); + + expect(cr.type).toEqual(CR_Type.DEFINITION_CHANGE); + expect(cr.what).toEqual('What'); + expect(cr.proposedSolutions).toHaveLength(0); + + expect(cr.wbsNum).toBeDefined(); + expect(cr.wbsNum).not.toBeNull(); + + const wbsElement = await prisma.wBS_Element.findUnique({ + where: { + wbsNumber: { + carNumber: 12, + projectNumber: 13, + workPackageNumber: 14, + organizationId: organization.organizationId + } + } + }); + + expect(wbsElement?.status).toEqual(WBS_Element_Status.INACTIVE); + expect(wbsElement?.carNumber).toEqual(12); + expect(wbsElement?.projectNumber).toEqual(13); + expect(wbsElement?.workPackageNumber).toEqual(14); + }); + it('create change request does not make active project inactive - project changes', async () => { + await prisma.wBS_Element.update({ + where: { + wbsNumber: { + carNumber: 12, + projectNumber: 13, + workPackageNumber: 14, + organizationId: organization.organizationId + } + }, + data: { + status: WBS_Element_Status.ACTIVE + } + }); + + const wpPropChanges: WorkPackageProposedChangesCreateArgs = { + name: 'wp', + descriptionBullets: [], + links: [], + duration: 3, + startDate: '2025-09-13', + blockedBy: [], + leadId: user.userId, + managerId: user.userId + }; + + await ChangeRequestsService.createStandardChangeRequest( + user, + 12, + 13, + 14, + CR_Type.DEFINITION_CHANGE, + 'What', + [ + { + type: Scope_CR_Why_Type.COMPETITION, + explain: 'Explaining' + } + ], + [], + organization, + null, + wpPropChanges + ); + + const wbsElement = await prisma.wBS_Element.findUnique({ + where: { + wbsNumber: { + carNumber: 12, + projectNumber: 13, + workPackageNumber: 14, + organizationId: organization.organizationId + } + } + }); + + expect(wbsElement?.status).toEqual(WBS_Element_Status.ACTIVE); + expect(wbsElement?.carNumber).toEqual(12); + expect(wbsElement?.projectNumber).toEqual(13); + expect(wbsElement?.workPackageNumber).toEqual(14); + }); + it('create change request does not make active project inactive - work package changes', async () => { + await prisma.wBS_Element.update({ + where: { + wbsNumber: { + carNumber: 12, + projectNumber: 13, + workPackageNumber: 14, + organizationId: organization.organizationId + } + }, + data: { + status: WBS_Element_Status.ACTIVE + } + }); + + const wpPropChanges: WorkPackageProposedChangesCreateArgs = { + name: 'wp', + descriptionBullets: [], + links: [], + duration: 3, + startDate: '2025-09-13', + blockedBy: [], + leadId: user.userId, + managerId: user.userId + }; + + const cr = await ChangeRequestsService.createStandardChangeRequest( + user, + 12, + 13, + 14, + CR_Type.DEFINITION_CHANGE, + 'What', + [ + { + type: Scope_CR_Why_Type.COMPETITION, + explain: 'Explaining' + } + ], + [], + organization, + null, + wpPropChanges + ); + + const wbsElement = await prisma.wBS_Element.findUnique({ + where: { + wbsNumber: { + carNumber: 12, + projectNumber: 13, + workPackageNumber: 14, + organizationId: organization.organizationId + } + } + }); + expect(cr.submitter.userId).toEqual(user.userId); + expect(cr.wbsNum?.carNumber).toEqual(12); + expect(cr.wbsNum?.projectNumber).toEqual(13); + expect(cr.wbsNum?.workPackageNumber).toEqual(14); + + expect(cr.type).toEqual(CR_Type.DEFINITION_CHANGE); + expect(cr.what).toEqual('What'); + expect(cr.proposedSolutions).toHaveLength(0); + + expect(cr.wbsNum).toBeDefined(); + expect(cr.wbsNum).not.toBeNull(); + + expect(wbsElement?.status).toEqual(WBS_Element_Status.ACTIVE); + expect(wbsElement?.carNumber).toEqual(12); + expect(wbsElement?.projectNumber).toEqual(13); + expect(wbsElement?.workPackageNumber).toEqual(14); + }); + it('create change request on an inactive project - work package changes', async () => { + await prisma.wBS_Element.update({ + where: { + wbsNumber: { + carNumber: 12, + projectNumber: 13, + workPackageNumber: 14, + organizationId: organization.organizationId + } + }, + data: { + status: WBS_Element_Status.INACTIVE + } + }); + + const wpPropChanges: WorkPackageProposedChangesCreateArgs = { + name: 'wp', + descriptionBullets: [], + links: [], + duration: 3, + startDate: '2025-09-13', + blockedBy: [], + leadId: user.userId, + managerId: user.userId + }; + + await ChangeRequestsService.createStandardChangeRequest( + user, + 12, + 13, + 14, + CR_Type.DEFINITION_CHANGE, + 'What', + [ + { + type: Scope_CR_Why_Type.COMPETITION, + explain: 'Explaining' + } + ], + [], + organization, + null, + wpPropChanges + ); + + const wbsElement = await prisma.wBS_Element.findUnique({ + where: { + wbsNumber: { + carNumber: 12, + projectNumber: 13, + workPackageNumber: 14, + organizationId: organization.organizationId + } + } + }); + + expect(wbsElement?.status).toEqual(WBS_Element_Status.INACTIVE); + expect(wbsElement?.carNumber).toEqual(12); + expect(wbsElement?.projectNumber).toEqual(13); + expect(wbsElement?.workPackageNumber).toEqual(14); + }); + }); +}); diff --git a/src/frontend/src/components/NERDataGrid.tsx b/src/frontend/src/components/NERDataGrid.tsx new file mode 100644 index 0000000000..8e66ea1b68 --- /dev/null +++ b/src/frontend/src/components/NERDataGrid.tsx @@ -0,0 +1,160 @@ +import React, { useMemo, useState } from 'react'; +import { DataGrid, GridColDef, GridRowParams } from '@mui/x-data-grid'; +import { Box, Button, Paper, TextField } from '@mui/material'; +import type { SxProps } from '@mui/system'; +import type { Theme } from '@mui/material/styles'; + +export type MapRowResult = T & { id: string | number; raw?: T }; + +interface NERDataGridProps { + items: T[]; + // map an item to a row object (must include `id` and may include `raw`) + mapRow: (item: T) => MapRowResult; + columns: GridColDef[]; + pageSizeDefault?: number; + rowsPerPageOptions?: number[]; + onAdd: () => void; + onRowClick?: (item: T) => void; + // optional simple search fields (keys of mapped row) or a custom filter function + searchFields?: (keyof MapRowResult)[]; + searchFilter?: (term: string, row: MapRowResult) => boolean; + // optional sort model to apply initially + initialSortModel?: { field: string; sort: 'asc' | 'desc' }[]; + headerHeight?: number; + rowHeight?: number; + paperSx?: SxProps; + canEditRow?: (row: MapRowResult) => boolean; +} + +function NERDataGrid({ + items, + mapRow, + columns, + pageSizeDefault = 10, + rowsPerPageOptions, + onAdd, + onRowClick, + searchFields, + searchFilter, + initialSortModel = [{ field: 'name', sort: 'asc' }], + headerHeight = 56, + rowHeight = 52, + paperSx, + canEditRow +}: NERDataGridProps) { + const [searchTerm, setSearchTerm] = useState(''); + const [pageSize, setPageSize] = useState(pageSizeDefault); + + // compute standard pagination options if caller didn't pass any + const effectiveRowsPerPageOptions = useMemo(() => { + const base = [5, 10, 25, 50, 100]; + const itemsCount = (items ?? []).length; + if (rowsPerPageOptions && rowsPerPageOptions.length > 0) { + const provided = Array.from(new Set(rowsPerPageOptions)) + .sort((a, b) => a - b) + .filter((opt) => opt <= itemsCount); + if (provided.length > 0) return provided; + return itemsCount > 0 ? [itemsCount] : base; + } + + // default behavior: include standard options up to the total number of items + if (itemsCount === 0) return base; + const opts = base.filter((opt) => opt <= itemsCount); + if (itemsCount < 100 && !opts.includes(itemsCount)) opts.push(itemsCount); + return Array.from(new Set(opts)).sort((a, b) => a - b); + }, [rowsPerPageOptions, items]); + + const rows = useMemo(() => items.map(mapRow), [items, mapRow]); + + const filteredRows = useMemo(() => { + const term = searchTerm.trim().toLowerCase(); + if (!term) return rows; + if (searchFilter) return rows.filter((r) => searchFilter(term, r)); + if (searchFields && searchFields.length > 0) { + return rows.filter((r) => + searchFields.some((f) => + String(((r as MapRowResult)[f] as unknown) ?? '') + .toLowerCase() + .includes(term) + ) + ); + } + return rows.filter((r) => JSON.stringify(r).toLowerCase().includes(term)); + }, [rows, searchTerm, searchFields, searchFilter]); + + return ( + + + + setSearchTerm(e.target.value)} + size="small" + placeholder="Search" + sx={{ flex: 1 }} + /> + + + + + setPageSize(newSize)} + rowsPerPageOptions={effectiveRowsPerPageOptions} + pagination + disableSelectionOnClick + headerHeight={headerHeight} + rowHeight={rowHeight} + onRowClick={(params: GridRowParams>) => { + if (!onRowClick) return; + const row = params.row as MapRowResult; + const editable = canEditRow ? canEditRow(row) : true; + if (!editable) return; // do not call onRowClick for non-editable rows + const raw = params.row.raw as T | undefined; + if (raw) onRowClick(raw); + }} + getRowClassName={(params) => { + const row = params.row as MapRowResult; + const editable = canEditRow ? canEditRow(row) : true; + return editable ? 'editable-row' : 'non-editable-row'; + }} + sx={{ + height: '100%', + '& .MuiDataGrid-columnHeaders': { + backgroundColor: '#ef4345', + color: 'white', + fontWeight: 'bold' + }, + '& .MuiDataGrid-columnHeader': { + borderTopLeftRadius: 10, + borderTopRightRadius: 10 + }, + // per-row hover: mark editable rows with pointer and non-editable rows with default + '& .editable-row:hover': { + cursor: onRowClick ? 'pointer' : 'default' + }, + '& .non-editable-row:hover': { + cursor: 'default' + }, + '& .non-editable-row': { + opacity: 0.7 + }, + '& .MuiDataGrid-columnSeparator': { + display: 'none' + } + }} + /> + + + + ); +} + +export default NERDataGrid; diff --git a/src/frontend/src/pages/AdminToolsPage/AdminToolTable.tsx b/src/frontend/src/pages/AdminToolsPage/AdminToolTable.tsx deleted file mode 100644 index c20b7fc363..0000000000 --- a/src/frontend/src/pages/AdminToolsPage/AdminToolTable.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Table, TableBody, TableCell, TableContainer, TableHead } from '@mui/material'; - -interface AdminToolTableProps { - columns: { - name: string; - width?: string; - }[]; - rows: JSX.Element[]; -} - -const AdminToolTable = ({ columns, rows }: AdminToolTableProps) => { - return ( - - - - {columns.map((column, idx) => ( - - {column.name} - - ))} - - {rows} -
-
- ); -}; - -export default AdminToolTable; From 4d7855f41e9eb7b515cbb9e2d70fc06a65a2aaf0 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sat, 22 Nov 2025 17:33:49 -0500 Subject: [PATCH 240/477] #3636 Restore NERTable.tsx required by base branch files --- src/frontend/src/components/NERTable.tsx | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/frontend/src/components/NERTable.tsx diff --git a/src/frontend/src/components/NERTable.tsx b/src/frontend/src/components/NERTable.tsx new file mode 100644 index 0000000000..f22521f83c --- /dev/null +++ b/src/frontend/src/components/NERTable.tsx @@ -0,0 +1,47 @@ +import { Table, TableBody, TableCell, TableContainer, TableHead, TableSortLabel } from '@mui/material'; + +interface AdminToolTableProps { + columns: { + name: string; + width?: string; + sort?: SortLabelProps; + }[]; + rows: JSX.Element[]; + size?: 'small' | 'medium'; +} + +export interface SortLabelProps { + active?: boolean; + direction: 'asc' | 'desc'; + onClick: () => void; +} + +const NERTable = ({ columns, rows, size }: AdminToolTableProps) => { + return ( + + + + {columns.map((column, idx) => ( + + {column.name} + + ))} + + {rows} +
+
+ ); +}; + +export default NERTable; From 38ea0d55d535ed0da6b429f3ffad3a66c38f028a Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 23 Nov 2025 17:33:14 -0500 Subject: [PATCH 241/477] #3754 holy changes --- src/backend/index.ts | 2 - .../src/controllers/calendar.controllers.ts | 44 ++- .../controllers/design-reviews.controllers.ts | 2 + .../design-reviews.query-args.ts | 2 + .../src/prisma-query-args/event.query-args.ts | 22 +- .../work-packages.query-args.ts | 8 +- .../20251101233144_calendar/migration.sql | 332 +++++++++++++++++- src/backend/src/prisma/schema.prisma | 84 +---- src/backend/src/prisma/seed.ts | 21 +- src/backend/src/routes/calendar.routes.ts | 16 +- .../src/routes/design-reviews.routes.ts | 2 + src/backend/src/services/calendar.services.ts | 187 ++++++++-- .../src/services/design-reviews.services.ts | 10 + .../src/services/notifications.services.ts | 111 +++--- .../src/transformers/calendar.transformer.ts | 65 +++- .../design-reviews.transformer.ts | 2 + .../transformers/work-packages.transformer.ts | 8 +- src/backend/src/utils/calendar.utils.ts | 13 +- src/backend/src/utils/design-reviews.utils.ts | 15 +- .../src/utils/google-integration.utils.ts | 70 ++-- src/backend/src/utils/notifications.utils.ts | 11 +- src/backend/src/utils/pop-up.utils.ts | 22 +- src/backend/src/utils/slack.utils.ts | 84 +++-- src/backend/tests/test-utils.ts | 98 ++++-- src/backend/tests/unit/calendar.test.ts | 66 ++-- src/backend/tests/unit/design-review.test.ts | 117 ------ .../tests/unmocked/design-review.test.ts | 69 ---- src/frontend/src/apis/calendar.api.ts | 29 +- src/frontend/src/apis/design-reviews.api.ts | 16 +- .../apis/transformers/calendar.transformer.ts | 19 +- .../design-reviews.tranformers.ts | 2 + .../work-packages.transformers.ts | 4 +- src/frontend/src/hooks/calendar.hooks.ts | 78 +++- .../src/hooks/design-reviews.hooks.ts | 17 +- .../AdminToolsAttendeeDesignReviewInfo.tsx | 27 +- .../src/pages/CalendarPage/Calendar.tsx | 2 +- .../CalendarComponents/CalendarDayCard.tsx | 44 +-- .../src/pages/CalendarPage/CalendarPage.tsx | 219 ++++++------ .../DesignReviewDetails.tsx | 21 -- ...lityInfo.tsx => EventAvailabilityInfo.tsx} | 16 +- ...ewCreateModal.tsx => EventCreateModal.tsx} | 2 + .../AvailabilityScheduleView.tsx | 9 +- .../AvailabilityView.tsx | 90 +++-- .../EventDetailPage.tsx} | 91 +++-- .../EventDetailPage/EventDetails.tsx | 21 ++ .../FinalizeEventDetailsModal.tsx} | 71 ++-- .../UserAvailabilitesView.tsx | 34 +- ...SummaryModal.tsx => EventSummaryModal.tsx} | 96 ++--- ...viewDelayModal.tsx => EventDelayModal.tsx} | 20 +- .../{DesignReviewPill.tsx => EventPill.tsx} | 2 +- ...ees.tsx => EventSummaryModalAttendees.tsx} | 40 ++- ...ttons.tsx => EventSummaryModalButtons.tsx} | 24 +- ...tails.tsx => EventSummaryModalDetails.tsx} | 85 +++-- .../GanttChartColorLegend.tsx | 14 +- .../ProjectGanttChartPage.tsx | 2 +- .../{DesignReviewCard.tsx => EventCard.tsx} | 56 +-- .../components/UpcomingDesignReviews.tsx | 44 +-- .../src/pages/NewCalendarPage/NewCalendar.tsx | 2 +- .../pages/NewCalendarPage/NewCalendarPage.tsx | 187 +++++----- .../UserScheduleSettings.tsx | 20 +- .../UserScheduleSettingsView.tsx | 46 ++- .../tests/hooks/DesignReviews.hooks.test.tsx | 35 -- .../test-data/design-reviews.stub.ts | 149 ++++++-- .../test-data/work-packages.stub.ts | 10 +- src/frontend/src/utils/design-review.utils.ts | 28 +- src/frontend/src/utils/enum-pipes.ts | 19 +- src/frontend/src/utils/gantt.utils.tsx | 20 +- src/frontend/src/utils/pipes.ts | 32 +- src/frontend/src/utils/urls.ts | 16 +- src/shared/src/types/calendar-types.ts | 45 ++- src/shared/src/types/design-review-types.ts | 2 + src/shared/src/types/project-types.ts | 4 +- src/shared/src/utils.ts | 8 +- 73 files changed, 2048 insertions(+), 1253 deletions(-) delete mode 100644 src/backend/tests/unit/design-review.test.ts delete mode 100644 src/backend/tests/unmocked/design-review.test.ts delete mode 100644 src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/DesignReviewDetails.tsx rename src/frontend/src/pages/CalendarPage/{DesignReviewAvailabilityInfo.tsx => EventAvailabilityInfo.tsx} (79%) rename src/frontend/src/pages/CalendarPage/{DesignReviewCreateModal.tsx => EventCreateModal.tsx} (99%) rename src/frontend/src/pages/CalendarPage/{DesignReviewDetailPage => EventDetailPage}/AvailabilityScheduleView.tsx (94%) rename src/frontend/src/pages/CalendarPage/{DesignReviewDetailPage => EventDetailPage}/AvailabilityView.tsx (59%) rename src/frontend/src/pages/CalendarPage/{DesignReviewDetailPage/DesignReviewDetailPage.tsx => EventDetailPage/EventDetailPage.tsx} (79%) create mode 100644 src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetails.tsx rename src/frontend/src/pages/CalendarPage/{DesignReviewDetailPage/FinalizeDesignReviewDetailsModal.tsx => EventDetailPage/FinalizeEventDetailsModal.tsx} (74%) rename src/frontend/src/pages/CalendarPage/{DesignReviewDetailPage => EventDetailPage}/UserAvailabilitesView.tsx (80%) rename src/frontend/src/pages/CalendarPage/{DesignReviewSummaryModal.tsx => EventSummaryModal.tsx} (54%) rename src/frontend/src/pages/CalendarPage/SummaryComponents/{DesignReviewDelayModal.tsx => EventDelayModal.tsx} (67%) rename src/frontend/src/pages/CalendarPage/SummaryComponents/{DesignReviewPill.tsx => EventPill.tsx} (91%) rename src/frontend/src/pages/CalendarPage/SummaryComponents/{DesignReviewSummaryModalAttendees.tsx => EventSummaryModalAttendees.tsx} (71%) rename src/frontend/src/pages/CalendarPage/SummaryComponents/{DesignReviewSummaryModalButtons.tsx => EventSummaryModalButtons.tsx} (78%) rename src/frontend/src/pages/CalendarPage/SummaryComponents/{DesignReviewSummaryModalDetails.tsx => EventSummaryModalDetails.tsx} (56%) rename src/frontend/src/pages/HomePage/components/{DesignReviewCard.tsx => EventCard.tsx} (59%) delete mode 100644 src/frontend/src/tests/hooks/DesignReviews.hooks.test.tsx diff --git a/src/backend/index.ts b/src/backend/index.ts index f958e82b98..ac3887d693 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -12,7 +12,6 @@ import descriptionBulletsRouter from './src/routes/description-bullets.routes'; import tasksRouter from './src/routes/tasks.routes'; import reimbursementRequestsRouter from './src/routes/reimbursement-requests.routes'; import notificationsRouter from './src/routes/notifications.routes'; -import designReviewsRouter from './src/routes/design-reviews.routes'; import wbsElementTemplatesRouter from './src/routes/wbs-element-templates.routes'; import carsRouter from './src/routes/cars.routes'; import organizationRouter from './src/routes/organizations.routes'; @@ -75,7 +74,6 @@ app.use('/change-requests', changeRequestsRouter); app.use('/description-bullets', descriptionBulletsRouter); app.use('/tasks', tasksRouter); app.use('/reimbursement-requests', reimbursementRequestsRouter); -app.use('/design-reviews', designReviewsRouter); app.use('/notifications', notificationsRouter); app.use('/templates', wbsElementTemplatesRouter); app.use('/cars', carsRouter); diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index cbf2d2778f..739e67df9b 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -8,12 +8,11 @@ export default class CalendarController { const { name, calendarIds, - initialDateScheduled, - recurring, - allDay, + schedule, requiredMembers, optionalMembers, teams, + teamType, location, zoomLink, shop, @@ -31,12 +30,11 @@ export default class CalendarController { name, calendarIds, req.organization, - initialDateScheduled, - recurring, - allDay, + schedule, requiredMembers, optionalMembers, teams, + teamType, location, zoomLink, shop, @@ -194,12 +192,11 @@ export default class CalendarController { const { name, calendarIds, - initialDateScheduled, - recurring, - allDay, + schedule, requiredMembers, optionalMembers, teams, + teamType, location, zoomLink, shop, @@ -218,12 +215,11 @@ export default class CalendarController { calendarIds, req.organization, name, - initialDateScheduled, - recurring, - allDay, + schedule, requiredMembers, optionalMembers, teams, + teamType, location, zoomLink, shop, @@ -272,6 +268,7 @@ export default class CalendarController { eventTypeId, memberIds, teamIds, + teamTypeId, shopIds, machineryIds, workPackageIds, @@ -295,6 +292,7 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, + teamTypeId, questionDocument, location, zoomLink, @@ -315,6 +313,7 @@ export default class CalendarController { requiredMemberIds, optionalMemberIds, teamIds, + teamTypeId, status, shopIds, machineryIds, @@ -341,6 +340,7 @@ export default class CalendarController { workPackageIds, documentIds, scheduleSlot, + teamTypeId, questionDocument, location, zoomLink @@ -431,4 +431,24 @@ export default class CalendarController { next(error); } } + + static async getSingleEvent(req: Request, res: Response, next: NextFunction) { + try { + const { eventId } = req.params; + + const event = await CalendarService.getSingleEvent(req.currentUser, eventId, req.organization); + res.status(200).json(event); + } catch (error: unknown) { + next(error); + } + } + + static async getAllEvents(req: Request, res: Response, next: NextFunction) { + try { + const events = await CalendarService.getAllEvents(req.organization); + res.status(200).json(events); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/controllers/design-reviews.controllers.ts b/src/backend/src/controllers/design-reviews.controllers.ts index 979ad3d1f1..defd3f32b5 100644 --- a/src/backend/src/controllers/design-reviews.controllers.ts +++ b/src/backend/src/controllers/design-reviews.controllers.ts @@ -1,3 +1,4 @@ +/* import { NextFunction, Request, Response } from 'express'; import DesignReviewsService from '../services/design-reviews.services'; import { getCurrentUserWithUserSettings } from '../utils/auth.utils'; @@ -133,3 +134,4 @@ export default class DesignReviewsController { } } } +*/ diff --git a/src/backend/src/prisma-query-args/design-reviews.query-args.ts b/src/backend/src/prisma-query-args/design-reviews.query-args.ts index d577cba599..24347a54cc 100644 --- a/src/backend/src/prisma-query-args/design-reviews.query-args.ts +++ b/src/backend/src/prisma-query-args/design-reviews.query-args.ts @@ -1,3 +1,4 @@ +/* import { Prisma } from '@prisma/client'; import { getUserQueryArgs, getUserWithSettingsQueryArgs } from './user.query-args'; @@ -33,3 +34,4 @@ export const getDesignReviewPreviewQueryArgs = (organizationId: string) => userCreated: getUserWithSettingsQueryArgs(organizationId) } }); +*/ diff --git a/src/backend/src/prisma-query-args/event.query-args.ts b/src/backend/src/prisma-query-args/event.query-args.ts index 5a3384e656..c8524dd867 100644 --- a/src/backend/src/prisma-query-args/event.query-args.ts +++ b/src/backend/src/prisma-query-args/event.query-args.ts @@ -6,7 +6,7 @@ export type EventQueryArgs = ReturnType; export const getEventQueryArgs = (organizationId: string) => Prisma.validator()({ include: { - userCreated: getUserQueryArgs(organizationId), + userCreated: getUserWithSettingsQueryArgs(organizationId), requiredMembers: getUserQueryArgs(organizationId), optionalMembers: getUserQueryArgs(organizationId), confirmedMembers: getUserWithSettingsQueryArgs(organizationId), @@ -17,6 +17,12 @@ export const getEventQueryArgs = (organizationId: string) => teamId: true } }, + teamType: { + select: { + teamTypeId: true, + name: true + } + }, shops: { select: { name: true, @@ -33,13 +39,23 @@ export const getEventQueryArgs = (organizationId: string) => select: { wbsElement: { select: { - name: true + name: true, + carNumber: true, + projectNumber: true, + workPackageNumber: true + } + }, + project: { + include: { + wbsElement: true, + teams: true } }, workPackageId: true } }, approvalRequiredBy: getUserQueryArgs(organizationId), - scheduledTimes: true + scheduledTimes: true, + notificationSlackThreads: true } }); diff --git a/src/backend/src/prisma-query-args/work-packages.query-args.ts b/src/backend/src/prisma-query-args/work-packages.query-args.ts index 6bc571f82c..64f8b4bf3e 100644 --- a/src/backend/src/prisma-query-args/work-packages.query-args.ts +++ b/src/backend/src/prisma-query-args/work-packages.query-args.ts @@ -1,8 +1,8 @@ import { Prisma } from '@prisma/client'; import { getUserPreviewQueryArgs, getUserQueryArgs } from './user.query-args'; import { getDescriptionBulletQueryArgs } from './description-bullets.query-args'; -import { getDesignReviewPreviewQueryArgs } from './design-reviews.query-args'; import { getLinkQueryArgs } from './links.query-args'; +import { getEventQueryArgs } from './event.query-args'; export type WorkPackageQueryArgs = ReturnType; export type WorkPackagePreviewQueryArgs = ReturnType; @@ -30,11 +30,11 @@ export const getWorkPackageQueryArgs = (organizationId: string) => orderBy: { dateImplemented: 'asc' } }, blocking: { where: { wbsElement: { dateDeleted: null } }, include: { wbsElement: true } }, - descriptionBullets: { where: { dateDeleted: null }, ...getDescriptionBulletQueryArgs(organizationId) }, - designReviews: { where: { dateDeleted: null }, ...getDesignReviewPreviewQueryArgs(organizationId) } + descriptionBullets: { where: { dateDeleted: null }, ...getDescriptionBulletQueryArgs(organizationId) } } }, - blockedBy: { where: { dateDeleted: null } } + blockedBy: { where: { dateDeleted: null } }, + events: { where: { dateDeleted: null }, ...getEventQueryArgs(organizationId) } } }); diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index 2168cd3ac9..d81116c27e 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -30,7 +30,6 @@ CREATE TABLE "public"."Machinery" ( -- CreateTable CREATE TABLE "public"."Shop_Machinery" ( - "description" TEXT, "shopMachineryId" TEXT NOT NULL, "shopId" TEXT NOT NULL, "machineryId" TEXT NOT NULL, @@ -69,6 +68,7 @@ CREATE TABLE "public"."Event" ( "documentIds" TEXT[], "questionDocument" TEXT, "description" TEXT, + "teamTypeId" TEXT, CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId") ); @@ -96,12 +96,11 @@ CREATE TABLE "public"."Event_Type" ( "dateDeleted" TIMESTAMP(3), "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, - "initialDateScheduled" BOOLEAN NOT NULL DEFAULT FALSE, - "allDay" BOOLEAN NOT NULL DEFAULT FALSE, - "recurring" BOOLEAN NOT NULL DEFAULT FALSE, + "schedule" BOOLEAN NOT NULL DEFAULT FALSE, "optionalMembers" BOOLEAN NOT NULL DEFAULT FALSE, "requiredMembers" BOOLEAN NOT NULL DEFAULT FALSE, "teams" BOOLEAN NOT NULL DEFAULT FALSE, + "teamType" BOOLEAN NOT NULL DEFAULT FALSE, "location" BOOLEAN NOT NULL DEFAULT FALSE, "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, "shop" BOOLEAN NOT NULL DEFAULT FALSE, @@ -309,6 +308,9 @@ ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY -- AddForeignKey ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_approvalRequiredFromUserId_fkey" FOREIGN KEY ("approvalRequiredFromUserId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_teamTypeId_fkey" FOREIGN KEY ("teamTypeId") REFERENCES "public"."Team_Type"("teamTypeId") ON DELETE SET NULL ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; @@ -362,3 +364,325 @@ ALTER TABLE "public"."_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Ty -- AddForeignKey ALTER TABLE "public"."_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Event_Type"("eventTypeId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- Create Event_Types for Design Review (one per organization) +INSERT INTO "public"."Event_Type" ( + "eventTypeId", + "name", + "dateCreated", + "userCreatedId", + "schedule", + "requiredMembers", + "optionalMembers", + "teams", + "teamType", + "location", + "zoomLink", + "shop", + "machinery", + "workPackage", + "questionDocument", + "documents", + "description", + "onlyHeadsOrAboveForEventCreation", + "requiresConfirmation", + "organizationId" +) +SELECT DISTINCT ON (org."organizationId") + gen_random_uuid(), + 'Design Review', + NOW(), + org."userCreatedId", + true, -- schedule + true, -- requiredMembers + true, -- optionalMembers + false, -- teams + true, -- team type + true, -- location + true, -- zoomLink + false, -- shop + false, -- machinery + true, -- workPackage (based on wbsElementId) + true, -- questionDocument (docTemplateLink) + true, -- documents + false, -- description + false, -- onlyHeadsOrAboveForEventCreation + false, -- requiresConfirmation + org."organizationId" +FROM "public"."Organization" org +WHERE EXISTS ( + SELECT 1 FROM "public"."Design_Review" dr + JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId" + WHERE w."organizationId" = org."organizationId" + AND dr."dateDeleted" IS NULL +); + +-- Create Event_Types for Meeting (one per organization) +INSERT INTO "public"."Event_Type" ( + "eventTypeId", + "name", + "dateCreated", + "userCreatedId", + "schedule", + "requiredMembers", + "optionalMembers", + "teams", + "teamType", + "location", + "zoomLink", + "shop", + "machinery", + "workPackage", + "questionDocument", + "documents", + "description", + "onlyHeadsOrAboveForEventCreation", + "requiresConfirmation", + "organizationId" +) +SELECT DISTINCT ON (org."organizationId") + gen_random_uuid(), + 'Meeting', + NOW(), + org."userCreatedId", + true, -- schedule + false, -- requiredMembers + false, -- optionalMembers + true, -- teams + false, -- team type + false, -- location + false, -- zoomLink + false, -- shop + false, -- machinery + false, -- workPackage + false, -- questionDocument + false, -- documents + false, -- description + false, -- onlyHeadsOrAboveForEventCreation + false, -- requiresConfirmation + org."organizationId" +FROM "public"."Organization" org +WHERE EXISTS ( + SELECT 1 FROM "public"."Meeting" m + JOIN "public"."Team" t ON m."teamId" = t."teamId" + WHERE t."organizationId" = org."organizationId" +); + +-- Migrate Design_Review records to Event table +INSERT INTO "public"."Event" ( + "eventId", + "dateCreated", + "dateDeleted", + "title", + "userCreatedId", + "userDeletedId", + "eventTypeId", + "approved", + "approvalRequiredFromUserId", + "location", + "zoomLink", + "documentIds", + "questionDocument", + "description", + "status", + "teamTypeId" +) +SELECT + dr."designReviewId", + dr."dateCreated", + dr."dateDeleted", + 'Design Review - ' || w."name", -- Generate title from WBS element name + dr."userCreatedId", + dr."userDeletedId", + (SELECT et."eventTypeId" + FROM "public"."Event_Type" et + WHERE et."name" = 'Design Review' + AND et."organizationId" = w."organizationId" + LIMIT 1), + CASE WHEN dr."status" IN ('CONFIRMED', 'SCHEDULED', 'DONE') THEN true ELSE false END, + NULL, -- approvalRequiredFromUserId (not in Design_Review) + dr."location", + dr."zoomLink", + CASE WHEN dr."docTemplateLink" IS NOT NULL THEN ARRAY[dr."docTemplateLink"] ELSE ARRAY[]::TEXT[] END, + dr."docTemplateLink", -- questionDocument uses docTemplateLink + NULL, -- description (not in Design_Review) + dr."status", + dr."teamTypeId" +FROM "public"."Design_Review" dr +JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId"; + +-- Create Schedule_Slot records for Design Reviews +-- This creates one slot per time per design review +-- Design Reviews are non-recurring, so endDate = dateScheduled +INSERT INTO "public"."Schedule_Slot" ( + "scheduleSlotId", + "days", + "startTime", + "endTime", + "recurrenceNumber", + "initialDateScheduled", + "endDate", + "allDay" +) +SELECT + gen_random_uuid(), + ARRAY[CASE EXTRACT(DOW FROM dr."dateScheduled") + WHEN 0 THEN 'SUNDAY'::public."DayOfWeek" + WHEN 1 THEN 'MONDAY'::public."DayOfWeek" + WHEN 2 THEN 'TUESDAY'::public."DayOfWeek" + WHEN 3 THEN 'WEDNESDAY'::public."DayOfWeek" + WHEN 4 THEN 'THURSDAY'::public."DayOfWeek" + WHEN 5 THEN 'FRIDAY'::public."DayOfWeek" + WHEN 6 THEN 'SATURDAY'::public."DayOfWeek" + END], + dr."dateScheduled" + ((10 + time_slot) * INTERVAL '1 hour'), -- 10am + time_slot + dr."dateScheduled" + ((11 + time_slot) * INTERVAL '1 hour'), -- End time (1 hour later) + 0, -- No recurrence for design reviews + dr."dateScheduled", -- initialDateScheduled is the actual scheduled date + dr."dateScheduled", -- endDate same as scheduled date (no recurrence) + false +FROM "public"."Design_Review" dr +CROSS JOIN LATERAL unnest(dr."meetingTimes") AS time_slot; + +-- Link Schedule_Slots to Events for Design Reviews +INSERT INTO "public"."_EventToSchedule_Slot" ("A", "B") +SELECT + dr."designReviewId", + ss."scheduleSlotId" +FROM "public"."Design_Review" dr +JOIN "public"."Schedule_Slot" ss ON + ss."initialDateScheduled" = dr."dateScheduled" + AND ss."endDate" = dr."dateScheduled" + AND DATE_PART('hour', ss."startTime") - 10 = ANY(dr."meetingTimes"); + +-- Migrate Design Review member relationships +INSERT INTO "public"."_requiredEventAttendee" ("A", "B") +SELECT dr."designReviewId", ra."B" +FROM "public"."Design_Review" dr +JOIN "public"."_requiredAttendee" ra ON dr."designReviewId" = ra."A"; + +INSERT INTO "public"."_optionalEventAttendee" ("A", "B") +SELECT dr."designReviewId", oa."B" +FROM "public"."Design_Review" dr +JOIN "public"."_optionalAttendee" oa ON dr."designReviewId" = oa."A"; + +INSERT INTO "public"."_confirmedEventAttendee" ("A", "B") +SELECT dr."designReviewId", ca."B" +FROM "public"."Design_Review" dr +JOIN "public"."_confirmedAttendee" ca ON dr."designReviewId" = ca."A"; + +INSERT INTO "public"."_deniedEventAttendee" ("A", "B") +SELECT dr."designReviewId", da."B" +FROM "public"."Design_Review" dr +JOIN "public"."_deniedAttendee" da ON dr."designReviewId" = da."A"; + +-- Link Design Reviews to Work Packages (via wbsElementId) +INSERT INTO "public"."_EventToWork_Package" ("A", "B") +SELECT dr."designReviewId", wp."workPackageId" +FROM "public"."Design_Review" dr +JOIN "public"."Work_Package" wp ON dr."wbsElementId" = wp."wbsElementId"; + +-- Migrate Meeting records to Event table +INSERT INTO "public"."Event" ( + "eventId", + "dateCreated", + "title", + "userCreatedId", + "eventTypeId", + "approved", + "status" +) +SELECT + m."meetingId", + NOW(), + m."title", + t."headId", -- Use the team head as the creator + (SELECT et."eventTypeId" + FROM "public"."Event_Type" et + WHERE et."name" = 'Meeting' + AND et."organizationId" = t."organizationId" + LIMIT 1), + false, -- Meetings aren't pre-approved + 'UNCONFIRMED'::public."Event_Status" +FROM "public"."Meeting" m +JOIN "public"."Team" t ON m."teamId" = t."teamId"; + +-- Create Schedule_Slot records for Meetings +INSERT INTO "public"."Schedule_Slot" ( + "scheduleSlotId", + "days", + "startTime", + "endTime", + "recurrenceNumber", + "initialDateScheduled", + "endDate", + "allDay" +) +SELECT + gen_random_uuid(), + ARRAY[CASE EXTRACT(DOW FROM m."dateSet") + WHEN 0 THEN 'SUNDAY'::public."DayOfWeek" + WHEN 1 THEN 'MONDAY'::public."DayOfWeek" + WHEN 2 THEN 'TUESDAY'::public."DayOfWeek" + WHEN 3 THEN 'WEDNESDAY'::public."DayOfWeek" + WHEN 4 THEN 'THURSDAY'::public."DayOfWeek" + WHEN 5 THEN 'FRIDAY'::public."DayOfWeek" + WHEN 6 THEN 'SATURDAY'::public."DayOfWeek" + END], + m."dateSet" + ((10 + time_slot) * INTERVAL '1 hour'), -- 10am + time_slot + m."dateSet" + ((11 + time_slot) * INTERVAL '1 hour'), -- End time (1 hour later) + CASE WHEN m."recurringInterval" > 0 THEN m."recurringInterval" ELSE 0 END, + m."dateSet"::DATE, + CASE + WHEN m."recurringInterval" > 0 THEN (m."dateSet" + INTERVAL '1 year')::DATE + ELSE m."dateSet"::DATE + END, + false +FROM "public"."Meeting" m +CROSS JOIN LATERAL unnest(m."meetingTimes") AS time_slot; + +-- Link Schedule_Slots to Events for Meetings +INSERT INTO "public"."_EventToSchedule_Slot" ("A", "B") +SELECT + m."meetingId", + ss."scheduleSlotId" +FROM "public"."Meeting" m +JOIN "public"."Schedule_Slot" ss ON + ss."initialDateScheduled" = m."dateSet"::DATE + AND DATE_PART('hour', ss."startTime") - 10 = ANY(m."meetingTimes") + AND ss."recurrenceNumber" = CASE WHEN m."recurringInterval" > 0 THEN m."recurringInterval" ELSE 0 END; + +-- Link Meetings to Teams +INSERT INTO "public"."_affiliatedTeam" ("A", "B") +SELECT m."meetingId", m."teamId" +FROM "public"."Meeting" m; + +ALTER TABLE "Message_Info" ADD COLUMN "eventId" TEXT; + +UPDATE "Message_Info" +SET "eventId" = "designReviewId" +WHERE "designReviewId" IS NOT NULL; + +DROP INDEX IF EXISTS "Message_Info_designReviewId_idx"; + +ALTER TABLE "Message_Info" DROP COLUMN IF EXISTS "designReviewId"; + +CREATE INDEX IF NOT EXISTS "Message_Info_eventId_idx" ON "Message_Info"("eventId"); + +ALTER TABLE "Message_Info" +ADD CONSTRAINT "Message_Info_eventId_fkey" +FOREIGN KEY ("eventId") +REFERENCES "Event"("eventId") +ON DELETE SET NULL +ON UPDATE CASCADE; + +-- Drop old relation tables for Design_Review +DROP TABLE IF EXISTS "public"."_requiredAttendee" CASCADE; +DROP TABLE IF EXISTS "public"."_optionalAttendee" CASCADE; +DROP TABLE IF EXISTS "public"."_confirmedAttendee" CASCADE; +DROP TABLE IF EXISTS "public"."_deniedAttendee" CASCADE; +DROP TABLE IF EXISTS "public"."_userAttended" CASCADE; + +-- Drop the old Meeting and Design_Review tables +DROP TABLE IF EXISTS "public"."Meeting" CASCADE; +DROP TABLE IF EXISTS "public"."Design_Review" CASCADE; \ No newline at end of file diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index d1cd7cbb3c..be459e11b4 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -201,13 +201,6 @@ model User { archivedTeams Team[] @relation(name: "userArchived") createdMaterialTypes Material_Type[] @relation(name: "materialTypeCreator") createdManufacturers Manufacturer[] @relation(name: "manufacturerCreator") - requiredDesignReviews Design_Review[] @relation(name: "requiredAttendee") - optionalDesignReviews Design_Review[] @relation(name: "optionalAttendee") - userConfirmedDesignReviews Design_Review[] @relation(name: "confirmedAttendee") - userDeniedDesignReviews Design_Review[] @relation(name: "deniedAttendee") - attendedDesignReviews Design_Review[] @relation(name: "userAttended") - createdDesignReviews Design_Review[] @relation(name: "designReviewCreator") - deletedDesignReviews Design_Review[] @relation(name: "designReviewDeleter") drScheduleSettings Schedule_Settings? wbsProposedlead Wbs_Proposed_Changes[] @relation(name: "wbslead") wbsProposedmanager Wbs_Proposed_Changes[] @relation(name: "wbsmanager") @@ -305,7 +298,6 @@ model Team { dateArchived DateTime? userArchivedId String? userArchived User? @relation(name: "userArchived", fields: [userArchivedId], references: [userId]) - meetings Meeting[] proposedProjectChanges Project_Proposed_Changes[] @relation(name: "proposedProjectTeams") teamType Team_Type? @relation(fields: [teamTypeId], references: [teamTypeId]) teamTypeId String? @@ -380,13 +372,13 @@ model Message_Info { changeRequestId String? changeRequest Change_Request? @relation(fields: [changeRequestId], references: [crId]) - designReviewId String? - designReview Design_Review? @relation(fields: [designReviewId], references: [designReviewId]) + eventId String? + event Event? @relation(fields: [eventId], references: [eventId]) reimbursementRequestId String? reimbursementRequest Reimbursement_Request? @relation(fields: [reimbursementRequestId], references: [reimbursementRequestId]) @@index([reimbursementRequestId]) - @@index([designReviewId]) + @@index([eventId]) @@index([changeRequestId]) } @@ -515,7 +507,6 @@ model WBS_Element { assemblies Assembly[] materials Material[] reimbursementProductReasons Reimbursement_Product_Reason[] - designReviews Design_Review[] proposedBlockedByChanges Work_Package_Proposed_Changes[] @relation(name: "proposedBlockedBy") descriptionBullets Description_Bullet[] organizationId String @@ -1000,11 +991,9 @@ model Machinery { events Event[] organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) - } model Shop_Machinery { - description String? shopMachineryId String @id @default(uuid()) shopId String machineryId String @@ -1062,6 +1051,8 @@ model Event { confirmedMembers User[] @relation(name: "confirmedEventAttendee") deniedMembers User[] @relation(name: "deniedEventAttendee") teams Team[] @relation(name: "affiliatedTeam") + teamType Team_Type? @relation(fields: [teamTypeId], references: [teamTypeId]) + teamTypeId String? location String? zoomLink String? shops Shop[] @@ -1071,6 +1062,7 @@ model Event { status Event_Status questionDocument String? description String? + notificationSlackThreads Message_Info[] } model Calendar { @@ -1087,7 +1079,6 @@ model Calendar { eventTypes Event_Type[] organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) - } model Event_Type { @@ -1100,12 +1091,11 @@ model Event_Type { userDeletedId String? userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventTypeDeleter") calendars Calendar[] - initialDateScheduled Boolean - allDay Boolean - recurring Boolean + schedule Boolean requiredMembers Boolean optionalMembers Boolean teams Boolean + teamType Boolean location Boolean zoomLink Boolean shop Boolean @@ -1119,65 +1109,31 @@ model Event_Type { events Event[] organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) - } model Team_Type { - teamTypeId String @id @default(uuid()) + teamTypeId String @id @default(uuid()) name String iconName String - designReviews Design_Review[] teams Team[] - description String @default("") + description String @default("") imageFileId String? organizationId String - organization Organization @relation(fields: [organizationId], references: [organizationId]) + organization Organization @relation(fields: [organizationId], references: [organizationId]) calendarId String? checklists Checklist[] - usersOnboarding User[] @relation(name: "onboardingTeamTypes") - usersOnboarded User[] @relation(name: "onboardedTeamTypes") + usersOnboarding User[] @relation(name: "onboardingTeamTypes") + usersOnboarded User[] @relation(name: "onboardedTeamTypes") dateDeleted DateTime? deletedById String? deletedBy User? @relation(name: "teamTypeDeleter", fields: [deletedById], references: [userId]) + events Event[] @@unique([name, organizationId], name: "uniqueTeamType") @@index([organizationId]) } -model Design_Review { - designReviewId String @id @default(uuid()) - dateScheduled DateTime @db.Date - // Meeting times are an integer between 0 and 11 from 10am - 10pm for the date scheduled at hour intervals - meetingTimes Int[] - initialDateScheduled DateTime @db.Date - dateCreated DateTime @default(now()) @db.Timestamp(3) - userCreated User @relation(fields: [userCreatedId], references: [userId], name: "designReviewCreator") - userCreatedId String - status Event_Status - teamType Team_Type @relation(fields: [teamTypeId], references: [teamTypeId]) - teamTypeId String - requiredMembers User[] @relation(name: "requiredAttendee") - optionalMembers User[] @relation(name: "optionalAttendee") - confirmedMembers User[] @relation(name: "confirmedAttendee") - deniedMembers User[] @relation(name: "deniedAttendee") - location String? - isOnline Boolean - isInPerson Boolean - zoomLink String? - attendees User[] @relation(name: "userAttended") - dateDeleted DateTime? @db.Timestamp(3) - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "designReviewDeleter") - userDeletedId String? - docTemplateLink String? - wbsElementId String - wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) - notificationSlackThreads Message_Info[] - calendarEventId String? - - @@index([teamTypeId]) -} - model Availability { availabilityId String @id @default(uuid()) scheduleSettingsId String @@ -1199,18 +1155,6 @@ model Schedule_Settings { availabilities Availability[] } -model Meeting { - meetingId String @id @default(uuid()) - title String - - dateSet DateTime - recurringInterval Int // the number of days between each meeting (0 = no recurring) - // meetingTimes are integers between 0 and 11 representing time from 10am - 10pm on the date the meeting is set for at hour intervals see meetingTime field in Design_Review - meetingTimes Int[] - team Team? @relation(fields: [teamId], references: [teamId]) - teamId String -} - model Wbs_Proposed_Changes { wbsProposedChangesId String @id @default(uuid()) name String diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 25c70e7130..3cda2f063c 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -24,7 +24,7 @@ import ChangeRequestsService from '../services/change-requests.services'; import TeamsService from '../services/teams.services'; import { DayOfWeek, - DesignReviewStatus, + Review_Status, MaterialStatus, RoleEnum, StandardChangeRequest, @@ -37,7 +37,6 @@ import { seedWorkPackage } from './seed-data/work-packages.seed'; import ReimbursementRequestService from '../services/reimbursement-requests.services'; import ProjectsService from '../services/projects.services'; import { Decimal } from 'decimal.js'; -import DesignReviewsService from '../services/design-reviews.services'; import BillOfMaterialsService from '../services/boms.services'; import UsersService from '../services/users.services'; import { transformDate } from '../utils/datetime.utils'; @@ -2345,6 +2344,7 @@ const performSeed: () => Promise = async () => { const nextDay = new Date(); nextDay.setDate(nextDay.getDate() + 1); + /* const designReview1 = await DesignReviewsService.createDesignReview( batman, nextDay.toDateString(), @@ -2377,6 +2377,7 @@ const performSeed: () => Promise = async () => { [1, 2, 3, 4, 5, 6, 7], ner ); + */ const newWorkPackageChangeRequest = await ChangeRequestsService.createStandardChangeRequest( batman, @@ -3175,11 +3176,10 @@ const performSeed: () => Promise = async () => { [calendar.calendarId], ner, true, - true, - true, false, false, true, + false, true, true, false, @@ -3201,11 +3201,10 @@ const performSeed: () => Promise = async () => { true, true, true, - true, - true, false, true, true, + true, false, false, true, @@ -3223,13 +3222,12 @@ const performSeed: () => Promise = async () => { [], ner, true, - false, - false, true, true, false, false, false, + false, true, true, true, @@ -3248,8 +3246,7 @@ const performSeed: () => Promise = async () => { ner, true, true, - true, - true, + false, false, false, false, @@ -3286,6 +3283,7 @@ const performSeed: () => Promise = async () => { allDay: false } ], + mechanical.teamTypeId, undefined, 'Conference Room A', 'https://zoom.us/j/123456789', @@ -3314,6 +3312,7 @@ const performSeed: () => Promise = async () => { allDay: false } ], + software.teamTypeId, 'https://docs.google.com/document/d/2_example', 'Conference Room B', 'https://zoom.us/j/987654321', @@ -3342,6 +3341,7 @@ const performSeed: () => Promise = async () => { allDay: false } ], + electrical.teamTypeId, 'https://docs.google.com/document/d/3_example', undefined, undefined, @@ -3370,6 +3370,7 @@ const performSeed: () => Promise = async () => { allDay: false } ], + mechanical.teamTypeId, undefined, undefined, undefined, diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index f2a1301c91..7c10676608 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -19,12 +19,11 @@ calendarRouter.post( nonEmptyString(body('name')), body('calendarIds').isArray(), body('calendarIds.*').isString(), - body('initialDateScheduled').isBoolean(), - body('allDay').isBoolean(), - body('recurring').isBoolean(), + body('schedule').isBoolean(), body('requiredMembers').isBoolean(), body('optionalMembers').isBoolean(), body('teams').isBoolean(), + body('teamType').isBoolean(), body('location').isBoolean(), body('zoomLink').isBoolean(), body('shop').isBoolean(), @@ -44,12 +43,11 @@ calendarRouter.post( nonEmptyString(body('name')), body('calendarIds').isArray(), body('calendarIds.*').isString(), - body('initialDateScheduled').isBoolean(), - body('allDay').isBoolean(), - body('recurring').isBoolean(), + body('schedule').isBoolean(), body('requiredMembers').isBoolean(), body('optionalMembers').isBoolean(), body('teams').isBoolean(), + body('teamType').isBoolean(), body('location').isBoolean(), body('zoomLink').isBoolean(), body('shop').isBoolean(), @@ -74,6 +72,7 @@ calendarRouter.post( nonEmptyString(body('optionalMemberIds.*')), body('teamIds').isArray(), body('teamIds.*').isString(), + body('teamTypeId').optional().isString(), body('location').optional().isString(), body('zoomLink').optional().isURL(), body('shopIds').isArray(), @@ -107,6 +106,7 @@ calendarRouter.post( nonEmptyString(body('optionalMemberIds.*')), body('teamIds').isArray(), body('teamIds.*').isString(), + body('teamTypeId').optional().isString(), isEventStatus(body('status')), body('location').optional().isString(), body('zoomLink').optional().isURL(), @@ -153,6 +153,10 @@ calendarRouter.post( calendarRouter.post('/event/:eventId/delete', CalendarController.deleteEvent); +calendarRouter.get('/event/:eventId', CalendarController.getSingleEvent); + +calendarRouter.get('/events', CalendarController.getAllEvents); + calendarRouter.post('/machinery/create', nonEmptyString(body('name')), validateInputs, CalendarController.createMachinery); calendarRouter.post( diff --git a/src/backend/src/routes/design-reviews.routes.ts b/src/backend/src/routes/design-reviews.routes.ts index 3b08a7185f..07e2fce4c5 100644 --- a/src/backend/src/routes/design-reviews.routes.ts +++ b/src/backend/src/routes/design-reviews.routes.ts @@ -1,3 +1,4 @@ +/* import express from 'express'; import { body } from 'express-validator'; import { intMinZero, nonEmptyString, isDate, isEventStatus, validateInputs } from '../utils/validation.utils'; @@ -66,3 +67,4 @@ designReviewsRouter.post( ); export default designReviewsRouter; +*/ diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index ea287535af..026b2f9c1c 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -45,6 +45,14 @@ import { } from '../utils/calendar.utils'; import { UserWithSettings } from '../utils/auth.utils'; import { getUserScheduleSettingsQueryArgs } from '../prisma-query-args/user.query-args'; +import { + sendDREventConfirmationToThread, + sendDREventScheduledSlackNotif, + sendDREventUserConfirmationToThread, + sendSlackDesignReviewEventConfirmNotification, + sendSlackDREventNotifications +} from '../utils/slack.utils'; +import { sendDrEventPopUp } from '../utils/pop-up.utils'; export default class CalendarService { /** @@ -54,12 +62,11 @@ export default class CalendarService { * @param name The name of the event type. * @param calendarIds An array of the calendars this event type is associated with. * @param organization The organization for which the event type is being created. - * @param initialDateScheduled Determines if a date is associated with this event type. - * @param recurring Determines if this event type is recurring. - * @param allDay Determines if this event type is all day. + * @param schedule Determines if a date is associated with this event type. * @param requiredMembers Determines if this event type has required members. * @param optionalMembers Determines if this event type has optional members. * @param teams Determines if this event type has teams. + * @param teamType Determines if this event type has a team type. * @param location Determines if this event type has a location. * @param zoomLink Determines if this event type has a zoom link. * @param shop Determines if a shop is associated with this event type. @@ -81,12 +88,11 @@ export default class CalendarService { name: string, calendarIds: string[], organization: Organization, - initialDateScheduled: boolean, - recurring: boolean, - allDay: boolean, + schedule: boolean, requiredMembers: boolean, optionalMembers: boolean, teams: boolean, + teamType: boolean, location: boolean, zoomLink: boolean, shop: boolean, @@ -141,12 +147,11 @@ export default class CalendarService { connect: calendarIds.map((calendarId) => ({ calendarId })) }, userCreatedId: submitter.userId, - initialDateScheduled, - recurring, - allDay, + schedule, requiredMembers, optionalMembers, teams, + teamType, location, zoomLink, shop, @@ -216,6 +221,8 @@ export default class CalendarService { * @param organization The organization for which the event type is being created. * @param requiredMemberIds An array of required member ids that are invited to the event. * @param optionalMemberIds An array of optional member ids that are invited to the event. + * @param teamIds An array of team ids that are invited to the event. + * @param teamTypeId The team type id invited to the event. * @param shopIds An array of shops associated with the event. * @param machineryIds An array of machinery associated with the event. * @param workPackageIds An array of work packages associated with the event. @@ -244,6 +251,7 @@ export default class CalendarService { workPackageIds: string[], documentIds: string[], scheduleSlot: ScheduleSlotCreateArgs[], + teamTypeId?: string, questionDocument?: string, location?: string, zoomLink?: string, @@ -272,6 +280,7 @@ export default class CalendarService { requiredMemberIds, optionalMemberIds, teamIds, + teamTypeId, shopIds, machineryIds, workPackageIds, @@ -380,6 +389,18 @@ export default class CalendarService { } } + if (teamTypeId) { + // Validate team type + const foundTeamType = await prisma.team_Type.findUnique({ + where: { + teamTypeId + } + }); + if (!foundTeamType) { + throw new NotFoundException('Team Type', teamTypeId); + } + } + // Check for conflicts const { hasConflict, approverUserId } = await checkEventConflicts(scheduleSlot, organization, location, undefined); @@ -415,6 +436,7 @@ export default class CalendarService { teams: { connect: teamIds.map((teamId) => ({ teamId })) }, + teamTypeId, shops: { connect: shopIds.map((shopId) => ({ shopId })) }, @@ -447,6 +469,69 @@ export default class CalendarService { ...getEventQueryArgs(organization.organizationId) }); + if (workPackageIds.length > 0) { + const members = await prisma.user.findMany({ + where: { userId: { in: optionalMemberIds.concat(requiredMemberIds) } } + }); + + if (!members) { + throw new NotFoundException('User', 'Cannot find members who are invited to the design review'); + } + + // get the user settings for all the members invited, who are leaderingship + const memberUserSettings = await prisma.user_Settings.findMany({ + where: { userId: { in: members.map((member) => member.userId) } } + }); + + if (!memberUserSettings) { + throw new NotFoundException('User Settings', 'Cannot find settings of members'); + } + + const workPackageNames = newEvent.workPackages.map((wp) => wp.wbsElement.name).join(', '); + + const projects = newEvent.workPackages.map((wp) => wp.project); + + // Send a slack message to all members invited to the design review + for (const memberUserSetting of memberUserSettings) { + if (memberUserSetting.slackId) { + try { + // For each project associated with this event + for (const project of projects) { + await sendSlackDesignReviewEventConfirmNotification( + memberUserSetting.slackId, + newEvent.eventId, + newEvent.title, + project.wbsElement.name + ); + } + } catch (err: unknown) { + if (err instanceof Error) { + throw new HttpException(500, `Failed to send slack notification: ${err.message}`); + } + } + } + } + + // Send popup notification + await sendDrEventPopUp(newEvent, members, submitter, workPackageNames, organization.organizationId); + + const createdEvent = eventTransformer(newEvent); + + for (const project of projects) { + const projectTeams = project.teams; + if (projectTeams.length > 0) { + await sendSlackDREventNotifications( + projectTeams, + createdEvent, + submitter, + workPackageNames, + project.wbsElement.name + ); + } + } + return createdEvent; + } + return eventTransformer(newEvent); } @@ -460,6 +545,8 @@ export default class CalendarService { * @param requiredMemberIds An array of required member ids that are invited to the event. * @param optionalMemberIds An array of optional member ids that are invited to the event. * @param status see Event_Status enum + * @param teamIds An array of teams invited to the event. + * @param teamType Team type Id invited to the event. * @param shopIds An array of shops associated with the event. * @param machineryIds An array of machinery associated with the event. * @param workPackageIds An array of work packages associated with the event. @@ -489,6 +576,7 @@ export default class CalendarService { workPackageIds: string[], documentIds: string[], scheduleSlot: ScheduleSlotCreateArgs[], + teamTypeId?: string, questionDocument?: string, location?: string, zoomLink?: string, @@ -516,6 +604,7 @@ export default class CalendarService { requiredMemberIds, optionalMemberIds, teamIds, + teamTypeId, shopIds, machineryIds, workPackageIds, @@ -653,6 +742,18 @@ export default class CalendarService { } } + if (teamTypeId) { + // Validate team type + const foundTeamType = await prisma.team_Type.findMany({ + where: { + teamTypeId + } + }); + if (!foundTeamType) { + throw new NotFoundException('Team Type', teamTypeId); + } + } + // Use transaction for the update const updatedEvent = await prisma.$transaction(async (tx) => { // Fetch existing schedule slots @@ -765,6 +866,7 @@ export default class CalendarService { teams: { set: teamIds.map((teamId) => ({ teamId })) }, + ...(teamTypeId !== undefined && { teamTypeId }), status: newStatus, shops: { set: shopIds.map((shopId) => ({ shopId })) @@ -794,7 +896,13 @@ export default class CalendarService { }); }); - return eventTransformer(updatedEvent); + const edittedEvent = eventTransformer(updatedEvent); + + if (status === Event_Status.SCHEDULED && workPackageIds.length > 0) { + await sendDREventScheduledSlackNotif(updatedEvent.notificationSlackThreads, edittedEvent); + } + + return edittedEvent; } /** @@ -903,8 +1011,9 @@ export default class CalendarService { } }); - // possibly want to do - //await sendDRUserConfirmationToThread(updatedDesignReview.notificationSlackThreads, submitter); + if (updatedEvent.workPackages.length > 0) { + await sendDREventUserConfirmationToThread(updatedEvent.notificationSlackThreads, submitter); + } // If all required attendees have confirmed their schedule and this member was a required attendee, mark design review as confirmed if ( @@ -918,8 +1027,9 @@ export default class CalendarService { status: Event_Status.CONFIRMED } }); - - //await sendDRConfirmationToThread(updatedDesignReview.notificationSlackThreads, updatedDesignReview.userCreated); + if (updatedEvent.workPackages.length > 0) { + await sendDREventConfirmationToThread(updatedEvent.notificationSlackThreads, updatedEvent.userCreated); + } } return eventTransformer(updatedEvent); @@ -1629,12 +1739,11 @@ export default class CalendarService { * @param name The name of the event type. * @param calendarIds An array of the calendars this event type is associated with. * @param organization The organization for which the event type is being created. - * @param initialDateScheduled Determines if a date is associated with this event type. - * @param recurring Determines if this event type is recurring. - * @param allDay Determines if this event type is all day. + * @param schedule Determines if a date is associated with this event type. * @param requiredMembers Determines if this event type has required members. * @param optionalMembers Determines if this event type has optional members. * @param teams Determines if this event type has teams. + * @param teamType Determines if this event type has team types. * @param location Determines if this event type has a location. * @param zoomLink Determines if this event type has a zoom link. * @param shop Determines if a shop is associated with this event type. @@ -1657,12 +1766,11 @@ export default class CalendarService { calendarIds: string[], organization: Organization, name: string, - initialDateScheduled: boolean, - recurring: boolean, - allDay: boolean, + schedule: boolean, requiredMembers: boolean, optionalMembers: boolean, teams: boolean, + teamType: boolean, location: boolean, zoomLink: boolean, shop: boolean, @@ -1717,12 +1825,11 @@ export default class CalendarService { calendars: { connect: calendarIds.map((calendarId) => ({ calendarId })) }, - initialDateScheduled, - recurring, - allDay, + schedule, requiredMembers, optionalMembers, teams, + teamType, location, zoomLink, shop, @@ -2038,4 +2145,38 @@ export default class CalendarService { return machineryTransformer(deleted); } + + /** + * Retrieves a single event + * + * @param submitter the user who is trying to retrieve the event + * @param designReviewId the id of the event to retrieve + * @param organizationId the organization that the user is currently in + * @returns the event + */ + static async getSingleEvent(_submitter: User, eventId: string, organization: Organization): Promise { + const event = await prisma.event.findUnique({ + where: { eventId }, + ...getEventQueryArgs(organization.organizationId) + }); + + if (!event) throw new NotFoundException('Event', eventId); + + if (event.dateDeleted) throw new DeletedException('Event', eventId); + + return eventTransformer(event); + } + + /** + * Gets all events in the database + * @param organizationId the organization id of the current user + * @returns All of the events + */ + static async getAllEvents(organization: Organization): Promise { + const events = await prisma.event.findMany({ + where: { dateDeleted: null }, + ...getEventQueryArgs(organization.organizationId) + }); + return events.map(eventTransformer); + } } diff --git a/src/backend/src/services/design-reviews.services.ts b/src/backend/src/services/design-reviews.services.ts index a215b9b38a..61f92a2115 100644 --- a/src/backend/src/services/design-reviews.services.ts +++ b/src/backend/src/services/design-reviews.services.ts @@ -1,3 +1,4 @@ +/* import { Event_Status, Team_Type, Organization } from '@prisma/client'; import { DesignReview, @@ -48,6 +49,7 @@ export default class DesignReviewsService { * @param organizationId the organization id of the current user * @returns All of the design reviews */ +/* static async getAllDesignReviews(organization: Organization): Promise { const designReviews = await prisma.design_Review.findMany({ where: { dateDeleted: null, wbsElement: { organizationId: organization.organizationId } }, @@ -62,6 +64,7 @@ export default class DesignReviewsService { * @param designReviewId the id of the design review to be deleted * @param organizationId the organization that the user is currently in */ +/* static async deleteDesignReview( submitter: User, designReviewId: string, @@ -114,6 +117,7 @@ export default class DesignReviewsService { * @param organizationId the organization that the user is currently in * @returns a new design review */ +/* static async createDesignReview( submitter: User, initialDate: string, @@ -230,6 +234,7 @@ export default class DesignReviewsService { * @param organizationId the organization that the user is currently in * @returns the design review */ +/* static async getSingleDesignReview( _submitter: User, designReviewId: string, @@ -267,6 +272,7 @@ export default class DesignReviewsService { * @param meetingTimes meeting time must be between 0-83 (representing 1hr increments from 10am 10pm, Monday-Sunday) * @param organizationId the organization that the user is currently in */ +/* static async editDesignReview( user: User, @@ -409,6 +415,7 @@ export default class DesignReviewsService { * @param organizationId the organization that the user is currently in * @returns the modified design review with its updated confirmedMembers */ +/* static async markUserConfirmed( designReviewId: string, availabilities: AvailabilityCreateArgs[], @@ -499,6 +506,7 @@ export default class DesignReviewsService { * @param organizationId the organization that the user is currently in * @returns the modified design review */ +/* static async setStatus( user: User, designReviewId: string, @@ -541,6 +549,7 @@ export default class DesignReviewsService { * @param organizationId The organization that the user is currently in * @returns The retrieved Team Type */ +/* static async getSingleTeamType(teamTypeId: string, organization: Organization): Promise { const teamType = await prisma.team_Type.findUnique({ where: { teamTypeId } @@ -552,3 +561,4 @@ export default class DesignReviewsService { return teamType; } } +*/ diff --git a/src/backend/src/services/notifications.services.ts b/src/backend/src/services/notifications.services.ts index d0365b840b..48e156d045 100644 --- a/src/backend/src/services/notifications.services.ts +++ b/src/backend/src/services/notifications.services.ts @@ -1,23 +1,24 @@ import prisma from '../prisma/prisma'; import { - DesignReviewWithAttendees, TaskWithAssignees, endOfDayTomorrow, startOfDayTomorrow, - usersToSlackPings + usersToSlackPings, + EventWithAttendees } from '../utils/notifications.utils'; import { sendMessage } from '../integrations/slack'; -import { daysBetween, meetingStartTimePipe, startOfDay, wbsPipe } from 'shared'; +import { daysBetween, meetingStartTimePipeNumbers, startOfDay, wbsPipe } from 'shared'; import { buildDueString, sendThreadResponse } from '../utils/slack.utils'; import WorkPackagesService from './work-packages.services'; import { addWeeksToDate } from 'shared'; import { HttpException } from '../utils/errors.utils'; import { Reimbursement_Status_Type } from '@prisma/client'; +import { scheduleTimesTransformer } from '../transformers/calendar.transformer'; export default class NotificationsService { static async sendDailySlackNotifications() { await NotificationsService.sendTaskDeadlineSlackNotifications(); - await NotificationsService.sendDesignReviewSlackNotifications(); + await NotificationsService.sendDesignReviewEventSlackNotifications(); await NotificationsService.sendWorkPackageDeadlineSlackNotifications(); await NotificationsService.sendSponsorTaskNotifications(); await NotificationsService.sendPendingSaboSubmissionNotifications(); @@ -119,70 +120,94 @@ export default class NotificationsService { /** * Sends the design review slack notifications for all design reviews scheduled for today */ - static async sendDesignReviewSlackNotifications() { + static async sendDesignReviewEventSlackNotifications() { const endOfToday = startOfDayTomorrow(); const startOfToday = startOfDay(new Date()); - const designReviews = await prisma.design_Review.findMany({ + const designReviewEvents = await prisma.event.findMany({ where: { - dateScheduled: { - lt: endOfToday, - gte: startOfToday - }, status: 'SCHEDULED', - dateDeleted: null + dateDeleted: null, + workPackages: { + some: {} // Event must have at least one work package to be a design review + }, + scheduledTimes: { + some: { + initialDateScheduled: { + lte: endOfToday, + gte: startOfToday + } + } + } }, include: { requiredMembers: { include: { userSettings: true } }, optionalMembers: { include: { userSettings: true } }, userCreated: { include: { userSettings: true } }, - wbsElement: { + scheduledTimes: true, + workPackages: { include: { - project: { include: { teams: true } }, - workPackage: { include: { project: { include: { teams: true } } } } + wbsElement: true, + project: { + include: { + teams: true, + wbsElement: true + } + } } } } }); - const designReviewTeamMap = new Map(); + const desginReviewEventTeamMap = new Map(); - designReviews.forEach((designReview) => { - const teamSlackIds = designReview.wbsElement.project - ? designReview.wbsElement.project.teams.map((team) => team.slackId) - : (designReview.wbsElement.workPackage?.project.teams.map((team) => team.slackId) ?? []); + designReviewEvents.forEach((event) => { + // Get all unique teams from all work packages associated with this event + const teamSlackIds = new Set(); + + event.workPackages.forEach((workPackage) => { + workPackage.project.teams.forEach((team) => { + if (team.slackId) { + teamSlackIds.add(team.slackId); + } + }); + }); teamSlackIds.forEach((teamSlackId) => { - const currentTasks = designReviewTeamMap.get(teamSlackId); - if (currentTasks) { - currentTasks.push({ - ...designReview, - attendees: designReview.requiredMembers.concat(designReview.optionalMembers).concat(designReview.userCreated) - }); - designReviewTeamMap.set(teamSlackId, currentTasks); + const currentEvents = desginReviewEventTeamMap.get(teamSlackId); + const eventWithAttendees = { + ...event, + attendees: event.requiredMembers.concat(event.optionalMembers).concat(event.userCreated), + scheduledTimes: event.scheduledTimes.map(scheduleTimesTransformer) + }; + + if (currentEvents) { + currentEvents.push(eventWithAttendees); } else { - designReviewTeamMap.set(teamSlackId, [ - { - ...designReview, - attendees: designReview.requiredMembers.concat(designReview.optionalMembers).concat(designReview.userCreated) - } - ]); + desginReviewEventTeamMap.set(teamSlackId, [eventWithAttendees]); } }); }); - // send the notifications to each team for their respective design reviews - const promises = Array.from(designReviewTeamMap).map(async ([slackId, designReviews]) => { - const messageBlock = designReviews - .map((designReview) => { - const zoomLink = designReview.zoomLink ? `<${designReview.zoomLink}|Zoom Link>\n` : ''; - const questionDocLink = designReview.docTemplateLink - ? `<${designReview.docTemplateLink}|Question Doc Link>\n` - : ''; + // Send the notifications to each team for their respective design reviews + const promises = Array.from(desginReviewEventTeamMap).map(async ([slackId, events]) => { + const messageBlock = events + .map((event) => { + const zoomLink = event.zoomLink ? `<${event.zoomLink}|Zoom Link>\n` : ''; + const questionDocLink = event.questionDocument ? `<${event.questionDocument}|Question Doc Link>\n` : ''; + + // Get work package names for this event + const workPackageNames = event.workPackages.map((wp) => wp.wbsElement.name).join(', '); + + // Extract meeting times from scheduled slots + const meetingTimes = event.scheduledTimes + .map((slot) => (slot.startTime ? new Date(slot.startTime).getHours() : null)) + .filter((hour): hour is number => hour !== null) + .sort((a, b) => a - b); + return ( - `${usersToSlackPings(designReview.attendees ?? [])} ${ - designReview.wbsElement.name - } will be having a design review today at ${meetingStartTimePipe(designReview.meetingTimes)}! ` + + `${usersToSlackPings(event.attendees ?? [])} ${event.title} (${workPackageNames}) ` + + `will be having an event today at ${meetingStartTimePipeNumbers(meetingTimes)}! ` + zoomLink + questionDocLink ); diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index b5e27875f3..1e28d28c4b 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -1,5 +1,16 @@ -import { Prisma } from '@prisma/client'; -import { Machinery, Shop, ShopMachinery, EventType, Calendar, Event, ScheduleSlot, DayOfWeek, EventStatus } from 'shared'; +import { Prisma, DayOfWeek as PrismaDayOfWeek, Event_Status as PrismaEventStatus } from '@prisma/client'; +import { + Machinery, + Shop, + ShopMachinery, + EventType, + Calendar, + Event, + ScheduleSlot, + EventStatus, + EventPreview, + DayOfWeek +} from 'shared'; import { MachineryQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { userTransformer, userWithScheduleSettingsTransformer } from './user.transformer'; import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; @@ -23,8 +34,7 @@ export const shopMachineryTransformer = ( return { shopMachineryId: shopMachinery.shopMachineryId, shop: shopTransformer(shopMachinery.shop), - quantity: shopMachinery.quantity, - description: shopMachinery.description ?? undefined + quantity: shopMachinery.quantity }; }; @@ -44,12 +54,11 @@ export const eventTypeTransformer = (eventType: Prisma.Event_TypeGetPayload): ScheduleSlot => { return { scheduleSlotId: scheduleTimes.scheduleSlotId, - days: scheduleTimes.days.map((d) => d as DayOfWeek), + days: scheduleTimes.days.map(dayOfWeekTransformer), startTime: scheduleTimes.startTime ?? undefined, endTime: scheduleTimes.endTime ?? undefined, recurrenceNumber: scheduleTimes.recurrenceNumber, @@ -99,6 +108,7 @@ export const eventTransformer = (event: Prisma.EventGetPayload): confirmedMembers: event.confirmedMembers.map(userWithScheduleSettingsTransformer), deniedMembers: event.deniedMembers.map(userTransformer), teams: event.teams, + teamType: event.teamType ?? undefined, shops: event.shops, machinery: event.machinery, workPackages: event.workPackages, @@ -110,6 +120,43 @@ export const eventTransformer = (event: Prisma.EventGetPayload): zoomLink: event.zoomLink ?? undefined, questionDocument: event.questionDocument ?? undefined, description: event.description ?? undefined, - status: event.status as EventStatus + status: eventStatusTransformer(event.status) }; }; + +export const eventPreviewTransformer = (event: Prisma.EventGetPayload, wbsName: string): EventPreview => { + // Get the earliest scheduled date from scheduledTimes + const dateScheduled = event.scheduledTimes.length > 0 ? event.scheduledTimes[0].initialDateScheduled : new Date(); + + return { + eventId: event.eventId, + title: event.title, + dateScheduled, + status: event.status as EventStatus, + userCreated: userTransformer(event.userCreated), + wbsName + }; +}; + +export const dayOfWeekTransformer = (day: PrismaDayOfWeek): DayOfWeek => { + const mapping: Record = { + MONDAY: DayOfWeek.MONDAY, + TUESDAY: DayOfWeek.TUESDAY, + WEDNESDAY: DayOfWeek.WEDNESDAY, + THURSDAY: DayOfWeek.THURSDAY, + FRIDAY: DayOfWeek.FRIDAY, + SATURDAY: DayOfWeek.SATURDAY, + SUNDAY: DayOfWeek.SUNDAY + }; + return mapping[day]; +}; + +export const eventStatusTransformer = (status: PrismaEventStatus): EventStatus => { + const mapping: Record = { + UNCONFIRMED: EventStatus.UNCONFIRMED, + CONFIRMED: EventStatus.CONFIRMED, + SCHEDULED: EventStatus.SCHEDULED, + DONE: EventStatus.DONE + }; + return mapping[status]; +}; diff --git a/src/backend/src/transformers/design-reviews.transformer.ts b/src/backend/src/transformers/design-reviews.transformer.ts index 86cd515f52..b614a6ea77 100644 --- a/src/backend/src/transformers/design-reviews.transformer.ts +++ b/src/backend/src/transformers/design-reviews.transformer.ts @@ -1,3 +1,4 @@ +/* import { Prisma } from '@prisma/client'; import { DesignReview, DesignReviewPreview, DesignReviewStatus, isProjectWbs } from 'shared'; import { wbsNumOf } from '../utils/utils'; @@ -50,3 +51,4 @@ export const designReviewPreviewTransformer = ( wbsName }; }; +*/ diff --git a/src/backend/src/transformers/work-packages.transformer.ts b/src/backend/src/transformers/work-packages.transformer.ts index 7d38bc6230..efdb7c3b6d 100644 --- a/src/backend/src/transformers/work-packages.transformer.ts +++ b/src/backend/src/transformers/work-packages.transformer.ts @@ -4,8 +4,8 @@ import descriptionBulletTransformer from '../transformers/description-bullets.tr import { convertStatus, wbsNumOf } from '../utils/utils'; import { userTransformer } from './user.transformer'; import { WorkPackageQueryArgs, WorkPackagePreviewQueryArgs } from '../prisma-query-args/work-packages.query-args'; -import { designReviewPreviewTransformer } from './design-reviews.transformer'; import { teamTypeTransformer } from './team-types.transformer'; +import { eventPreviewTransformer } from './calendar.transformer'; const workPackageTransformer = (wpInput: Prisma.Work_PackageGetPayload): WorkPackage => { const wbsNum = wbsNumOf(wpInput.wbsElement); @@ -39,9 +39,9 @@ const workPackageTransformer = (wpInput: Prisma.Work_PackageGetPayload wbsNumOf(wp.wbsElement)), - designReviews: wpInput.wbsElement.designReviews.map((designReview) => - designReviewPreviewTransformer(designReview, `${wpInput.project.wbsElement.name} - ${wpInput.wbsElement.name}`) - ), + events: wpInput.events + .filter((event) => event.workPackages.length > 0) // Only events that are design reviews (have work packages) + .map((event) => eventPreviewTransformer(event, `${wpInput.project.wbsElement.name} - ${wpInput.wbsElement.name}`)), deleted: wpInput.wbsElement.dateDeleted !== null }; }; diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index 8b629ee62a..78fbcd41c3 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -33,6 +33,7 @@ export function validateEventTypeConfiguration( requiredMemberIds: string[]; optionalMemberIds: string[]; teamIds: string[]; + teamTypeId?: string; shopIds: string[]; machineryIds: string[]; workPackageIds: string[]; @@ -48,11 +49,11 @@ export function validateEventTypeConfiguration( if (eventType.requiredMembers && eventData.requiredMemberIds.length === 0) { throw new InvalidEventTypeConfigurationException('at least one required member'); } - if (eventType.location && !eventData.location) { - throw new InvalidEventTypeConfigurationException('a location'); + if (eventType.teamType && !eventData.teamTypeId) { + throw new InvalidEventTypeConfigurationException('a team type'); } - if (eventType.zoomLink && !eventData.zoomLink) { - throw new InvalidEventTypeConfigurationException('a zoom link'); + if ((eventType.location && !eventData.location) || (eventType.zoomLink && !eventData.zoomLink)) { + throw new InvalidEventTypeConfigurationException('a location or zoom link'); } if (eventType.workPackage && eventData.workPackageIds.length === 0) { throw new InvalidEventTypeConfigurationException('at least one work package'); @@ -60,7 +61,7 @@ export function validateEventTypeConfiguration( if (eventType.questionDocument && !eventData.questionDocument) { throw new InvalidEventTypeConfigurationException('a question document'); } - if (eventType.initialDateScheduled && eventData.scheduleSlot.length === 0) { + if (eventType.schedule && eventData.scheduleSlot.length === 0) { throw new InvalidEventTypeConfigurationException('at least one schedule slot'); } @@ -95,7 +96,7 @@ export function validateEventTypeConfiguration( if (!eventType.description && eventData.description) { throw new InvalidEventTypeConfigurationException('Event type does not allow a description'); } - if (!eventType.initialDateScheduled && eventData.scheduleSlot.length > 0) { + if (!eventType.schedule && eventData.scheduleSlot.length > 0) { throw new InvalidEventTypeConfigurationException('Event type does not allow schedule slots'); } } diff --git a/src/backend/src/utils/design-reviews.utils.ts b/src/backend/src/utils/design-reviews.utils.ts index 6ec4ec91b5..a73c5c6cd4 100644 --- a/src/backend/src/utils/design-reviews.utils.ts +++ b/src/backend/src/utils/design-reviews.utils.ts @@ -1,12 +1,6 @@ -import { DesignReview } from 'shared'; +/* import { HttpException } from './errors.utils'; -import { User } from 'shared'; -/** - * Validate meeting times - * @param nums the meeting times - * @returns the meeting times - */ export const validateMeetingTimes = (nums: number[]): number[] => { if (nums.length === 0) { throw new HttpException(400, 'There must be at least one meeting time'); @@ -23,12 +17,6 @@ export const validateMeetingTimes = (nums: number[]): number[] => { return nums; }; -export const isUserOnDesignReview = (user: User, designReview: DesignReview): boolean => { - const requiredMembers = designReview.requiredMembers.map((user) => user.userId); - const optionalMembers = designReview.optionalMembers.map((user) => user.userId); - return requiredMembers.includes(user.userId) || optionalMembers.includes(user.userId); -}; - export const transformStartTime = (times: number[]) => { return (times[0] % 12) + 10; }; @@ -38,3 +26,4 @@ export const addHours = (date: Date, hours: number) => { date.setTime(date.getTime() + hoursToAdd); return date; }; +*/ diff --git a/src/backend/src/utils/google-integration.utils.ts b/src/backend/src/utils/google-integration.utils.ts index 26a317094d..d96e7adb63 100644 --- a/src/backend/src/utils/google-integration.utils.ts +++ b/src/backend/src/utils/google-integration.utils.ts @@ -4,9 +4,7 @@ import SMTPTransport from 'nodemailer/lib/smtp-transport'; import { HttpException } from './errors.utils'; import stream, { Readable } from 'stream'; import concat from 'concat-stream'; -import { User, WBS_Element } from '@prisma/client'; -import { transformDate } from './datetime.utils'; -import { transformStartTime } from './design-reviews.utils'; +import { Schedule_Slot, User } from '@prisma/client'; import { getUsers } from './users.utils'; const { OAuth2 } = google.auth; @@ -193,42 +191,49 @@ export const createCalendar = async (name: string) => { /** * Creates A Google Calendar Event on the NER Google Calendar - * @param members required and optional members * @param calendarId the id of the calendar to add the event - * @param dateScheduled - * @param isInPerson - * @param zoomLink - * @param location - * @param meetingTimes - * @param wbsElement + * @param memberIds required and optional members + * @param scheduledSlots the scheduled time slots for the event + * @param isInPerson whether the event is in person + * @param zoomLink zoom link if online + * @param location physical location if in person + * @param eventTitle the title of the event * @returns the id of the calendar event */ export const createCalendarEvent = async ( calendarId: string, memberIds: string[], - dateScheduled: Date, + scheduledSlots: Schedule_Slot[], isInPerson: boolean, zoomLink: string | null, location: string | null, - meetingTimes: number[], - wbsElement: WBS_Element + eventTitle: string ) => { if (process.env.NODE_ENV !== 'production') return; + + const [firstSlot] = scheduledSlots; + if (!firstSlot?.startTime || !firstSlot?.endTime) { + throw new Error('Event must have a valid start and end time'); + } + try { oauth2Client.setCredentials({ refresh_token: CALENDAR_REFRESH_TOKEN }); const calendar = google.calendar({ version: 'v3', auth: oauth2Client }); - const startTime = transformStartTime(meetingTimes); + + const startDateTime = new Date(firstSlot.startTime); + const endDateTime = new Date(firstSlot.endTime); + const eventInput = { location: isInPerson ? location : zoomLink, - summary: `Design Review - ${wbsElement.projectNumber} ${wbsElement.name}`, + summary: eventTitle, start: { - dateTime: `${transformDate(new Date(dateScheduled))}T${startTime}:00:00-04:00`, + dateTime: startDateTime.toISOString(), timeZone: 'America/New_York' }, end: { - dateTime: `${transformDate(new Date(dateScheduled))}T${startTime + 1}:00:00-04:00`, + dateTime: endDateTime.toISOString(), timeZone: 'America/New_York' }, attendees: (await getUsers(memberIds)).map((user) => { @@ -258,36 +263,47 @@ export const createCalendarEvent = async ( * Updates a Google Calendar Event * @param calendarId Id of the calendar the event is on * @param eventId Id of the calendar event - * @param members required and optional members - * @param designReview + * @param memberIds required and optional members + * @param scheduledSlots the scheduled time slots for the event + * @param isInPerson whether the event is in person + * @param zoomLink zoom link if online + * @param location physical location if in person + * @param eventTitle the title of the event * @returns the id of the updated calendar event */ export const updateCalendarEvent = async ( calendarId: string, eventId: string, memberIds: string[], - dateScheduled: Date, + scheduledSlots: Schedule_Slot[], isInPerson: boolean, zoomLink: string | null, location: string | null, - meetingTimes: number[], - wbsElement: WBS_Element + eventTitle: string ) => { + const [firstSlot] = scheduledSlots; + if (!firstSlot?.startTime || !firstSlot?.endTime) { + throw new Error('Event must have a valid start and end time'); + } + try { oauth2Client.setCredentials({ refresh_token: CALENDAR_REFRESH_TOKEN }); const calendar = google.calendar({ version: 'v3', auth: oauth2Client }); - const startTime = transformStartTime(meetingTimes); + + const startDateTime = new Date(firstSlot.startTime); + const endDateTime = new Date(firstSlot.endTime); + const eventInput = { location: isInPerson ? location : zoomLink, - summary: `Design Review - ${wbsElement.projectNumber} ${wbsElement.name}`, + summary: eventTitle, start: { - dateTime: `${transformDate(dateScheduled)}T${startTime}:00:00-04:00`, + dateTime: startDateTime.toISOString(), timeZone: 'America/New_York' }, end: { - dateTime: `${transformDate(dateScheduled)}T${startTime + 1}:00:00-04:00`, + dateTime: endDateTime.toISOString(), timeZone: 'America/New_York' }, attendees: (await getUsers(memberIds)).map((user) => { @@ -301,11 +317,13 @@ export const updateCalendarEvent = async ( ] } }; + const calendarEvent = await calendar.events.update({ calendarId, eventId, requestBody: eventInput }); + return calendarEvent.data.id; } catch (error: unknown) { throw error; diff --git a/src/backend/src/utils/notifications.utils.ts b/src/backend/src/utils/notifications.utils.ts index 8fb6046318..61057ac1fe 100644 --- a/src/backend/src/utils/notifications.utils.ts +++ b/src/backend/src/utils/notifications.utils.ts @@ -1,12 +1,19 @@ -import { Task as Prisma_Task, WBS_Element, Design_Review } from '@prisma/client'; +import { Task as Prisma_Task, WBS_Element, Event, Work_Package } from '@prisma/client'; import { UserWithSettings } from './auth.utils'; +import { ScheduleSlot } from 'shared'; export type TaskWithAssignees = Prisma_Task & { assignees: UserWithSettings[] | null; wbsElement: WBS_Element; }; -export type DesignReviewWithAttendees = Design_Review & { attendees: UserWithSettings[]; wbsElement: WBS_Element }; +export type EventWithAttendees = Event & { + attendees: UserWithSettings[]; + scheduledTimes: ScheduleSlot[]; + workPackages: (Work_Package & { + wbsElement: WBS_Element; + })[]; +}; export const usersToSlackPings = (users: UserWithSettings[]) => { // https://api.slack.com/reference/surfaces/formatting#mentioning-users diff --git a/src/backend/src/utils/pop-up.utils.ts b/src/backend/src/utils/pop-up.utils.ts index f987c7da61..a5445f10ca 100644 --- a/src/backend/src/utils/pop-up.utils.ts +++ b/src/backend/src/utils/pop-up.utils.ts @@ -1,23 +1,23 @@ -import { Change_Request, Design_Review } from '@prisma/client'; +import { Change_Request, Event } from '@prisma/client'; import { User } from 'shared'; import { PopUpService } from '../services/pop-up.services'; /** - * Sends a pop up that a design review was scheduled - * @param designReview dr that was created - * @param members optional and required members of the dr - * @param submitter the user who created the dr - * @param workPackageName the name of the work package associated witht the dr - * @param organizationId id of the organization of the dr + * Sends a pop up that a design review event was scheduled + * @param event event that was created + * @param members optional and required members of the event + * @param submitter the user who created the event + * @param workPackageName the name of the work package associated witht the event + * @param organizationId id of the organization of the event */ -export const sendDrPopUp = async ( - designReview: Design_Review, +export const sendDrEventPopUp = async ( + event: Event, members: User[], submitter: User, workPackageName: string, organizationId: string ) => { - const designReviewLink = `/settings/preferences?drId=${designReview.designReviewId}`; + const designReviewEventLink = `/settings/preferences?drId=${event.eventId}`; const msg = `Design Review for ${workPackageName} is being scheduled by ${submitter.firstName} ${submitter.lastName}`; await PopUpService.sendPopUpToUsers( @@ -25,7 +25,7 @@ export const sendDrPopUp = async ( 'calendar_month', members.map((member) => member.userId), organizationId, - designReviewLink + designReviewEventLink ); }; diff --git a/src/backend/src/utils/slack.utils.ts b/src/backend/src/utils/slack.utils.ts index 91cea13067..704a8ef255 100644 --- a/src/backend/src/utils/slack.utils.ts +++ b/src/backend/src/utils/slack.utils.ts @@ -4,9 +4,10 @@ import { Task, wbsPipe, calculateEndDate, - meetingStartTimePipe, CreateSponsorTask, - User + User, + Event, + meetingStartTimePipeNumbers } from 'shared'; import { Account_Code, Reimbursement_Product_Other_Reason, Sponsor_Task } from '@prisma/client'; import { @@ -21,10 +22,9 @@ import { import { getUserSlackId, getUserSlackMentionOrName } from './users.utils'; import prisma from '../prisma/prisma'; import { HttpException } from './errors.utils'; -import { Change_Request, Design_Review, Team, WBS_Element } from '@prisma/client'; +import { Change_Request, Team, WBS_Element } from '@prisma/client'; import { UserWithSettings } from './auth.utils'; import { usersToSlackPings, userToSlackPing } from './notifications.utils'; -import { addHours } from './design-reviews.utils'; import { WorkPackageQueryArgs } from '../prisma-query-args/work-packages.query-args'; import { Prisma } from '@prisma/client'; import { userTransformer } from '../transformers/user.transformer'; @@ -243,18 +243,18 @@ export const sendPendingSaboSubmissionNotification = async ( ); }; -export const sendSlackDesignReviewConfirmNotification = async ( +export const sendSlackDesignReviewEventConfirmNotification = async ( slackId: string, - designReviewId: string, - designReviewName: string, + eventId: string, + eventName: string, projectName: string ) => { const isProduction = process.env.NODE_ENV === 'production'; if (!isProduction && !DEV_TESTING_OVERRIDE) return; // don't send msgs unless in prod - const msg = `You have been invited to the ${designReviewName} Design Review in project ${projectName}!`; + const msg = `You have been invited to the ${eventName} Design Review in project ${projectName}!`; const fullLink = isProduction - ? `https://finishlinebyner.com/settings/preferences?drId=${designReviewId}` - : `http://localhost:3000/settings/preferences?drId=${designReviewId}`; + ? `https://finishlinebyner.com/settings/preferences?eventId=${eventId}` + : `http://localhost:3000/settings/preferences?eventId=${eventId}`; const linkButtonText = 'Confirm Availability'; try { @@ -331,7 +331,7 @@ export const sendAndGetSlackCRNotifications = async ( return notifications; }; -export const sendSlackDesignReviewNotification = async ( +export const sendSlackDesignReviewEventNotification = async ( team: Team, message: string ): Promise<{ channelId: string; ts: string }[]> => { @@ -346,9 +346,9 @@ export const sendSlackDesignReviewNotification = async ( return msgs; }; -export const sendSlackDRNotifications = async ( +export const sendSlackDREventNotifications = async ( teams: Team[], - designReview: Design_Review, + event: Event, submitter: User, workPackageName: string, projectName: string @@ -358,7 +358,10 @@ export const sendSlackDRNotifications = async ( const message = `:spiral_calendar_pad: Design Review for *${workPackageName}* is being scheduled by ${submitter.firstName} ${submitter.lastName} in project ${projectName}`; const completion: Promise[] = teams.map(async (team) => { - const sentNotifications: { channelId: string; ts: string }[] = await sendSlackDesignReviewNotification(team, message); + const sentNotifications: { channelId: string; ts: string }[] = await sendSlackDesignReviewEventNotification( + team, + message + ); if (sentNotifications) notifications.push(...sentNotifications); }); await Promise.all(completion); @@ -367,12 +370,12 @@ export const sendSlackDRNotifications = async ( async (notification) => await prisma.message_Info.create({ data: { - designReviewId: designReview.designReviewId, + eventId: event.eventId, channelId: notification.channelId, timestamp: notification.ts }, include: { - designReview: true + event: true } }) ); @@ -381,7 +384,7 @@ export const sendSlackDRNotifications = async ( return notifications; }; -export const sendDRUserConfirmationToThread = async (threads: SlackMessageThread[], submitter: UserWithSettings) => { +export const sendDREventUserConfirmationToThread = async (threads: SlackMessageThread[], submitter: UserWithSettings) => { if (process.env.NODE_ENV !== 'production' && !DEV_TESTING_OVERRIDE) return; // don't send msgs unless in prod const slackPing = userToSlackPing(submitter); const fullMsg = `${slackPing} confirmed their availability!`; @@ -397,7 +400,7 @@ export const sendDRUserConfirmationToThread = async (threads: SlackMessageThread } }; -export const sendDRConfirmationToThread = async (threads: SlackMessageThread[], submitter: UserWithSettings) => { +export const sendDREventConfirmationToThread = async (threads: SlackMessageThread[], submitter: UserWithSettings) => { if (process.env.NODE_ENV !== 'production' && !DEV_TESTING_OVERRIDE) return; // don't send msgs unless in prod const slackPing = userToSlackPing(submitter); const fullMsg = `${slackPing} All of the required attendees have confirmed their availability!`; @@ -413,27 +416,40 @@ export const sendDRConfirmationToThread = async (threads: SlackMessageThread[], } }; -export const sendDRScheduledSlackNotif = async ( - threads: SlackMessageThread[], - designReview: Design_Review & { wbsElement: WBS_Element; userCreated: User } -) => { +export const sendDREventScheduledSlackNotif = async (threads: SlackMessageThread[], event: Event) => { if (process.env.NODE_ENV !== 'production' && !DEV_TESTING_OVERRIDE) return; // don't send msgs unless in prod - const drName = designReview.wbsElement.name; - const { dateScheduled } = designReview; - const drTime = `${addHours(dateScheduled, 12).toLocaleDateString()} at ${meetingStartTimePipe(designReview.meetingTimes)}`; - const drSubmitter = `${designReview.userCreated.firstName} ${designReview.userCreated.lastName}`; - const zoomLink = designReview.isOnline && designReview.zoomLink && `on <${designReview.zoomLink}|Zoom>`; - const location = - zoomLink && designReview.isInPerson - ? `in ${designReview.location} and ${zoomLink}` - : designReview.isInPerson - ? `in ${designReview.location}` - : zoomLink; + // Get work package names + const wpNames = event.workPackages.map((wp) => wp.wbsElement.name).join(', '); + const drName = event.title + (wpNames ? ` (${wpNames})` : ''); + + // Get the first scheduled time + const [firstScheduledTime] = event.scheduledTimes; + if (!firstScheduledTime) { + throw new HttpException(400, 'Event has no scheduled times'); + } + + const dateScheduled = firstScheduledTime.initialDateScheduled; + + // Extract meeting times from scheduled slots + const meetingTimes = event.scheduledTimes + .map((slot) => (slot.startTime ? new Date(slot.startTime).getHours() : null)) + .filter((hour): hour is number => hour !== null) + .sort((a, b) => a - b); + + const drTime = `${dateScheduled.toLocaleDateString()} at ${meetingStartTimePipeNumbers(meetingTimes)}`; + const drSubmitter = `${event.userCreated.firstName} ${event.userCreated.lastName}`; + + // Check for online/in-person location + const zoomLink = event.zoomLink && `on <${event.zoomLink}|Zoom>`; + const inPersonLocation = event.location && `in ${event.location}`; + + const location = zoomLink && inPersonLocation ? `${inPersonLocation} and ${zoomLink}` : inPersonLocation || zoomLink || ''; const msg = `:spiral_calendar_pad: Design Review for *${drName}* has been scheduled for *${drTime}* ${location} by ${drSubmitter}`; - const docLink = designReview.docTemplateLink ? `<${designReview.docTemplateLink}|Doc Link>` : ''; + const docLink = event.questionDocument ? `<${event.questionDocument}|Doc Link>` : ''; const threadMsg = `The Design Review has been Scheduled! \n` + docLink; + try { if (threads && threads.length !== 0) { const msgs = threads.map((thread) => editMessage(thread.channelId, thread.timestamp, msg)); diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index b2cf89f9a0..5f6483e0f1 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -18,7 +18,7 @@ import prisma from '../src/prisma/prisma'; import { dbSeedAllUsers } from '../src/prisma/seed-data/users.seed'; import TeamsService from '../src/services/teams.services'; import ReimbursementRequestService from '../src/services/reimbursement-requests.services'; -import { Permission, RoleEnum, TaskPriority, TaskStatus } from 'shared'; +import { DayOfWeek, Permission, RoleEnum, TaskPriority, TaskStatus } from 'shared'; import { batmanAppAdmin, batmanScheduleSettings, @@ -30,10 +30,10 @@ import { getProjectTemplateQueryArgs, getWorkPackageTemplateQueryArgs } from '../src/prisma-query-args/wbs-element-template.query-args'; -import DesignReviewsService from '../src/services/design-reviews.services'; import TasksService from '../src/services/tasks.services'; import ProjectsService from '../src/services/projects.services'; import { SlackMessage } from '../src/services/slack.services'; +import CalendarService from '../src/services/calendar.services'; export interface CreateTestUserParams { firstName: string; @@ -151,7 +151,6 @@ export const resetUsers = async () => { await prisma.user_Secure_Settings.deleteMany(); await prisma.schedule_Settings.deleteMany(); await prisma.role.deleteMany(); - await prisma.design_Review.deleteMany(); await prisma.team_Type.deleteMany(); await prisma.wBS_Element.deleteMany(); await prisma.milestone.deleteMany(); @@ -545,7 +544,7 @@ export const createTestReimbursementRequest = async () => { }; // Always creates a new design review -export const createTestDesignReview = async () => { +export const createTestDesignReviewEvent = async () => { const organization = await createTestOrganization(); const head = await createTestUser( { ...batmanAppAdmin, googleAuthId: 'financeHead', role: RoleEnum.APP_ADMIN }, @@ -566,34 +565,93 @@ export const createTestDesignReview = async () => { const teamType = await TeamsService.createTeamType(head, 'Team1', 'Software', 'Software team', organization); - const { designReviewId } = await DesignReviewsService.createDesignReview( + const designReviewEventType = await CalendarService.createEventType( lead, - '03/25/2027', - teamType.teamTypeId, - [lead.userId], - [], - { - carNumber: 0, - projectNumber: 0, - workPackageNumber: 0 - }, - [0, 1], - organization + 'Design Review', + [], // No calendar IDs for now + organization, + true, // schedule + true, // requiredMembers + true, // optionalMembers + false, // teams + true, // team type + true, // location + true, // zoomLink + false, // shop + false, // machinery + true, // workPackage + true, // questionDocument + true, // documents + false, // description + true, // onlyHeadsOrAbove + true // requiresConfirmation + ); + + const testWorkPackage = await prisma.work_Package.findFirst({ + where: { + wbsElement: { + carNumber: 1, + projectNumber: 1, + workPackageNumber: 1, + organizationId: organization.organizationId + } + } + }); + + if (!testWorkPackage) { + throw new Error('Test work package not found'); + } + + const { eventId } = await CalendarService.createEvent( + lead, + 'Design Review - Impact Attenuator', + designReviewEventType.eventTypeId, + organization, + [lead.userId], // requiredMemberIds + [], // optionalMemberIds + [], // teamIds + [], // shopIds + [], // machineryIds + [testWorkPackage.workPackageId], // workPackageIds + [], // documentIds + [ + { + days: [DayOfWeek.TUESDAY], + startTime: new Date('2027-03-25T10:00:00'), + endTime: new Date('2027-03-25T11:00:00'), + recurrenceNumber: 0, + initialDateScheduled: new Date('2027-03-25'), + allDay: false + }, + { + days: [DayOfWeek.TUESDAY], + startTime: new Date('2027-03-25T11:00:00'), + endTime: new Date('2027-03-25T12:00:00'), + recurrenceNumber: 0, + initialDateScheduled: new Date('2027-03-25'), + allDay: false + } + ], // scheduleSlot - two 1-hour time slots + teamType.teamTypeId, // team type id + 'https://docs.google.com/document/d/test-design-review-questions', // questionDocument + 'Campus Center Room 101', // location + 'https://zoom.us/j/123456789', // zoomLink + undefined // description ); - const dr = await prisma.design_Review.findUnique({ + const event = await prisma.event.findUnique({ where: { - designReviewId + eventId }, include: { userCreated: true } }); - if (!dr) throw new Error('Failed to create design review'); + if (!event) throw new Error('Failed to create design review'); const orgId = organization.organizationId; - return { dr, organization, orgId }; + return { event, organization, orgId }; }; export const createTestTeamType = async (name: string = 'aTeam', organizationId?: string) => { diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index c055ef8879..db671f09f6 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -60,11 +60,10 @@ describe('Calendar Tests', () => { [calendar.calendarId], organization, true, - false, - true, true, true, true, + false, true, true, true, @@ -247,8 +246,7 @@ describe('Calendar Tests', () => { true, true, true, - true, - true, + false, false, true, false, @@ -271,11 +269,10 @@ describe('Calendar Tests', () => { [], organization, true, - false, - true, true, true, false, + false, true, true, false, @@ -289,12 +286,11 @@ describe('Calendar Tests', () => { ); expect(result.name).toEqual('Meeting'); - expect(result.initialDateScheduled).toBe(true); - expect(result.recurring).toBe(false); - expect(result.allDay).toBe(true); + expect(result.schedule).toBe(true); expect(result.requiredMembers).toBe(true); expect(result.optionalMembers).toBe(true); expect(result.teams).toBe(false); + expect(result.teamType).toBe(false); expect(result.location).toBe(true); expect(result.zoomLink).toBe(true); expect(result.shop).toBe(false); @@ -637,8 +633,6 @@ describe('Calendar Tests', () => { [calendar.calendarId], organization, true, - false, - true, true, true, false, @@ -649,6 +643,7 @@ describe('Calendar Tests', () => { false, false, false, + false, true, true, false @@ -678,7 +673,6 @@ describe('Calendar Tests', () => { false, false, false, - false, false ) ).rejects.toThrow(new AccessDeniedAdminOnlyException('edit event type')); @@ -707,7 +701,6 @@ describe('Calendar Tests', () => { true, true, true, - true, true ) ).rejects.toThrow(new NotFoundException('Calendar', invalidCalendarId)); @@ -754,7 +747,6 @@ describe('Calendar Tests', () => { false, false, false, - false, false ) ).rejects.toThrow(new InvalidOrganizationException('Calendar')); @@ -770,11 +762,10 @@ describe('Calendar Tests', () => { organization, 'Non Existent Event Type', false, - true, - true, false, true, false, + false, true, false, false, @@ -798,10 +789,9 @@ describe('Calendar Tests', () => { 'Initial Event Type 2', false, true, - false, - true, true, false, + false, true, false, true, @@ -815,13 +805,12 @@ describe('Calendar Tests', () => { ); expect(result.name).toBe('Initial Event Type 2'); - expect(result.initialDateScheduled).toBe(false); - expect(result.recurring).toBe(true); - expect(result.allDay).toBe(false); + expect(result.schedule).toBe(false); expect(result.eventTypeId).toBe(eventType.eventTypeId); expect(result.requiredMembers).toBe(true); expect(result.optionalMembers).toBe(true); expect(result.teams).toBe(false); + expect(result.teamType).toBe(false); expect(result.location).toBe(true); expect(result.zoomLink).toBe(false); expect(result.shop).toBe(true); @@ -900,6 +889,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -920,6 +910,7 @@ describe('Calendar Tests', () => { expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); + expect(result.teamType).toBe(undefined); expect(result.approved).toBe(true); expect(result.approvalRequiredFrom).toBe(undefined); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); @@ -1013,6 +1004,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1030,6 +1022,7 @@ describe('Calendar Tests', () => { expect(result.workPackages).toHaveLength(0); expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); + expect(result.teamType).toBe(undefined); expect(result.approved).toBe(true); expect(result.approvalRequiredFrom).toBeUndefined(); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); @@ -1064,6 +1057,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1098,6 +1092,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1132,6 +1127,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1166,6 +1162,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1200,6 +1197,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1240,6 +1238,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1287,6 +1286,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1326,6 +1326,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1345,6 +1346,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1387,6 +1389,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1406,6 +1409,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1437,6 +1441,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots2, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1480,6 +1485,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1499,6 +1505,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1530,6 +1537,7 @@ describe('Calendar Tests', () => { [], [document], scheduleSlots2, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1630,8 +1638,7 @@ describe('Calendar Tests', () => { data: { shopId: anotherShop.shopId, machineryId: machineryToDelete.machineryId, - quantity: 1, - description: 'Bridge row for deletion test' + quantity: 1 } }); }); @@ -1713,6 +1720,7 @@ describe('Calendar Tests', () => { [], ['document'], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1781,6 +1789,7 @@ describe('Calendar Tests', () => { [], ['document'], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1805,6 +1814,7 @@ describe('Calendar Tests', () => { [], ['document'], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1859,6 +1869,7 @@ describe('Calendar Tests', () => { [], ['document'], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1889,6 +1900,7 @@ describe('Calendar Tests', () => { [], ['document'], scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1924,6 +1936,7 @@ describe('Calendar Tests', () => { [], ['doc2', 'doc3'], newScheduleSlots, + undefined, 'https://updated.com/questions.pdf', 'Updated Location', 'https://zoom.us/updated', @@ -1976,6 +1989,7 @@ describe('Calendar Tests', () => { [], ['doc2', 'doc3'], scheduleSlots, + undefined, 'https://updated.com/questions.pdf', 'Updated Location', 'https://zoom.us/updated', @@ -2030,11 +2044,10 @@ describe('Calendar Tests', () => { [calendar.calendarId], organization, true, - false, - true, true, true, false, + false, true, false, false, @@ -2089,11 +2102,10 @@ describe('Calendar Tests', () => { [], otherOrg, true, - false, - true, true, true, false, + false, true, false, false, diff --git a/src/backend/tests/unit/design-review.test.ts b/src/backend/tests/unit/design-review.test.ts deleted file mode 100644 index fe2e87729a..0000000000 --- a/src/backend/tests/unit/design-review.test.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { financeMember, supermanAdmin } from '../test-data/users.test-data'; -import DesignReviewsService from '../../src/services/design-reviews.services'; -import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; -import { createTestDesignReview, createTestUser, resetUsers } from '../test-utils'; -import prisma from '../../src/prisma/prisma'; -import { getUserQueryArgs } from '../../src/prisma-query-args/user.query-args'; -import { DesignReviewStatus } from 'shared'; -import { Design_Review, Organization } from '@prisma/client'; - -describe('Design Reviews', () => { - let designReview: Design_Review; - let organizationId: string; - let organization: Organization; - beforeEach(async () => { - const { dr, organization: org, orgId } = await createTestDesignReview(); - designReview = dr; - organization = org; - organizationId = orgId; - }); - - afterEach(async () => { - await resetUsers(); - }); - - test('Marks design review as confirmed if updated list of required members have confirmed', async () => { - const user = await createTestUser(supermanAdmin, organizationId); - - const origonalDesignreview = await prisma.design_Review.update({ - where: { designReviewId: designReview.designReviewId }, - data: { - requiredMembers: { - connect: [{ userId: user.userId }] - }, - confirmedMembers: { - connect: [{ userId: designReview.userCreatedId }] - } - }, - include: { - requiredMembers: true, - confirmedMembers: true - } - }); - - const requiredMembers = origonalDesignreview.requiredMembers.map((member) => member.userId) || []; - const confirmedMembers = origonalDesignreview.confirmedMembers.map((member) => member.userId) || []; - - expect(requiredMembers.length).toBe(2); - expect(confirmedMembers.length).toBe(1); - - await DesignReviewsService.setStatus(user, designReview.designReviewId, DesignReviewStatus.CONFIRMED, organization); - - const updatedDesignReview = await DesignReviewsService.editDesignReview( - user, - designReview.designReviewId, - new Date(), - origonalDesignreview.teamTypeId, - [designReview.userCreatedId], - [], - false, - false, - null, - null, - '', - DesignReviewStatus.CONFIRMED, - [], - [0, 1], - organization - ); - - expect(updatedDesignReview.status).toBe(DesignReviewStatus.SCHEDULED); - }); - - // change with admin who is not creator - test('Set status works when an admin who is not the creator sets', async () => { - const user = await createTestUser(supermanAdmin, organizationId); - await DesignReviewsService.setStatus(user, designReview.designReviewId, DesignReviewStatus.CONFIRMED, organization); - const updatedDR = await prisma.design_Review.findUnique({ - where: { - designReviewId: designReview.designReviewId - } - }); - // check that status changed to correct status - expect(updatedDR?.status).toBe(DesignReviewStatus.CONFIRMED); - }); - - // Set status works when creator is not admin - test('Set status works when set with creator who is not admin', async () => { - const drCreator = await prisma.user.findUnique({ - where: { - userId: designReview.userCreatedId - }, - ...getUserQueryArgs(organizationId) - }); - if (!drCreator) { - throw new Error('User not found in database'); - } - await DesignReviewsService.setStatus(drCreator, designReview.designReviewId, DesignReviewStatus.CONFIRMED, organization); - const updatedDR = await prisma.design_Review.findUnique({ - where: { - designReviewId: designReview.designReviewId - } - }); - expect(updatedDR?.status).toBe(DesignReviewStatus.CONFIRMED); - }); - - // fails when user is not admin or creator - test('Set status fails when user is not admin or creator', async () => { - await expect(async () => - DesignReviewsService.setStatus( - await createTestUser(financeMember, organizationId), - designReview.designReviewId, - DesignReviewStatus.CONFIRMED, - organization - ) - ).rejects.toThrow(new AccessDeniedAdminOnlyException('set the status of a design review')); - }); -}); diff --git a/src/backend/tests/unmocked/design-review.test.ts b/src/backend/tests/unmocked/design-review.test.ts deleted file mode 100644 index 4c88f979b8..0000000000 --- a/src/backend/tests/unmocked/design-review.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { financeMember, supermanAdmin } from '../test-data/users.test-data'; -import DesignReviewsService from '../../src/services/design-reviews.services'; -import { AccessDeniedAdminOnlyException } from '../../src/utils/errors.utils'; -import { createTestDesignReview, createTestUser, resetUsers } from '../test-utils'; -import prisma from '../../src/prisma/prisma'; -import { getUserQueryArgs } from '../../src/prisma-query-args/user.query-args'; -import { DesignReviewStatus } from 'shared'; -import { Design_Review, Organization } from '@prisma/client'; - -describe('Design Reviews', () => { - let designReview: Design_Review; - let organizationId: string; - let organization: Organization; - beforeEach(async () => { - const { dr, organization: org, orgId } = await createTestDesignReview(); - designReview = dr; - organization = org; - organizationId = orgId; - }); - - afterEach(async () => { - await resetUsers(); - }); - - // change with admin who is not creator - test('Set status works when an admin who is not the creator sets', async () => { - const user = await createTestUser(supermanAdmin, organizationId); - await DesignReviewsService.setStatus(user, designReview.designReviewId, DesignReviewStatus.CONFIRMED, organization); - const updatedDR = await prisma.design_Review.findUnique({ - where: { - designReviewId: designReview.designReviewId - } - }); - // check that status changed to correct status - expect(updatedDR?.status).toBe(DesignReviewStatus.CONFIRMED); - }); - - // Set status works when creator is not admin - test('Set status works when set with creator who is not admin', async () => { - const drCreator = await prisma.user.findUnique({ - where: { - userId: designReview.userCreatedId - }, - ...getUserQueryArgs(organizationId) - }); - if (!drCreator) { - throw new Error('User not found in database'); - } - await DesignReviewsService.setStatus(drCreator, designReview.designReviewId, DesignReviewStatus.CONFIRMED, organization); - const updatedDR = await prisma.design_Review.findUnique({ - where: { - designReviewId: designReview.designReviewId - } - }); - expect(updatedDR?.status).toBe(DesignReviewStatus.CONFIRMED); - }); - - // fails when user is not admin or creator - test('Set status fails when user is not admin or creator', async () => { - await expect(async () => - DesignReviewsService.setStatus( - await createTestUser(financeMember, organizationId), - designReview.designReviewId, - DesignReviewStatus.CONFIRMED, - organization - ) - ).rejects.toThrow(new AccessDeniedAdminOnlyException('set the status of a design review')); - }); -}); diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index a953cfb1b5..e8d5cc2b15 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,6 +1,7 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; -import { Shop, Machinery } from 'shared'; +import { Shop, Machinery, AvailabilityCreateArgs, Event, EventStatus } from 'shared'; +import { eventTransformer } from './transformers/calendar.transformer'; export const getAllShops = () => { return axios.get(apiUrls.calendarShops(), { @@ -61,3 +62,29 @@ export const editShop = (shopId: string, payload: { name: string; description: s transformResponse: (data) => JSON.parse(data) as Shop }); }; + +export const markUserConfirmed = async (id: string, payload: { availability: AvailabilityCreateArgs[] }) => { + return axios.post(apiUrls.calendarEventMarkUserConfirmed(id), payload); +}; + +export const getSingleEvent = async (id: string) => { + return axios.get(apiUrls.calendarGetSingleEvent(id), { + transformResponse: (data) => eventTransformer(JSON.parse(data)) + }); +}; + +export const getAllEvents = () => { + return axios.get(apiUrls.calendarEvents(), { + transformResponse: (data) => JSON.parse(data).map(eventTransformer) + }); +}; + +export const deleteEvent = async (id: string) => { + return axios.delete(apiUrls.calendarDeleteEvent(id)); +}; + +export const setEventStatus = async (id: string, payload: { status: EventStatus }) => { + return axios.post(apiUrls.calendarEventSetStatus(id), payload, { + transformResponse: (data) => eventTransformer(JSON.parse(data)) + }); +}; diff --git a/src/frontend/src/apis/design-reviews.api.ts b/src/frontend/src/apis/design-reviews.api.ts index 269f1e9fba..d9ccfbe2f7 100644 --- a/src/frontend/src/apis/design-reviews.api.ts +++ b/src/frontend/src/apis/design-reviews.api.ts @@ -2,6 +2,7 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ +/* import { EditDesignReviewPayload } from '../hooks/design-reviews.hooks'; import axios from '../utils/axios'; import { AvailabilityCreateArgs, DesignReview, DesignReviewStatus } from 'shared'; @@ -9,54 +10,60 @@ import { apiUrls } from '../utils/urls'; import { CreateDesignReviewsPayload } from '../hooks/design-reviews.hooks'; import { designReviewTransformer } from './transformers/design-reviews.tranformers'; import { datePipe } from '../utils/pipes'; - +*/ /** * Create a design review * @param payload all info needed to create a design review */ +/* export const createDesignReviews = async (payload: CreateDesignReviewsPayload) => { return axios.post(apiUrls.designReviewsCreate(), { ...payload, dateScheduled: datePipe(payload.dateScheduled) }); }; - +*/ /** * Gets all the design reviews */ +/* export const getAllDesignReviews = () => { return axios.get(apiUrls.designReviews(), { transformResponse: (data) => JSON.parse(data).map(designReviewTransformer) }); }; - +*/ /** * Edit a design review * * @param designReviewId The id of the design review being edited * @param payload The new information for the design review */ +/* export const editDesignReview = (designReviewId: string, payload: EditDesignReviewPayload) => { return axios.post<{ message: string }>(apiUrls.designReviewsEdit(designReviewId), { ...payload }); }; - +*/ /** * Gets a single design review * @param id the ID of the design review to return * @returns the request design review */ +/* export const getSingleDesignReview = async (id: string) => { return axios.get(apiUrls.designReviewById(id), { transformResponse: (data) => designReviewTransformer(JSON.parse(data)) }); }; +*/ /** * Deletes a design review * @param id the ID of the design review to delete */ +/* export const deleteDesignReview = async (id: string) => { return axios.delete(apiUrls.designReviewDelete(id)); }; @@ -70,3 +77,4 @@ export const setDesignReviewStatus = async (id: string, payload: { status: Desig transformResponse: (data) => designReviewTransformer(JSON.parse(data)) }); }; +*/ diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts index 107d94ef25..081b139f62 100644 --- a/src/frontend/src/apis/transformers/calendar.transformer.ts +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -1,4 +1,4 @@ -import { Shop } from 'shared'; +import { Shop, Event, EventPreview } from 'shared'; import { userTransformer } from './users.transformers'; export const shopTransformer = (shop: Shop): Shop => { @@ -8,3 +8,20 @@ export const shopTransformer = (shop: Shop): Shop => { userCreated: userTransformer(shop.userCreated) }; }; + +export const eventTransformer = (event: Event): Event => { + return { + ...event + }; +}; + +export const eventPreviewTransformer = (event: EventPreview): EventPreview => { + return { + eventId: event.eventId, + title: event.title, + dateScheduled: event.dateScheduled, + status: event.status, + userCreated: userTransformer(event.userCreated), + wbsName: event.wbsName + }; +}; diff --git a/src/frontend/src/apis/transformers/design-reviews.tranformers.ts b/src/frontend/src/apis/transformers/design-reviews.tranformers.ts index 7401224f51..50d1996398 100644 --- a/src/frontend/src/apis/transformers/design-reviews.tranformers.ts +++ b/src/frontend/src/apis/transformers/design-reviews.tranformers.ts @@ -1,3 +1,4 @@ +/* import { DesignReview, DesignReviewPreview } from 'shared'; export const designReviewTransformer = (designReview: DesignReview): DesignReview => { @@ -20,3 +21,4 @@ export const designReviewPreviewTransformer = (designReview: DesignReviewPreview dateScheduled: new Date(anyDesignReview.dateScheduled.split('T')[0] + 'T04:00:00.000Z') }; }; +*/ diff --git a/src/frontend/src/apis/transformers/work-packages.transformers.ts b/src/frontend/src/apis/transformers/work-packages.transformers.ts index 183e4b513c..d805517a41 100644 --- a/src/frontend/src/apis/transformers/work-packages.transformers.ts +++ b/src/frontend/src/apis/transformers/work-packages.transformers.ts @@ -5,8 +5,8 @@ import { RetrospectiveWorkPackage, WorkPackage, WorkPackagePreview } from 'shared'; import { implementedChangeTransformer } from './change-requests.transformers'; -import { designReviewPreviewTransformer } from './design-reviews.tranformers'; import { descriptionBulletTransformer } from './projects.transformers'; +import { eventPreviewTransformer } from './calendar.transformer'; /** * Transforms a work package to ensure deep field transformation of date objects. @@ -22,7 +22,7 @@ export const workPackageTransformer = (workPackage: WorkPackage): WorkPackage => endDate: new Date(workPackage.endDate), descriptionBullets: workPackage.descriptionBullets.map(descriptionBulletTransformer), changes: workPackage.changes.map(implementedChangeTransformer), - designReviews: workPackage.designReviews.map(designReviewPreviewTransformer) + events: workPackage.events.map(eventPreviewTransformer) }; }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 8c787564ed..6101842353 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,5 +1,5 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop, Machinery } from 'shared'; +import { Shop, Machinery, AvailabilityCreateArgs, Event, EventStatus } from 'shared'; import { getAllShops, postCreateShop, @@ -7,8 +7,14 @@ import { postCreateMachinery, postEditMachinery, postAddMachineryToShop, - editShop + editShop, + markUserConfirmed, + getSingleEvent, + getAllEvents, + deleteEvent, + setEventStatus } from '../apis/calendar.api'; +import { useCurrentUser } from './users.hooks'; export const MACHINERY_KEY = ['machinery'] as const; @@ -101,3 +107,71 @@ export const useAddMachineryToShop = (machineryId: string) => { } ); }; + +export const useMarkUserConfirmed = (id: string) => { + const user = useCurrentUser(); + const queryClient = useQueryClient(); + return useMutation( + ['events', 'mark-confirmed'], + async (eventPayload: { availability: AvailabilityCreateArgs[] }) => { + const { data } = await markUserConfirmed(id, eventPayload); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['events']); + queryClient.invalidateQueries(['users', user.userId, 'schedule-settings']); + } + } + ); +}; + +export const useSingleEvent = (id?: string) => { + return useQuery( + ['events', id], + async () => { + const { data } = await getSingleEvent(id!); + return data; + }, + { enabled: !!id } + ); +}; + +export const useAllEvents = () => { + return useQuery(['events'], async () => { + const { data } = await getAllEvents(); + return data; + }); +}; + +export const useDeleteEvent = (id: string) => { + const queryClient = useQueryClient(); + return useMutation( + ['events', 'delete'], + async () => { + const { data } = await deleteEvent(id); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['events']); + } + } + ); +}; + +export const useSetEventStatus = (id: string) => { + const queryClient = useQueryClient(); + return useMutation( + ['events', id], + async (payload: { status: EventStatus }) => { + const { data } = await setEventStatus(id, payload); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['events', id]); + } + } + ); +}; diff --git a/src/frontend/src/hooks/design-reviews.hooks.ts b/src/frontend/src/hooks/design-reviews.hooks.ts index c801cc968c..7c6aa03c06 100644 --- a/src/frontend/src/hooks/design-reviews.hooks.ts +++ b/src/frontend/src/hooks/design-reviews.hooks.ts @@ -2,8 +2,9 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ +/* import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { DesignReview, WbsNumber, DesignReviewStatus, AvailabilityCreateArgs } from 'shared'; +import { WbsNumber, AvailabilityCreateArgs } from 'shared'; import { deleteDesignReview, editDesignReview, @@ -39,12 +40,13 @@ export const useCreateDesignReviews = () => { } ); }; - +/* /** * Custom react hook to get all design reviews * * @returns all the design reviews */ +/* export const useAllDesignReviews = () => { return useQuery(['design-reviews'], async () => { const { data } = await getAllDesignReviews(); @@ -66,11 +68,12 @@ export interface EditDesignReviewPayload { attendees: string[]; meetingTimes: number[]; } - +/* /** * Custom React Hook to edit a Design Review * @param designReviewId the design review being edited */ +/* export const useEditDesignReview = (designReviewId: string) => { const queryClient = useQueryClient(); return useMutation<{ message: string }, Error, EditDesignReviewPayload>( @@ -86,11 +89,11 @@ export const useEditDesignReview = (designReviewId: string) => { } ); }; - +/* /** * Custom react hook to delete a design review */ - +/* export const useDeleteDesignReview = (id: string) => { const queryClient = useQueryClient(); return useMutation( @@ -106,12 +109,13 @@ export const useDeleteDesignReview = (id: string) => { } ); }; - +/* /** * Custom react hook to get a single design review * * @returns a single design review */ +/* export const useSingleDesignReview = (id?: string) => { return useQuery( ['design-reviews', id], @@ -156,3 +160,4 @@ export const useSetDesignReviewStatus = (id: string) => { } ); }; +*/ diff --git a/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx b/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx index 546e4f679d..72d6a018c7 100644 --- a/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx +++ b/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx @@ -6,26 +6,21 @@ import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { fullNamePipe } from '../../utils/pipes'; import { useAllUsers } from '../../hooks/users.hooks'; -import { useAllDesignReviews } from '../../hooks/design-reviews.hooks'; -import { DesignReviewStatus } from 'shared'; +import { useAllEvents } from '../../hooks/calendar.hooks'; +import { EventStatus } from 'shared'; const AdminToolsAttendeeDesignReviewInfo: React.FC = () => { const [searchQuery, setSearchQuery] = useState(''); const { data: allTeams, isLoading: teamsIsLoading, isError: teamsIsError, error: teamsError } = useAllTeams(); const { data: allUsers, isLoading: usersIsLoading, isError: usersIsError, error: usersError } = useAllUsers(); - const { - data: allDesignReviews, - isLoading: designReviewsIsLoading, - isError: designReviewsIsError, - error: designReviewsError - } = useAllDesignReviews(); + const { data: allEvents, isLoading: eventsIsLoading, isError: eventsIsError, error: eventsError } = useAllEvents(); - if (!allTeams || teamsIsLoading || !allUsers || usersIsLoading || !allDesignReviews || designReviewsIsLoading) + if (!allTeams || teamsIsLoading || !allUsers || usersIsLoading || !allEvents || eventsIsLoading) return ; if (teamsIsError) return ; if (usersIsError) return ; - if (designReviewsIsError) return ; + if (eventsIsError) return ; const filteredMembers = allUsers.filter((member) => fullNamePipe(member).toLowerCase().includes(searchQuery.toLowerCase()) @@ -38,9 +33,9 @@ const AdminToolsAttendeeDesignReviewInfo: React.FC = () => { const attendanceDict: Map = new Map(); const missedDict: Map = new Map(); - allDesignReviews.forEach((review) => { - if (review.status === DesignReviewStatus.DONE) { - review.attendees.forEach((member) => { + allEvents.forEach((review) => { + if (review.status === EventStatus.DONE) { + review.requiredMembers.forEach((member) => { if (attendanceDict.has(member.userId)) { attendanceDict.set(member.userId, attendanceDict.get(member.userId)! + 1); } else { @@ -48,7 +43,7 @@ const AdminToolsAttendeeDesignReviewInfo: React.FC = () => { } }); review.requiredMembers.forEach((member) => { - if (!review.attendees.map((user) => user.userId).includes(member.userId)) { + if (!review.requiredMembers.map((user) => user.userId).includes(member.userId)) { if (missedDict.has(member.userId)) { missedDict.set(member.userId, missedDict.get(member.userId)! + 1); } else { @@ -80,7 +75,7 @@ const AdminToolsAttendeeDesignReviewInfo: React.FC = () => { return ( - Design Review Attendee Info + Event Attendee Info Search by team member name @@ -89,7 +84,7 @@ const AdminToolsAttendeeDesignReviewInfo: React.FC = () => { { return ( diff --git a/src/frontend/src/pages/CalendarPage/CalendarComponents/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarComponents/CalendarDayCard.tsx index 97889ed529..4f58bac1cf 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarComponents/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarComponents/CalendarDayCard.tsx @@ -1,15 +1,14 @@ import { Box, Card, CardContent, Grid, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; -import { DesignReview, DesignReviewStatus, TeamType } from 'shared'; -import { meetingStartTimePipe } from '../../../utils/pipes'; +import { Event, EventStatus, TeamType } from 'shared'; +import { meetingStartTimePipeScheduleSlot } from '../../../utils/pipes'; import ConstructionIcon from '@mui/icons-material/Construction'; import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices'; import TerminalIcon from '@mui/icons-material/Terminal'; import { useState } from 'react'; -import DRCSummaryModal from '../DesignReviewSummaryModal'; -import { DesignReviewCreateModal } from '../DesignReviewCreateModal'; +import DRCSummaryModal from '../EventSummaryModal'; import DynamicTooltip from '../../../components/DynamicTooltip'; -import { designReviewStatusColor } from '../../../utils/design-review.utils'; +import { eventStatusColor } from '../../../utils/design-review.utils'; export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { const teamIcons: Map = new Map([ @@ -23,12 +22,12 @@ export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { interface CalendarDayCardProps { cardDate: Date; - events: DesignReview[]; + events: Event[]; teamTypes: TeamType[]; } const CalendarDayCard: React.FC = ({ cardDate, events, teamTypes }) => { - const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); + const [, setIsCreateModalOpen] = useState(false); const theme = useTheme(); const DayCardTitle = () => ( @@ -47,17 +46,17 @@ const CalendarDayCard: React.FC = ({ cardDate, events, tea ); - const EventCard = ({ event }: { event: DesignReview }) => { + const EventCard = ({ event }: { event: Event }) => { const [isSummaryModalOpen, setIsSummaryModalOpen] = useState(false); const [markedStatus, setMarkedStatus] = useState(event.status); - const name = event.wbsName; + const name = event.workPackages[0]?.wbsElement?.name || event.title; return ( <> setIsSummaryModalOpen(false)} - designReview={event} + event={event} teamTypes={teamTypes} markedStatus={markedStatus} setMarkedStatus={setMarkedStatus} @@ -77,7 +76,7 @@ const CalendarDayCard: React.FC = ({ cardDate, events, tea > = ({ cardDate, events, tea title={ name + ' - ' + - (event.status !== DesignReviewStatus.UNCONFIRMED - ? event.meetingTimes.length > 0 - ? meetingStartTimePipe(event.meetingTimes) + (event.status !== EventStatus.UNCONFIRMED + ? event.scheduledTimes.length > 0 + ? meetingStartTimePipeScheduleSlot(event.scheduledTimes) : '' : 'UNCONFIRMED! THIS TIME IS SUBJECT TO CHANGE') } @@ -105,7 +104,7 @@ const CalendarDayCard: React.FC = ({ cardDate, events, tea ); }; - const ExtraEventNote = ({ event }: { event: DesignReview }) => { + const ExtraEventNote = ({ event }: { event: Event }) => { const [isSummaryModalOpen, setIsSummaryModalOpen] = useState(false); const [markedStatus, setMarkedStatus] = useState(event.status); @@ -114,7 +113,7 @@ const CalendarDayCard: React.FC = ({ cardDate, events, tea setIsSummaryModalOpen(false)} - designReview={event} + event={event} teamTypes={teamTypes} markedStatus={markedStatus} setMarkedStatus={setMarkedStatus} @@ -126,13 +125,14 @@ const CalendarDayCard: React.FC = ({ cardDate, events, tea setIsSummaryModalOpen(true); }} > - {event.wbsName + (event.meetingTimes.length > 0 ? ' - ' + meetingStartTimePipe(event.meetingTimes) : '')} + {event.workPackages[0]?.wbsElement?.name || + event.title + (event.scheduledTimes.length > 0 ? meetingStartTimePipeScheduleSlot(event.scheduledTimes) : '')} ); }; - const ExtraEventsCard = ({ extraEvents }: { extraEvents: DesignReview[] }) => { + const ExtraEventsCard = ({ extraEvents }: { extraEvents: Event[] }) => { const [showTooltip, setShowTooltip] = useState(false); return ( = ({ cardDate, events, tea return ( <> - { - setIsCreateModalOpen(false); - }} - teamTypes={teamTypes} - defaultDate={cardDate} - /> { } = useAllTeamTypes(); const [displayMonthYear, setDisplayMonthYear] = useState(new Date()); - const { isLoading, isError, error, data: allDesignReviews } = useAllDesignReviews(); + const { isLoading, isError, error, data: allEvents } = useAllEvents(); const user = useCurrentUser(); - const [unconfirmedDesignReview, setUnconfirmedDesignReview] = useState(); + const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); - - if (isLoading || !allDesignReviews) return ; + if (isLoading || !allEvents) return ; if (isError) return ; - const confirmedDesignReviews = allDesignReviews; - - const eventDict = new Map(); - confirmedDesignReviews.sort((designReview1, designReview2) => { - if (designReview1.dateScheduled.getTime() === designReview2.dateScheduled.getTime()) { - return designReview1.meetingTimes[0] - designReview2.meetingTimes[0]; + // Sort events by date and time + const sortedEvents = [...allEvents].sort((event1, event2) => { + const date1 = event1.scheduledTimes[0]?.initialDateScheduled + ? new Date(event1.scheduledTimes[0].initialDateScheduled).getTime() + : 0; + const date2 = event2.scheduledTimes[0]?.initialDateScheduled + ? new Date(event2.scheduledTimes[0].initialDateScheduled).getTime() + : 0; + + if (date1 === date2) { + const time1 = event1.scheduledTimes[0]?.startTime ? new Date(event1.scheduledTimes[0].startTime).getTime() : 0; + const time2 = event2.scheduledTimes[0]?.startTime ? new Date(event2.scheduledTimes[0].startTime).getTime() : 0; + return time1 - time2; } - return designReview1.dateScheduled.getTime() - designReview2.dateScheduled.getTime(); + return date1 - date2; }); - confirmedDesignReviews.forEach((designReview) => { - // Accessing the date actually converts it to local time, which causes the date to be off. This is a workaround. - const date = datePipe( - new Date(designReview.dateScheduled.getTime() - designReview.dateScheduled.getTimezoneOffset() * -60000) - ); + const eventDict = new Map(); + sortedEvents.forEach((event) => { + const firstScheduledDate = event.scheduledTimes[0]?.initialDateScheduled; + if (!firstScheduledDate) return; + + // Convert string to Date + const dateObj = new Date(firstScheduledDate); + const date = datePipe(new Date(dateObj.getTime() - dateObj.getTimezoneOffset() * -60000)); if (eventDict.has(date)) { - eventDict.get(date)?.push(designReview); + eventDict.get(date)?.push(event); } else { - eventDict.set(date, [designReview]); + eventDict.set(date, [event]); } }); - const currentUserDesignReviews = allDesignReviews.filter( - (designReview) => designReview.userCreated.userId === user.userId && designReview.status !== DesignReviewStatus.DONE + const currentUserEvents = allEvents.filter( + (event) => event.userCreated.userId === user.userId && event.status !== EventStatus.DONE ); - const startOfEachWeek = [0, 7, 14, 21, 28, 35]; + // Generate calendar dates + const firstDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 1); + const lastDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 0); - const isDayInDifferentMonth = (day: number, week: number) => { - return day < week - 7 || day < 1 || day > week + 7; - }; + const paddingStart = firstDayOfMonth.getDay(); // 0-6 (Sun-Sat) + const totalDays = lastDayOfMonth.getDate(); + const totalCells = Math.ceil((paddingStart + totalDays) / 7) * 7; + + const calendarDates: Date[] = []; + + // Add padding days from previous month + const prevMonthLastDay = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 0); + const prevMonthDays = prevMonthLastDay.getDate(); + for (let i = paddingStart - 1; i >= 0; i--) { + calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, prevMonthDays - i)); + } + + // Add current month days + for (let day = 1; day <= totalDays; day++) { + calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), day)); + } + + // Add padding days from next month + const remainingCells = totalCells - calendarDates.length; + for (let day = 1; day <= remainingCells; day++) { + calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, day)); + } + + const eventButtons = (events: Event[]) => { + return events.map((event) => { + // Get team type name directly from event + const teamTypeName = event.teamType?.name || 'Default'; + + // Get title from work packages or event title + const title = + event.workPackages.length > 0 ? event.workPackages.map((wp) => wp.wbsElement.name).join(', ') : event.title; - const designReviewButtons = (designReviews: DesignReview[]) => { - return designReviews.map((designReview) => { return { - icon: getTeamTypeIcon(designReview.teamType.name), - title: designReview.wbsName, + icon: getTeamTypeIcon(teamTypeName), + title, onClick: () => { - setUnconfirmedDesignReview(designReview); + setSelectedEvent(event); }, disabled: false }; }); }; - const NoDRSButton = () => { + const NoEventsButton = () => { return [ { - title: 'No Design Reviews', + title: 'No Events', disabled: true, onClick: () => {} } ]; }; - const paddingArrayStart = [...Array(calendarPaddingDays(displayMonthYear)).keys()] - .map( - (day) => - daysInMonth(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, displayMonthYear.getDate())) - - day - ) - .reverse(); - const paddingArrayEnd = [ - ...Array(7 - ((daysInMonth(displayMonthYear) + calendarPaddingDays(displayMonthYear)) % 7)).keys() - ].map((day) => day + 1); - const daysThisMonth = paddingArrayStart - .concat([...Array(daysInMonth(displayMonthYear)).keys()].map((day) => day + 1)) - .concat(paddingArrayEnd.length < 7 ? paddingArrayEnd : []); - - const unconfirmedDRSDropdown = ( + const unconfirmedEventsDropdown = ( My Unconfirmed DRs @@ -121,67 +145,64 @@ const CalendarPage = () => { return ( <> - {unconfirmedDesignReview && ( + {selectedEvent && ( { - setUnconfirmedDesignReview(undefined); + setSelectedEvent(undefined); }} - designReview={unconfirmedDesignReview as DesignReview} + event={selectedEvent} teamTypes={allTeamTypes} /> )} - Design Review Calendar + Calendar - - {unconfirmedDRSDropdown} + {unconfirmedEventsDropdown} - - {enumToArray(DAY_NAMES).map((day) => ( - - - { - // Day of the week display based on current breakpoint - isLargerView ? day : isExtraSmallView ? day.charAt(0) : day.substring(0, 3) - } - + + + + {enumToArray(DAY_NAMES).map((day, index) => ( + + + {isLargerView ? day : isExtraSmallView ? day.charAt(0) : day.substring(0, 3)} + + + ))} - ))} - - - - {startOfEachWeek.map((week) => ( - - {daysThisMonth.slice(week, week + 7).map((day) => { - const cardDate = new Date( - displayMonthYear.getFullYear(), - displayMonthYear.getMonth() + (isDayInDifferentMonth(day, week) ? (day > 15 ? -1 : 1) : 0), - day - ); - return ( - - - - - - ); - })} + + + {Array.from({ length: Math.ceil(calendarDates.length / 7) }, (_, weekIndex) => ( + + {calendarDates.slice(weekIndex * 7, weekIndex * 7 + 7).map((cardDate, dayIndex) => ( + + + + + + ))} + + ))} - ))} - + + + + +
diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/DesignReviewDetails.tsx b/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/DesignReviewDetails.tsx deleted file mode 100644 index 6d23ff67b9..0000000000 --- a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/DesignReviewDetails.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This file is part of NER's FinishLine and licensed under GNU AGPLv3. - * See the LICENSE file in the repository root folder for details. - */ -import LoadingIndicator from '../../../components/LoadingIndicator'; -import { useParams } from 'react-router-dom'; -import ErrorPage from '../../ErrorPage'; -import DesignReviewDetailPage from './DesignReviewDetailPage'; -import { useSingleDesignReview } from '../../../hooks/design-reviews.hooks'; - -const DesignReviewDetails: React.FC = () => { - const { id } = useParams<{ id: string }>(); - const { data: designReview, isError, error, isLoading } = useSingleDesignReview(id); - - if (isError) return ; - if (!designReview || isLoading) return ; - - return ; -}; - -export default DesignReviewDetails; diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewAvailabilityInfo.tsx b/src/frontend/src/pages/CalendarPage/EventAvailabilityInfo.tsx similarity index 79% rename from src/frontend/src/pages/CalendarPage/DesignReviewAvailabilityInfo.tsx rename to src/frontend/src/pages/CalendarPage/EventAvailabilityInfo.tsx index 29a9d3e11e..3ed2a75a4b 100644 --- a/src/frontend/src/pages/CalendarPage/DesignReviewAvailabilityInfo.tsx +++ b/src/frontend/src/pages/CalendarPage/EventAvailabilityInfo.tsx @@ -1,13 +1,13 @@ -import { DesignReview } from 'shared'; +import { Event } from 'shared'; import { Grid, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; import ColumnHeader from '../FinancePage/FinanceComponents/ColumnHeader'; import { fullNamePipe } from '../../utils/pipes'; -interface DesignReviewAvailabilityInfoProps { - designReview: DesignReview; +interface EventAvailabilityInfoProps { + event: Event; } -export const DesignReviewAvailabilityInfo: React.FC = ({ designReview }) => { +export const EventAvailabilityInfo: React.FC = ({ event }) => { return ( @@ -23,14 +23,14 @@ export const DesignReviewAvailabilityInfo: React.FC - {designReview.requiredMembers.map((member) => ( + {event.requiredMembers.map((member) => ( {fullNamePipe(member)} - {designReview.confirmedMembers.some((confirmedMember) => confirmedMember.userId === member.userId) + {event.confirmedMembers.some((confirmedMember) => confirmedMember.userId === member.userId) ? 'Yes' : 'No'} @@ -54,14 +54,14 @@ export const DesignReviewAvailabilityInfo: React.FC - {designReview.optionalMembers.map((member) => ( + {event.optionalMembers.map((member) => ( {fullNamePipe(member)} - {designReview.confirmedMembers.some((confirmedMember) => confirmedMember.userId === member.userId) + {event.confirmedMembers.some((confirmedMember) => confirmedMember.userId === member.userId) ? 'Yes' : 'No'} diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewCreateModal.tsx b/src/frontend/src/pages/CalendarPage/EventCreateModal.tsx similarity index 99% rename from src/frontend/src/pages/CalendarPage/DesignReviewCreateModal.tsx rename to src/frontend/src/pages/CalendarPage/EventCreateModal.tsx index c9abd786c4..119cf95309 100644 --- a/src/frontend/src/pages/CalendarPage/DesignReviewCreateModal.tsx +++ b/src/frontend/src/pages/CalendarPage/EventCreateModal.tsx @@ -1,3 +1,4 @@ +/* import NERFormModal from '../../components/NERFormModal'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; @@ -316,3 +317,4 @@ export const DesignReviewCreateModal: React.FC = ( ); }; +*/ diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/AvailabilityScheduleView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx similarity index 94% rename from src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/AvailabilityScheduleView.tsx rename to src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx index ac66fd3829..606aa9aca2 100644 --- a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/AvailabilityScheduleView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx @@ -1,5 +1,5 @@ import { Grid } from '@mui/material'; -import { Availability, DesignReview, getDayOfWeek, getNextSevenDays, User } from 'shared'; +import { Availability, Event, getDayOfWeek, getNextSevenDays, User } from 'shared'; import { enumToArray, REVIEW_TIMES, @@ -20,7 +20,7 @@ interface AvailabilityScheduleViewProps { setCurrentUnavailableUsers: (val: User[]) => void; onSelectedTimeslotChanged: (val: number | null, day: Date | null) => void; dateRangeTitle: string; - designReview: DesignReview; + event: Event; } const AvailabilityScheduleView: React.FC = ({ @@ -32,11 +32,12 @@ const AvailabilityScheduleView: React.FC = ({ setCurrentUnavailableUsers, dateRangeTitle, onSelectedTimeslotChanged, - designReview + event }) => { const totalUsers = usersToAvailabilities.size; const [selectedTimeslot, setSelectedTimeslot] = useState(null); - const potentialDays = getNextSevenDays(designReview.initialDate); + const initialDate = event.scheduledTimes[0]?.initialDateScheduled || new Date(); + const potentialDays = getNextSevenDays(initialDate); const handleTimeslotClick = (index: number, day: Date) => { if (selectedTimeslot === index) { diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/AvailabilityView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx similarity index 59% rename from src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/AvailabilityView.tsx rename to src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx index 923c758933..b04d835b2e 100644 --- a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/AvailabilityView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx @@ -1,27 +1,19 @@ import { Grid } from '@mui/material'; -import { - Availability, - DesignReview, - DesignReviewStatus, - getMostRecentAvailabilities, - isSameDay, - User, - UserWithScheduleSettings -} from 'shared'; +import { Availability, Event, EventStatus, getMostRecentAvailabilities, User, UserWithScheduleSettings } from 'shared'; import { useState } from 'react'; import AvailabilityScheduleView from './AvailabilityScheduleView'; import UserAvailabilites from './UserAvailabilitesView'; import { getWeekDateRange } from '../../../utils/design-review.utils'; import { dateRangePipe } from '../../../utils/pipes'; -import { FinalizeReviewInformation } from './DesignReviewDetailPage'; +import { FinalizeEventInformation } from './EventDetailPage'; import { useManyUsersWithScheduleSettings } from '../../../hooks/users.hooks'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; interface AvailabilityViewProps { - designReview: DesignReview; - allDesignReviews: DesignReview[]; - handleEdit: (data?: FinalizeReviewInformation) => void; + event: Event; + allEvents: Event[]; + handleEdit: (data?: FinalizeEventInformation) => void; selectedDate: Date; setSelectDate: (date: Date) => void; startTime: number; @@ -33,8 +25,8 @@ interface AvailabilityViewProps { } const AvailabilityView: React.FC = ({ - designReview, - allDesignReviews, + event, + allEvents, handleEdit, selectedDate, setSelectDate, @@ -64,8 +56,12 @@ const AvailabilityView: React.FC = ({ if (isLoading || !relevantUsers) return ; if (isError) return ; - const currentWeekDesignReviews = allDesignReviews.filter((currDr) => { - const drDate = new Date(currDr.dateScheduled).getTime(); + // Get events within the current week + const currentWeekEvents = allEvents.filter((currEvent) => { + const eventDate = currEvent.scheduledTimes[0]?.initialDateScheduled; + if (!eventDate) return false; + + const drDate = new Date(eventDate).getTime(); const startRange = startDateRange.getTime(); const endRange = endDateRange.getTime(); @@ -79,29 +75,47 @@ const AvailabilityView: React.FC = ({ setSelectDate(day); }; - const conflictingDesignReviews = allDesignReviews.filter((currDr) => { - const times = []; - for (let i = startTime; i < endTime; i++) { - times.push(i); + // Find conflicting events for the selected time + const conflictingEvents = allEvents.filter((currEvent) => { + if (currEvent.eventId === event.eventId) return false; + if (currEvent.status !== EventStatus.SCHEDULED) return false; + + const eventDate = currEvent.scheduledTimes[0]?.initialDateScheduled; + if (!eventDate) return false; + + const cleanDate = new Date(eventDate.getTime() - eventDate.getTimezoneOffset() * -60000); + + // Check if event is on the selected date + if (cleanDate.toLocaleDateString() !== selectedDate.toLocaleDateString()) return false; + + // Check if any scheduled times overlap with selected time range + return currEvent.scheduledTimes.some((slot) => { + if (!slot.startTime) return false; + const slotHour = new Date(slot.startTime).getHours(); + return slotHour >= startTime + 10 && slotHour < endTime + 10; + }); + }); + + // Map existing scheduled events to time slots for visualization + currentWeekEvents.forEach((ev) => { + if (ev.status === EventStatus.SCHEDULED && ev.eventId !== event.eventId) { + ev.scheduledTimes.forEach((slot) => { + if (slot.startTime) { + const hour = new Date(slot.startTime).getHours(); + const timeIndex = hour - 10; // Convert back to 0-11 index + if (timeIndex >= 0 && timeIndex < 12) { + existingMeetingData.set(timeIndex, ev.teamType?.name || 'default'); + } + } + }); } - const cleanDate = new Date(currDr.dateScheduled.getTime() - currDr.dateScheduled.getTimezoneOffset() * -60000); - return ( - currDr.status === DesignReviewStatus.SCHEDULED && - cleanDate.toLocaleDateString() === selectedDate.toLocaleDateString() && - times.some((time) => isSameDay(currDr.dateScheduled, selectedDate) && currDr.meetingTimes.includes(time)) && - currDr.designReviewId !== designReview.designReviewId - ); }); - currentWeekDesignReviews.forEach((dr) => - dr.meetingTimes.forEach((meetingTime) => { - if (dr.status === DesignReviewStatus.SCHEDULED && dr.designReviewId !== designReview.designReviewId) - existingMeetingData.set(meetingTime, dr.teamType.iconName); - }) - ); + // Get the initial date for availability lookup + const initialDate = event.scheduledTimes[0]?.initialDateScheduled || new Date(); relevantUsers.forEach((user: UserWithScheduleSettings) => { - const availability = getMostRecentAvailabilities(user.scheduleSettings?.availabilities ?? [], designReview.initialDate); + const availability = getMostRecentAvailabilities(user.scheduleSettings?.availabilities ?? [], initialDate); usersToAvailabilities.set(user, availability ?? []); }); @@ -118,7 +132,7 @@ const AvailabilityView: React.FC = ({ setCurrentUnavailableUsers={setCurrentUnavailableUsers} dateRangeTitle={dateRangePipe(startDateRange, endDateRange)} onSelectedTimeslotChanged={onSelectedTimeslotChanged} - designReview={designReview} + event={event} /> @@ -126,8 +140,8 @@ const AvailabilityView: React.FC = ({ currentAvailableUsers={currentAvailableUsers} currentUnavailableUsers={currentUnavailableUsers} usersToAvailabilities={usersToAvailabilities} - designReview={designReview} - conflictingDesignReviews={conflictingDesignReviews} + event={event} + conflictingEvents={conflictingEvents} handleEdit={handleEdit} selectedDate={selectedDate} startTime={startTime} diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/DesignReviewDetailPage.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx similarity index 79% rename from src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/DesignReviewDetailPage.tsx rename to src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx index b75176b2fb..616a327482 100644 --- a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/DesignReviewDetailPage.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx @@ -20,56 +20,68 @@ import { useState } from 'react'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; import { DatePicker } from '@mui/x-date-pickers'; -import { DesignReview, DesignReviewStatus } from 'shared'; -import { EditDesignReviewPayload, useAllDesignReviews, useEditDesignReview } from '../../../hooks/design-reviews.hooks'; -import { designReviewNamePipe, meetingStartTimePipe } from '../../../utils/pipes'; +import { Event, meetingStartTimePipeNumbers } from 'shared'; +import { useAllEvents } from '../../../hooks/calendar.hooks'; +import { eventNamePipe } from '../../../utils/pipes'; import { HOURS } from '../../../utils/design-review.utils'; -import { useHistory } from 'react-router-dom'; -import { useToast } from '../../../hooks/toasts.hooks'; -import { routes } from '../../../utils/routes'; -export interface DesignReviewEditData { +export interface EventEditData { requiredUserIds: string[]; optionalUserIds: string[]; selectedDate: Date; startTime: number; endTime: number; } -interface DesignReviewDetailPageProps { - designReview: DesignReview; +interface EventDetailPageProps { + event: Event; } -export interface FinalizeReviewInformation { +export interface FinalizeEventInformation { docTemplateLink: string; zoomLink?: string; location?: string; meetingType: string[]; } -const DesignReviewDetailPage: React.FC = ({ designReview }) => { +const EventDetailPage: React.FC = ({ event }) => { const theme = useTheme(); - const [requiredUsers, setRequiredUsers] = useState(designReview.requiredMembers.map(userToAutocompleteOption)); - const [optionalUsers, setOptionalUsers] = useState(designReview.optionalMembers.map(userToAutocompleteOption)); - const [date, setDate] = useState( - new Date(designReview.dateScheduled.getTime() - designReview.dateScheduled.getTimezoneOffset() * -60000) + const [requiredUsers, setRequiredUsers] = useState(event.requiredMembers.map(userToAutocompleteOption)); + const [optionalUsers, setOptionalUsers] = useState(event.optionalMembers.map(userToAutocompleteOption)); + + const [firstScheduledSlot] = event.scheduledTimes; + const lastScheduledSlot = event.scheduledTimes.at(-1); + + // Convert string dates → real Date objects (defensive) + const parseDate = (dateInput: Date | string | undefined): Date => { + if (!dateInput) return new Date(); + return typeof dateInput === 'string' ? new Date(dateInput) : dateInput; + }; + + const [date, setDate] = useState( + firstScheduledSlot?.initialDateScheduled ? parseDate(firstScheduledSlot.initialDateScheduled) : new Date() + ); + + const [startTime, setStartTime] = useState( + firstScheduledSlot?.startTime ? new Date(firstScheduledSlot.startTime).getHours() - 10 : 0 + ); + + const [endTime, setEndTime] = useState( + lastScheduledSlot?.endTime + ? new Date(lastScheduledSlot.endTime).getHours() - 9 // +1 hour from start + : 1 ); - const [startTime, setStateTime] = useState(designReview.meetingTimes[0] % 12); - const [endTime, setEndTime] = useState((designReview.meetingTimes[designReview.meetingTimes.length - 1] % 12) + 1); - const { mutateAsync: editDesignReview } = useEditDesignReview(designReview.designReviewId); const { isLoading: allUsersIsLoading, isError: allUsersIsError, error: allUsersError, data: allUsers } = useAllUsers(); const { - data: allDesignReviews, - isError: allDesignReviewsIsError, - error: allDesignReviewsError, - isLoading: allDesignReviewsIsLoading - } = useAllDesignReviews(); - const history = useHistory(); - const toast = useToast(); + data: allEvents, + isError: allEventsIsError, + error: allEventsError, + isLoading: allEventsIsLoading + } = useAllEvents(); if (allUsersIsError) return ; - if (allDesignReviewsIsError) return ; - if (allUsersIsLoading || !allUsers || allDesignReviewsIsLoading || !allDesignReviews) return ; + if (allEventsIsError) return ; + if (allUsersIsLoading || !allUsers || allEventsIsLoading || !allEvents) return ; const users = allUsers.map(userToAutocompleteOption); @@ -88,13 +100,13 @@ const DesignReviewDetailPage: React.FC = ({ designR setRequiredUsers(newValue); }; - const handleEdit = async (data?: FinalizeReviewInformation) => { + const handleEdit = async () => { const times = []; for (let i = startTime; i < endTime; i++) { times.push(i % 12); } date.setHours(12); - + /* try { const payload: EditDesignReviewPayload = { dateScheduled: date, @@ -117,6 +129,7 @@ const DesignReviewDetailPage: React.FC = ({ designR toast.error(error.message); } } + */ }; const DateField = () => { @@ -153,7 +166,7 @@ const DesignReviewDetailPage: React.FC = ({ designR Name - {designReviewNamePipe(designReview)} + {eventNamePipe(event)} @@ -162,9 +175,9 @@ const DesignReviewDetailPage: React.FC = ({ designR meetingStartTimePipe([value], true)} + renderValue={(value) => meetingStartTimePipeNumbers([value])} value={endTime} disabled={true} onChange={(event: SelectChangeEvent) => setEndTime(Number(event.target.value))} @@ -194,7 +207,7 @@ const DesignReviewDetailPage: React.FC = ({ designR {HOURS.map((hour) => { return ( - {meetingStartTimePipe([hour])} + {meetingStartTimePipeNumbers([hour])} ); })} @@ -283,19 +296,19 @@ const DesignReviewDetailPage: React.FC = ({ designR user.id)} optionalUserIds={optionalUsers.map((user) => user.id)} startTime={startTime} endTime={endTime} - setStartTime={setStateTime} + setStartTime={setStartTime} setEndTime={setEndTime} /> ); }; -export default DesignReviewDetailPage; +export default EventDetailPage; diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetails.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetails.tsx new file mode 100644 index 0000000000..05b3adaa27 --- /dev/null +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetails.tsx @@ -0,0 +1,21 @@ +/* + * This file is part of NER's FinishLine and licensed under GNU AGPLv3. + * See the LICENSE file in the repository root folder for details. + */ +import LoadingIndicator from '../../../components/LoadingIndicator'; +import { useParams } from 'react-router-dom'; +import ErrorPage from '../../ErrorPage'; +import { useSingleEvent } from '../../../hooks/calendar.hooks'; +import EventDetailPage from './EventDetailPage'; + +const EventDetails: React.FC = () => { + const { id } = useParams<{ id: string }>(); + const { data: event, isError, error, isLoading } = useSingleEvent(id); + + if (isError) return ; + if (!event || isLoading) return ; + + return ; +}; + +export default EventDetails; diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/FinalizeDesignReviewDetailsModal.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx similarity index 74% rename from src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/FinalizeDesignReviewDetailsModal.tsx rename to src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx index f4aed95eb2..588868a2bb 100644 --- a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/FinalizeDesignReviewDetailsModal.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx @@ -1,35 +1,34 @@ import { Box, Grid, Link, ToggleButton, ToggleButtonGroup, Typography, Tooltip } from '@mui/material'; import HelpIcon from '@mui/icons-material/Help'; import React, { useState, useEffect } from 'react'; -import { DesignReview, wbsPipe } from 'shared'; -import { meetingStartTimePipe } from '../../../utils/pipes'; +import { Event, meetingStartTimePipeNumbers, wbsPipe } from 'shared'; import NERFormModal from '../../../components/NERFormModal'; import ReactHookTextField from '../../../components/ReactHookTextField'; import { useForm } from 'react-hook-form'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; -import { FinalizeReviewInformation } from './DesignReviewDetailPage'; +import { FinalizeEventInformation } from './EventDetailPage'; import { useCurrentUser, useUserScheduleSettings } from '../../../hooks/users.hooks'; -interface FinalizeDesignReviewProps { +interface FinalizeEventProps { open: boolean; setOpen: (val: boolean) => void; - designReview: DesignReview; - conflictingDesignReviews: DesignReview[]; + event: Event; + conflictingEvents: Event[]; startTime: number; selectedDate: Date; - finalizeDesignReview: (data: FinalizeReviewInformation) => void; + finalizeEvent: (data: FinalizeEventInformation) => void; } -const FinalizeDesignReviewDetailsModal = ({ +const FinalizeEventDetailsModal = ({ open, setOpen, - designReview, - conflictingDesignReviews, - finalizeDesignReview, + event, + conflictingEvents, + finalizeEvent, startTime, selectedDate -}: FinalizeDesignReviewProps) => { +}: FinalizeEventProps) => { const [meetingType, setMeetingType] = useState([]); const currentUser = useCurrentUser(); const { data: userScheduleSettings } = useUserScheduleSettings(currentUser.userId); @@ -43,16 +42,30 @@ const FinalizeDesignReviewDetailsModal = ({ docTemplateLink: yup.string().required('Question Doc is Required') }); - const title = `Finalize Design Review for ${designReview.wbsName}`; + const [firstWorkPackage] = event.workPackages; - const designReviewConflicts = conflictingDesignReviews.map( - (designReview) => `${wbsPipe(designReview.wbsNum)} - ${designReview.wbsName} at ${meetingStartTimePipe([startTime])}` + const wbsNum = firstWorkPackage + ? { + carNumber: firstWorkPackage.wbsElement.carNumber, + projectNumber: firstWorkPackage.wbsElement.projectNumber, + workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber + } + : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; + + const eventName = firstWorkPackage?.wbsElement?.name + ? `${firstWorkPackage.wbsElement.carNumber}.${firstWorkPackage.wbsElement.projectNumber}.${firstWorkPackage.wbsElement.workPackageNumber} - ${firstWorkPackage.wbsElement.name}` + : event.title; + + const title = `Finalize Event for ${eventName}`; + + const eventConflicts = conflictingEvents.map( + (_event) => `${wbsPipe(wbsNum)} - ${eventName} at ${meetingStartTimePipeNumbers([startTime])}` ); const defaultValues = { - docTemplateLink: designReview.docTemplateLink ?? '', - zoomLink: designReview.zoomLink ?? userScheduleSettings?.personalZoomLink ?? '', - location: designReview.location ?? undefined + docTemplateLink: event.questionDocument ?? '', + zoomLink: event.zoomLink ?? userScheduleSettings?.personalZoomLink ?? '', + location: event.location ?? undefined }; const { @@ -72,24 +85,24 @@ const FinalizeDesignReviewDetailsModal = ({ }; const onSubmit = async (data: { docTemplateLink: string; zoomLink?: string; location?: string }) => { - finalizeDesignReview({ ...data, zoomLink: data.zoomLink ? data.zoomLink : undefined, meetingType }); + finalizeEvent({ ...data, zoomLink: data.zoomLink ? data.zoomLink : undefined, meetingType }); setOpen(false); }; useEffect(() => { - if (userScheduleSettings && designReview.isOnline && !designReview.zoomLink) { + if (userScheduleSettings && !event.zoomLink) { reset({ - docTemplateLink: designReview.docTemplateLink ?? '', + docTemplateLink: event.questionDocument ?? '', zoomLink: userScheduleSettings.personalZoomLink ?? '', - location: designReview.location ?? undefined + location: event.location ?? undefined }); } - if (designReview.zoomLink === '' && !designReview.isOnline) { + if (event.zoomLink === '') { reset({ zoomLink: undefined }); } - }, [userScheduleSettings, designReview, reset]); + }, [userScheduleSettings, event, reset]); return ( Meeting Time: - {`${meetingStartTimePipe([ + {`${meetingStartTimePipeNumbers([ startTime ])} - ${selectedDate.toDateString()}`} @@ -155,7 +168,7 @@ const FinalizeDesignReviewDetailsModal = ({ )} - {designReviewConflicts && designReviewConflicts.length > 0 && ( + {eventConflicts && eventConflicts.length > 0 && ( Design Review Conflicts @@ -170,7 +183,7 @@ const FinalizeDesignReviewDetailsModal = ({ padding: 1 }} > - {designReviewConflicts.map((conflictDesign, index) => ( + {eventConflicts.map((conflictDesign, index) => ( {conflictDesign} @@ -183,4 +196,4 @@ const FinalizeDesignReviewDetailsModal = ({ ); }; -export default FinalizeDesignReviewDetailsModal; +export default FinalizeEventDetailsModal; diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/UserAvailabilitesView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/UserAvailabilitesView.tsx similarity index 80% rename from src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/UserAvailabilitesView.tsx rename to src/frontend/src/pages/CalendarPage/EventDetailPage/UserAvailabilitesView.tsx index 32ef5f66f6..f9d86b4fcc 100644 --- a/src/frontend/src/pages/CalendarPage/DesignReviewDetailPage/UserAvailabilitesView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/UserAvailabilitesView.tsx @@ -1,40 +1,40 @@ import { Typography } from '@mui/material'; import { Box, useTheme } from '@mui/system'; -import { Availability, DesignReview, DesignReviewStatus, User } from 'shared'; +import { Availability, Event, EventStatus, User } from 'shared'; import { HeatmapColors } from '../../../utils/design-review.utils'; import { fullNamePipe } from '../../../utils/pipes'; import NERFailButton from '../../../components/NERFailButton'; import NERSuccessButton from '../../../components/NERSuccessButton'; import { useState } from 'react'; -import FinalizeDesignReviewDetailsModal from './FinalizeDesignReviewDetailsModal'; -import { FinalizeReviewInformation } from './DesignReviewDetailPage'; +import { FinalizeEventInformation } from './EventDetailPage'; import { useHistory } from 'react-router-dom'; import { routes } from '../../../utils/routes'; +import FinalizeEventDetailsModal from './FinalizeEventDetailsModal'; interface UserAvailabilitiesProps { currentAvailableUsers: User[]; currentUnavailableUsers: User[]; usersToAvailabilities: Map; - designReview: DesignReview; - conflictingDesignReviews: DesignReview[]; + event: Event; + conflictingEvents: Event[]; selectedDate: Date; startTime: number; - handleEdit: (data?: FinalizeReviewInformation) => void; + handleEdit: (data?: FinalizeEventInformation) => void; } const UserAvailabilites: React.FC = ({ currentAvailableUsers, currentUnavailableUsers, usersToAvailabilities, - designReview, - conflictingDesignReviews, + event, + conflictingEvents, handleEdit, selectedDate, startTime }) => { const theme = useTheme(); const history = useHistory(); - const [showFinalizeDesignReviewDetailsModal, setShowFinalizeDesignReviewDetailsModal] = useState(false); + const [showFinalizeEventDetailsModal, setShowFinalizeEventDetailsModal] = useState(false); const totalUsers = usersToAvailabilities.size; const handleCancel = () => { @@ -126,20 +126,20 @@ const UserAvailabilites: React.FC = ({ Save setShowFinalizeDesignReviewDetailsModal(true)} + onClick={() => setShowFinalizeEventDetailsModal(true)} > Finalize - diff --git a/src/frontend/src/pages/CalendarPage/DesignReviewSummaryModal.tsx b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx similarity index 54% rename from src/frontend/src/pages/CalendarPage/DesignReviewSummaryModal.tsx rename to src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx index 9b3b1abdaa..426dc799ac 100644 --- a/src/frontend/src/pages/CalendarPage/DesignReviewSummaryModal.tsx +++ b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx @@ -1,54 +1,53 @@ -import { DesignReview, DesignReviewStatus, TeamType, isAdmin, wbsPipe } from 'shared'; +import { Event, EventStatus, TeamType, isAdmin, wbsPipe } from 'shared'; import NERModal from '../../components/NERModal'; import { Box, Chip, IconButton, Link, Typography } from '@mui/material'; import EditIcon from '@mui/icons-material/Edit'; import { useState } from 'react'; -import DesignReviewSummaryModalDetails from './SummaryComponents/DesignReviewSummaryModalDetails'; -import DesignReviewSummaryModalAttendees from './SummaryComponents/DesignReviewSummaryModalAttendees'; import { getTeamTypeIcon } from './CalendarComponents/CalendarDayCard'; import { Link as RouterLink, useHistory } from 'react-router-dom'; import { routes } from '../../utils/routes'; import { useCurrentUser } from '../../hooks/users.hooks'; import DeleteIcon from '@mui/icons-material/Delete'; import { useToast } from '../../hooks/toasts.hooks'; -import { useDeleteDesignReview } from '../../hooks/design-reviews.hooks'; -import { designReviewStatusColor, designReviewStatusPipe } from '../../utils/design-review.utils'; +import { eventStatusColor, eventStatusPipe } from '../../utils/design-review.utils'; import NERSuccessButton from '../../components/NERSuccessButton'; -import { DesignReviewAvailabilityInfo } from './DesignReviewAvailabilityInfo'; import { CheckCircle } from '@mui/icons-material'; +import { useDeleteEvent } from '../../hooks/calendar.hooks'; +import EventSummaryModalDetails from './SummaryComponents/EventSummaryModalDetails'; +import EventSummaryModalAttendees from './SummaryComponents/EventSummaryModalAttendees'; +import { EventAvailabilityInfo } from './EventAvailabilityInfo'; -interface DRCSummaryModalProps { +interface EventSummaryModalProps { open: boolean; onHide: () => void; - designReview: DesignReview; + event: Event; teamTypes: TeamType[]; - markedStatus?: DesignReviewStatus; - setMarkedStatus?: (_: DesignReviewStatus) => void; + markedStatus?: EventStatus; + setMarkedStatus?: (_: EventStatus) => void; } -const DRCSummaryModal: React.FC = ({ +const EventSummaryModal: React.FC = ({ open, onHide, - designReview, + event, teamTypes, - markedStatus = DesignReviewStatus.UNCONFIRMED, + markedStatus = EventStatus.UNCONFIRMED, setMarkedStatus = () => {} -}: DRCSummaryModalProps) => { +}: EventSummaryModalProps) => { const user = useCurrentUser(); const toast = useToast(); const history = useHistory(); const [showDeleteModal, setShowDeleteModal] = useState(false); - const { mutateAsync: deleteDesignReview } = useDeleteDesignReview(designReview.designReviewId); + const { mutateAsync: deleteEvent } = useDeleteEvent(event.eventId); - const isDesignReviewCreator = user.userId === designReview.userCreated.userId; + const isEventCreator = user.userId === event.userCreated.userId; - const isScheduled = - designReview.status === DesignReviewStatus.SCHEDULED || designReview.status === DesignReviewStatus.DONE; + const isScheduled = event.status === EventStatus.SCHEDULED || event.status === EventStatus.DONE; const handleDelete = () => { try { - deleteDesignReview(); + deleteEvent(); history.push(routes.CALENDAR); } catch (e: unknown) { if (e instanceof Error) { @@ -67,39 +66,52 @@ const DRCSummaryModal: React.FC = ({ submitText="Yes" onSubmit={handleDelete} > - Are you sure you want to delete this design review? + Are you sure you want to delete this event? ); }; + const [firstWorkPackage] = event.workPackages; + + const wbsNum = firstWorkPackage + ? { + carNumber: firstWorkPackage.wbsElement.carNumber, + projectNumber: firstWorkPackage.wbsElement.projectNumber, + workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber + } + : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; + + const eventName = firstWorkPackage?.wbsElement?.name + ? `${firstWorkPackage.wbsElement.carNumber}.${firstWorkPackage.wbsElement.projectNumber}.${firstWorkPackage.wbsElement.workPackageNumber} - ${firstWorkPackage.wbsElement.name}` + : event.title; + return ( - {(isDesignReviewCreator || isAdmin(user.role)) && ( + {(isEventCreator || isAdmin(user.role)) && ( <> setShowDeleteModal(true)}> - + )} attendee.userId === user.userId) || isScheduled + !event.requiredMembers.concat(event.optionalMembers).some((attendee) => attendee.userId === user.userId) || + isScheduled } > @@ -114,19 +126,19 @@ const DRCSummaryModal: React.FC = ({ - {`${designReview.wbsName}`} + {`${eventName}`} = ({ /> {isScheduled && ( - )} - {designReview.status === DesignReviewStatus.CONFIRMED && ( + {event.status === EventStatus.CONFIRMED && ( - - {isDesignReviewCreator && ( + + {isEventCreator && ( - - Schedule Design Review + + Schedule Event )} )} - {designReview.status === DesignReviewStatus.UNCONFIRMED && ( - - )} + {event.status === EventStatus.UNCONFIRMED && } ); }; -export default DRCSummaryModal; +export default EventSummaryModal; diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewDelayModal.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventDelayModal.tsx similarity index 67% rename from src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewDelayModal.tsx rename to src/frontend/src/pages/CalendarPage/SummaryComponents/EventDelayModal.tsx index 207625567d..61f04e31ee 100644 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewDelayModal.tsx +++ b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventDelayModal.tsx @@ -1,17 +1,13 @@ import { TextField, Link, FormLabel, FormControl } from '@mui/material'; import { useState, ChangeEvent } from 'react'; -import { DesignReview, wbsPipe } from 'shared'; +import { Event, wbsPipe } from 'shared'; import { Link as RouterLink } from 'react-router-dom'; import NERModal from '../../../components/NERModal'; import NERSuccessButton from '../../../components/NERSuccessButton'; import { useToast } from '../../../hooks/toasts.hooks'; import { routes } from '../../../utils/routes'; -export const DesignReviewDelayModal: React.FC<{ open: boolean; onHide: () => void; designReview: DesignReview }> = ({ - open, - onHide, - designReview -}) => { +export const EventDelayModal: React.FC<{ open: boolean; onHide: () => void; event: Event }> = ({ open, onHide, event }) => { const toast = useToast(); const [weeks, setWeeks] = useState(1); const onChange = (e: ChangeEvent) => { @@ -22,6 +18,16 @@ export const DesignReviewDelayModal: React.FC<{ open: boolean; onHide: () => voi } }; + const [firstWorkPackage] = event.workPackages; + + const wbsNumber = firstWorkPackage + ? { + carNumber: firstWorkPackage.wbsElement.carNumber, + projectNumber: firstWorkPackage.wbsElement.projectNumber, + workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber + } + : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; + return ( @@ -38,7 +44,7 @@ export const DesignReviewDelayModal: React.FC<{ open: boolean; onHide: () => voi underline="none" color={'text.primary'} component={RouterLink} - to={`${routes.CHANGE_REQUESTS}/new?wbsNum=${wbsPipe(designReview.wbsNum)}&timelineDelay=${weeks >= 1 ? weeks : 1}`} + to={`${routes.CHANGE_REQUESTS}/new?wbsNum=${wbsPipe(wbsNumber)}&timelineDelay=${weeks >= 1 ? weeks : 1}`} > Delay diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewPill.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventPill.tsx similarity index 91% rename from src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewPill.tsx rename to src/frontend/src/pages/CalendarPage/SummaryComponents/EventPill.tsx index 21b7eb09e9..f111a2b677 100644 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewPill.tsx +++ b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventPill.tsx @@ -1,6 +1,6 @@ import { Typography, Box } from '@mui/material'; -export const DesignReviewPill: React.FC<{ +export const EventPill: React.FC<{ icon: React.ReactNode; displayText: string; }> = ({ icon, displayText }) => { diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewSummaryModalAttendees.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalAttendees.tsx similarity index 71% rename from src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewSummaryModalAttendees.tsx rename to src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalAttendees.tsx index 3a684d30d9..1ba13eb66b 100644 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewSummaryModalAttendees.tsx +++ b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalAttendees.tsx @@ -1,50 +1,51 @@ import { Grid, Typography } from '@mui/material'; import { Box } from '@mui/system'; -import { DesignReview, User } from 'shared'; +import { Event, User } from 'shared'; import { MemberPill } from '../../../components/MemberPill'; import { useToast } from '../../../hooks/toasts.hooks'; import { useCurrentUser } from '../../../hooks/users.hooks'; -import { useEditDesignReview } from '../../../hooks/design-reviews.hooks'; -import LoadingIndicator from '../../../components/LoadingIndicator'; -interface DesignReviewSummaryModalAttendeesProps { - designReview: DesignReview; +interface EventSummaryModalAttendeesProps { + event: Event; } -interface DesignReviewEditAttendeesProps { +interface EventEditAttendeesProps { requiredMembers: User[]; optionalMembers: User[]; } -const DesignReviewSummaryModalAttendees: React.FC = ({ designReview }) => { +const EventSummaryModalAttendees: React.FC = ({ event }) => { const toast = useToast(); - const { requiredMembers } = designReview; - const { optionalMembers } = designReview; + const { requiredMembers } = event; + const { optionalMembers } = event; const currentUser = useCurrentUser(); + /* const { isLoading: editDesignReviewIsLoading, mutateAsync: editDesignReview } = useEditDesignReview( designReview.designReviewId ); + */ const handleRemoveRequiredMember = (user: User) => { - if (currentUser.userId === designReview.userCreated.userId) { + if (currentUser.userId === event.userCreated.userId) { const updatedMembers = requiredMembers.filter((member) => member.userId !== user.userId); saveMembers({ requiredMembers: updatedMembers, optionalMembers }); } else { - toast.error('Only the creator of the Design Review can edit attendees'); + toast.error('Only the creator of the Event can edit attendees'); } }; const handleRemoveOptionalMember = (user: User) => { - if (currentUser.userId === designReview.userCreated.userId) { + if (currentUser.userId === event.userCreated.userId) { const updatedMembers = optionalMembers.filter((member) => member.userId !== user.userId); saveMembers({ requiredMembers, optionalMembers: updatedMembers }); } else { - toast.error('Only the creator of the Design Review can edit attendees'); + toast.error('Only the creator of the Event can edit attendees'); } }; - const saveMembers = async (payload: DesignReviewEditAttendeesProps) => { + const saveMembers = async (_payload: EventEditAttendeesProps) => { + /* try { await editDesignReview({ ...designReview, @@ -61,9 +62,10 @@ const DesignReviewSummaryModalAttendees: React.FC; + // if (editDesignReviewIsLoading) return ; return ( @@ -72,13 +74,13 @@ const DesignReviewSummaryModalAttendees: React.FCRequired: - + {requiredMembers.map((member, index) => ( { handleRemoveRequiredMember(member); } @@ -98,7 +100,7 @@ const DesignReviewSummaryModalAttendees: React.FC { handleRemoveOptionalMember(member); } @@ -114,4 +116,4 @@ const DesignReviewSummaryModalAttendees: React.FC void; handleDelayClick: () => void; teamTypes: TeamType[]; } -const DesignReviewSummaryModalButtons: React.FC = ({ - designReview, +const EventSummaryModalButtons: React.FC = ({ + event: _event, handleDelayClick, handleStageGateClick, - teamTypes + teamTypes: _teamTypes }) => { const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); return ( - {isCreateModalOpen && ( + { + isCreateModalOpen && isCreateModalOpen + /* { @@ -33,7 +34,8 @@ const DesignReviewSummaryModalButtons: React.FC - )} + */ + } setIsCreateModalOpen(true)} > - Schedule Another DR + Schedule Another Event ); }; -export default DesignReviewSummaryModalButtons; +export default EventSummaryModalButtons; diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewSummaryModalDetails.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx similarity index 56% rename from src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewSummaryModalDetails.tsx rename to src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx index 44e340ab20..89d0af311b 100644 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/DesignReviewSummaryModalDetails.tsx +++ b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx @@ -1,27 +1,27 @@ import { Box, Checkbox, FormControlLabel, Link, Typography } from '@mui/material'; -import { DesignReview, DesignReviewStatus, TeamType } from 'shared'; +import { Event, EventStatus, TeamType } from 'shared'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import LocationOnIcon from '@mui/icons-material/LocationOn'; import DescriptionIcon from '@mui/icons-material/Description'; import VideocamIcon from '@mui/icons-material/Videocam'; -import { DesignReviewPill } from './DesignReviewPill'; -import { meetingStartTimePipe } from '../../../utils/pipes'; +import { EventPill } from './EventPill'; import { useState } from 'react'; import StageGateWorkPackageModalContainer from '../../WorkPackageDetailPage/StageGateWorkPackageModalContainer/StageGateWorkPackageModalContainer'; -import { DesignReviewDelayModal } from './DesignReviewDelayModal'; -import DesignReviewSummaryModalButtons from './DesignReviewSummaryModalButtons'; import NERModal from '../../../components/NERModal'; -import { useSetDesignReviewStatus } from '../../../hooks/design-reviews.hooks'; +import { useSetEventStatus } from '../../../hooks/calendar.hooks'; +import { meetingStartTimePipeScheduleSlot } from '../../../utils/pipes'; +import { EventDelayModal } from './EventDelayModal'; +import EventSummaryModalButtons from './EventSummaryModalButtons'; -interface DesignReviewSummaryModalDetailsProps { - designReview: DesignReview; +interface EventSummaryModalDetailsProps { + event: Event; teamTypes: TeamType[]; - markedStatus: DesignReviewStatus; - setMarkedStatus: (_: DesignReviewStatus) => void; + markedStatus: EventStatus; + setMarkedStatus: (_: EventStatus) => void; } -const DesignReviewSummaryModalDetails: React.FC = ({ - designReview, +const EventSummaryModalDetails: React.FC = ({ + event, teamTypes, markedStatus, setMarkedStatus @@ -30,23 +30,23 @@ const DesignReviewSummaryModalDetails: React.FC(false); const [showMarkCompleteModal, setShowMarkCompleteModal] = useState(false); const [showUnmarkCompleteModal, setShowUnmarkCompleteModal] = useState(false); - const { mutateAsync } = useSetDesignReviewStatus(designReview.designReviewId); + const { mutateAsync } = useSetEventStatus(event.eventId); const MarkCompleteModal: React.FC = () => { return ( setShowMarkCompleteModal(false)} cancelText="No" submitText="Yes" onSubmit={async () => { setShowMarkCompleteModal(false); - await mutateAsync({ status: DesignReviewStatus.DONE }); - setMarkedStatus(DesignReviewStatus.DONE); + await mutateAsync({ status: EventStatus.DONE }); + setMarkedStatus(EventStatus.DONE); }} > - Are you sure you want to mark this design review as complete? + Are you sure you want to mark this event as complete? ); }; @@ -55,58 +55,65 @@ const DesignReviewSummaryModalDetails: React.FC setShowUnmarkCompleteModal(false)} cancelText="No" submitText="Yes" onSubmit={async () => { setShowUnmarkCompleteModal(false); - await mutateAsync({ status: DesignReviewStatus.SCHEDULED }); - setMarkedStatus(DesignReviewStatus.SCHEDULED); + await mutateAsync({ status: EventStatus.SCHEDULED }); + setMarkedStatus(EventStatus.SCHEDULED); }} > - Are you sure you want to mark this design review as not complete? + Are you sure you want to mark this event as not complete? ); }; + const [firstWorkPackage] = event.workPackages; + + const wbsNum = firstWorkPackage + ? { + carNumber: firstWorkPackage.wbsElement.carNumber, + projectNumber: firstWorkPackage.wbsElement.projectNumber, + workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber + } + : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; + return ( <> setShowStageGateModal(false)} hideStatus /> - setShowDelayModal(false)} designReview={designReview} /> + setShowDelayModal(false)} event={event} /> - } displayText={meetingStartTimePipe(designReview.meetingTimes)} /> - } - displayText={designReview.location ? designReview.location : 'Online'} - /> + } displayText={meetingStartTimePipeScheduleSlot(event.scheduledTimes)} /> + } displayText={event.location ? event.location : 'Online'} /> - + - {designReview.docTemplateLink ? 'Question Document' : 'No Question Document'} + {event.questionDocument ? 'Question Document' : 'No Question Document'} { - if (markedStatus === DesignReviewStatus.DONE) setShowUnmarkCompleteModal(true); + if (markedStatus === EventStatus.DONE) setShowUnmarkCompleteModal(true); else setShowMarkCompleteModal(true); }} sx={{ @@ -120,13 +127,13 @@ const DesignReviewSummaryModalDetails: React.FC - - {designReview.zoomLink ? 'Zoom Link' : 'No Zoom'} + + {event.zoomLink ? 'Zoom Link' : 'No Zoom'} - {markedStatus === DesignReviewStatus.DONE && ( - setShowStageGateModal(true)} handleDelayClick={() => setShowDelayModal(true)} teamTypes={teamTypes} @@ -141,4 +148,4 @@ const DesignReviewSummaryModalDetails: React.FC { py: 1 }} > - {[DesignReviewStatus.UNCONFIRMED, DesignReviewStatus.SCHEDULED].map((status) => { + {[EventStatus.UNCONFIRMED, EventStatus.SCHEDULED].map((status) => { return ( { }} > - {DesignReviewStatusTextPipe(status)} + {DesignReviewEventStatusTextPipe(status)} ); @@ -193,7 +193,7 @@ const GanttChartColorLegend = () => { { dateCreated: new Date(), teamTypes: [], changes: [], - designReviews: [], + events: [], deleted: false }; diff --git a/src/frontend/src/pages/HomePage/components/DesignReviewCard.tsx b/src/frontend/src/pages/HomePage/components/EventCard.tsx similarity index 59% rename from src/frontend/src/pages/HomePage/components/DesignReviewCard.tsx rename to src/frontend/src/pages/HomePage/components/EventCard.tsx index a0fbd0d3e4..c392993c03 100644 --- a/src/frontend/src/pages/HomePage/components/DesignReviewCard.tsx +++ b/src/frontend/src/pages/HomePage/components/EventCard.tsx @@ -1,6 +1,6 @@ import { Box, Card, CardContent, Link, Stack, Typography, useTheme } from '@mui/material'; -import { AuthenticatedUser, DesignReview, meetingStartTimePipe } from 'shared'; -import { datePipe, projectWbsPipe } from '../../../utils/pipes'; +import { AuthenticatedUser, Event } from 'shared'; +import { datePipe, meetingStartTimePipeScheduleSlot, projectWbsPipe } from '../../../utils/pipes'; import { routes } from '../../../utils/routes'; import { Link as RouterLink } from 'react-router-dom'; import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; @@ -9,12 +9,12 @@ import { useHistory } from 'react-router-dom'; import { NERButton } from '../../../components/NERButton'; import { timezoneOffset } from '../../../utils/datetime.utils'; -interface DesignReviewProps { - designReview: DesignReview; +interface EventProps { + event: Event; user: AuthenticatedUser; } -const DesignReviewInfo = ({ icon, text, link }: { icon: React.ReactNode; text: string; link?: boolean }) => { +const EventInfo = ({ icon, text, link }: { icon: React.ReactNode; text: string; link?: boolean }) => { return ( {icon} @@ -33,9 +33,9 @@ const DesignReviewInfo = ({ icon, text, link }: { icon: React.ReactNode; text: s ); }; -const DisplayStatus: React.FC = ({ designReview, user }) => { +const DisplayStatus: React.FC = ({ event, user }) => { const history = useHistory(); - const confirmedMemberIds = designReview.confirmedMembers.map((user) => user.userId); + const confirmedMemberIds = event.confirmedMembers.map((user) => user.userId); return ( <> @@ -45,14 +45,14 @@ const DisplayStatus: React.FC = ({ designReview, user }) => { size="small" sx={{ color: 'white', padding: 1 }} onClick={() => { - history.push(`${routes.SETTINGS_PREFERENCES}?drId=${designReview.designReviewId}`); + history.push(`${routes.SETTINGS_PREFERENCES}?eventId=${event.eventId}`); }} component={RouterLink} > Confirm Availibility ) : ( - {designReview.status} + {event.status} )} ); @@ -67,9 +67,25 @@ const removeYear = (str: string): string => { return str.substring(0, str.length - 5); }; -const UpcomingDesignReviewsCard: React.FC = ({ designReview, user }) => { +const UpcomingEventCard: React.FC = ({ event, user }) => { const theme = useTheme(); - const timezoneAdjustedDate = timezoneOffset(designReview.dateScheduled); + const firstScheduledDate = event.scheduledTimes[0]?.initialDateScheduled; + const timezoneAdjustedDate = firstScheduledDate ? timezoneOffset(firstScheduledDate) : new Date(); + + const [firstWorkPackage] = event.workPackages; + + const wbsNumber = firstWorkPackage + ? { + carNumber: firstWorkPackage.wbsElement.carNumber, + projectNumber: firstWorkPackage.wbsElement.projectNumber, + workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber + } + : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; + + const eventName = firstWorkPackage?.wbsElement?.name + ? `${firstWorkPackage.wbsElement.carNumber}.${firstWorkPackage.wbsElement.projectNumber}.${firstWorkPackage.wbsElement.workPackageNumber} - ${firstWorkPackage.wbsElement.name}` + : event.title; + return ( = ({ designReview, - - {designReview.wbsName} + + {eventName} @@ -96,21 +112,17 @@ const UpcomingDesignReviewsCard: React.FC = ({ designReview, ', ' + removeYear(datePipe(timezoneAdjustedDate)) + ' @ ' + - meetingStartTimePipe(designReview.meetingTimes)} + meetingStartTimePipeScheduleSlot(event.scheduledTimes)} - {designReview.isInPerson && !!designReview.location && ( - } text={designReview.location} /> - )} - {designReview.isOnline && !!designReview.zoomLink && ( - } text={designReview.zoomLink} link /> - )} + {event.location && } text={event.location} />} + {event.zoomLink && } text={event.zoomLink} link />} - + ); }; -export default UpcomingDesignReviewsCard; +export default UpcomingEventCard; diff --git a/src/frontend/src/pages/HomePage/components/UpcomingDesignReviews.tsx b/src/frontend/src/pages/HomePage/components/UpcomingDesignReviews.tsx index 7d0d4c0565..47192c14fd 100644 --- a/src/frontend/src/pages/HomePage/components/UpcomingDesignReviews.tsx +++ b/src/frontend/src/pages/HomePage/components/UpcomingDesignReviews.tsx @@ -3,20 +3,20 @@ * See the LICENSE file in the repository root folder for details. */ -import DesignReviewCard from './DesignReviewCard'; -import { useAllDesignReviews } from '../../../hooks/design-reviews.hooks'; +import DesignReviewCard from './EventCard'; +import { useAllEvents } from '../../../hooks/calendar.hooks'; import ErrorPage from '../../ErrorPage'; -import { AuthenticatedUser, DesignReviewStatus, wbsPipe } from 'shared'; +import { AuthenticatedUser, EventStatus } from 'shared'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ScrollablePageBlock from './ScrollablePageBlock'; import EmptyPageBlockDisplay from './EmptyPageBlockDisplay'; import { Error } from '@mui/icons-material'; -interface UpcomingDesignReviewProps { +interface UpcomingEventProps { user: AuthenticatedUser; } -const NoUpcomingDesignReviewsDisplay: React.FC = () => { +const NoUpcomingEventsDisplay: React.FC = () => { return ( } @@ -26,37 +26,41 @@ const NoUpcomingDesignReviewsDisplay: React.FC = () => { ); }; -const UpcomingDesignReviews: React.FC = ({ user }) => { - const { data: designReviews, isLoading, isError, error } = useAllDesignReviews(); +const UpcomingEvents: React.FC = ({ user }) => { + const { data: events, isLoading, isError, error } = useAllEvents(); - if (isLoading || !designReviews) return ; + if (isLoading || !events) return ; if (isError) return ; - const filteredDesignReviews = designReviews.filter((review) => { - const scheduledDate = review.dateScheduled; + const filteredEvents = events.filter((event) => { + // Get the first scheduled date + const scheduledDate = event.scheduledTimes[0]?.initialDateScheduled; + if (!scheduledDate) return false; + const currentDate = new Date(); const inTwoWeeks = new Date(); inTwoWeeks.setDate(currentDate.getDate() + 14); + const memberUserIds = [ - ...review.requiredMembers.map((user) => user.userId), - ...review.optionalMembers.map((user) => user.userId) + ...event.requiredMembers.map((user) => user.userId), + ...event.optionalMembers.map((user) => user.userId) ]; - // added in case the person who created the design review forgets to add their name onto the required members - memberUserIds.concat(review.userCreated.userId); + + memberUserIds.push(event.userCreated.userId); return ( scheduledDate >= currentDate && scheduledDate <= inTwoWeeks && - review.status !== DesignReviewStatus.DONE && + event.status !== EventStatus.DONE && memberUserIds.includes(user.userId) ); }); const fullDisplay = ( - - {filteredDesignReviews.length === 0 ? ( - + + {filteredEvents.length === 0 ? ( + ) : ( - filteredDesignReviews.map((d) => ) + filteredEvents.map((event) => ) )} ); @@ -64,4 +68,4 @@ const UpcomingDesignReviews: React.FC = ({ user }) => return fullDisplay; }; -export default UpcomingDesignReviews; +export default UpcomingEvents; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx index 27504d4513..eacbb652a7 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx @@ -4,7 +4,7 @@ */ import { Route, Switch } from 'react-router-dom'; import { routes } from '../../utils/routes'; -import DesignReviewDetails from '../CalendarPage/DesignReviewDetailPage/DesignReviewDetails'; +import DesignReviewDetails from '../CalendarPage/EventDetailPage/EventDetails'; import CalendarTab from './CalendarTab'; const NewCalendar: React.FC = () => { diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 65ecdf2acf..5baf73a104 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -5,17 +5,17 @@ import { useState } from 'react'; import { Box, Grid, Stack, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material'; import PageLayout from '../../components/PageLayout'; -import { DesignReview, DesignReviewStatus } from 'shared'; +import { Event, EventStatus } from 'shared'; import MonthSelector from '../CalendarPage/CalendarComponents/MonthSelector'; import CalendarDayCard, { getTeamTypeIcon } from '../CalendarPage/CalendarComponents/CalendarDayCard'; -import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; +import { DAY_NAMES, enumToArray } from '../../utils/design-review.utils'; import ActionsMenu from '../../components/ActionsMenu'; -import { useAllDesignReviews } from '../../hooks/design-reviews.hooks'; +import { useAllEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { useCurrentUser } from '../../hooks/users.hooks'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; -import DRCSummaryModal from '../CalendarPage/DesignReviewSummaryModal'; +import DRCSummaryModal from '../CalendarPage/EventSummaryModal'; import { useAllTeamTypes } from '../../hooks/team-types.hooks'; import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; @@ -29,87 +29,112 @@ const NewCalendarPage = () => { } = useAllTeamTypes(); const [displayMonthYear, setDisplayMonthYear] = useState(new Date()); - const { isLoading, isError, error, data: allDesignReviews } = useAllDesignReviews(); + const { isLoading, isError, error, data: allEvents } = useAllEvents(); const user = useCurrentUser(); - const [unconfirmedDesignReview, setUnconfirmedDesignReview] = useState(); + const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); - if (isLoading || !allDesignReviews) return ; + if (isLoading || !allEvents) return ; if (isError) return ; - const confirmedDesignReviews = allDesignReviews; + // Sort events by date and time + const sortedEvents = [...allEvents].sort((event1, event2) => { + const date1 = event1.scheduledTimes[0]?.initialDateScheduled + ? new Date(event1.scheduledTimes[0].initialDateScheduled).getTime() + : 0; + const date2 = event2.scheduledTimes[0]?.initialDateScheduled + ? new Date(event2.scheduledTimes[0].initialDateScheduled).getTime() + : 0; - const eventDict = new Map(); - confirmedDesignReviews.sort((designReview1, designReview2) => { - if (designReview1.dateScheduled.getTime() === designReview2.dateScheduled.getTime()) { - return designReview1.meetingTimes[0] - designReview2.meetingTimes[0]; + if (date1 === date2) { + const time1 = event1.scheduledTimes[0]?.startTime ? new Date(event1.scheduledTimes[0].startTime).getTime() : 0; + const time2 = event2.scheduledTimes[0]?.startTime ? new Date(event2.scheduledTimes[0].startTime).getTime() : 0; + return time1 - time2; } - return designReview1.dateScheduled.getTime() - designReview2.dateScheduled.getTime(); + return date1 - date2; }); - confirmedDesignReviews.forEach((designReview) => { - // Accessing the date actually converts it to local time, which causes the date to be off. This is a workaround. - const date = datePipe( - new Date(designReview.dateScheduled.getTime() - designReview.dateScheduled.getTimezoneOffset() * -60000) - ); + const eventDict = new Map(); + sortedEvents.forEach((event) => { + const firstScheduledDate = event.scheduledTimes[0]?.initialDateScheduled; + if (!firstScheduledDate) return; + + // Convert string to Date + const dateObj = new Date(firstScheduledDate); + const date = datePipe(new Date(dateObj.getTime() - dateObj.getTimezoneOffset() * -60000)); if (eventDict.has(date)) { - eventDict.get(date)?.push(designReview); + eventDict.get(date)?.push(event); } else { - eventDict.set(date, [designReview]); + eventDict.set(date, [event]); } }); - const currentUserDesignReviews = allDesignReviews.filter( - (designReview) => designReview.userCreated.userId === user.userId && designReview.status !== DesignReviewStatus.DONE + const currentUserEvents = allEvents.filter( + (event) => event.userCreated.userId === user.userId && event.status !== EventStatus.DONE ); - const startOfEachWeek = [0, 7, 14, 21, 28, 35]; + // Generate calendar dates + const firstDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 1); + const lastDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 0); - const isDayInDifferentMonth = (day: number, week: number) => { - return day < week - 7 || day < 1 || day > week + 7; - }; + const paddingStart = firstDayOfMonth.getDay(); // 0-6 (Sun-Sat) + const totalDays = lastDayOfMonth.getDate(); + const totalCells = Math.ceil((paddingStart + totalDays) / 7) * 7; + + const calendarDates: Date[] = []; + + // Add padding days from previous month + const prevMonthLastDay = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 0); + const prevMonthDays = prevMonthLastDay.getDate(); + for (let i = paddingStart - 1; i >= 0; i--) { + calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, prevMonthDays - i)); + } + + // Add current month days + for (let day = 1; day <= totalDays; day++) { + calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), day)); + } + + // Add padding days from next month + const remainingCells = totalCells - calendarDates.length; + for (let day = 1; day <= remainingCells; day++) { + calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, day)); + } + + const eventButtons = (events: Event[]) => { + return events.map((event) => { + // Get team type name directly from event + const teamTypeName = event.teamType?.name || 'Default'; + + // Get title from work packages or event title + const title = + event.workPackages.length > 0 ? event.workPackages.map((wp) => wp.wbsElement.name).join(', ') : event.title; - const designReviewButtons = (designReviews: DesignReview[]) => { - return designReviews.map((designReview) => { return { - icon: getTeamTypeIcon(designReview.teamType.name), - title: designReview.wbsName, + icon: getTeamTypeIcon(teamTypeName), + title, onClick: () => { - setUnconfirmedDesignReview(designReview); + setSelectedEvent(event); }, disabled: false }; }); }; - const NoDRSButton = () => { + const NoEventsButton = () => { return [ { - title: 'No Design Reviews', + title: 'No Events', disabled: true, onClick: () => {} } ]; }; - const paddingArrayStart = [...Array(calendarPaddingDays(displayMonthYear)).keys()] - .map( - (day) => - daysInMonth(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, displayMonthYear.getDate())) - - day - ) - .reverse(); - const paddingArrayEnd = [ - ...Array(7 - ((daysInMonth(displayMonthYear) + calendarPaddingDays(displayMonthYear)) % 7)).keys() - ].map((day) => day + 1); - const daysThisMonth = paddingArrayStart - .concat([...Array(daysInMonth(displayMonthYear)).keys()].map((day) => day + 1)) - .concat(paddingArrayEnd.length < 7 ? paddingArrayEnd : []); - - const unconfirmedDRSDropdown = ( + const unconfirmedEventsDropdown = ( My Unconfirmed DRs @@ -120,24 +145,24 @@ const NewCalendarPage = () => { return ( <> - {unconfirmedDesignReview && ( + {selectedEvent && ( { - setUnconfirmedDesignReview(undefined); + setSelectedEvent(undefined); }} - designReview={unconfirmedDesignReview as DesignReview} + event={selectedEvent} teamTypes={allTeamTypes} /> )} - + Calendar - {unconfirmedDRSDropdown} + {unconfirmedEventsDropdown} @@ -146,50 +171,36 @@ const NewCalendarPage = () => { {enumToArray(DAY_NAMES).map((day, index) => ( - { - // Day of the week display based on current breakpoint - isLargerView ? day : isExtraSmallView ? day.charAt(0) : day.substring(0, 3) - } + {isLargerView ? day : isExtraSmallView ? day.charAt(0) : day.substring(0, 3)} ))} - {startOfEachWeek.map((week, weekIndex) => ( + {Array.from({ length: Math.ceil(calendarDates.length / 7) }, (_, weekIndex) => ( - {daysThisMonth.slice(week, week + 7).map((day, dayIndex) => { - const cardDate = new Date( - displayMonthYear.getFullYear(), - displayMonthYear.getMonth() + (isDayInDifferentMonth(day, week) ? (day > 15 ? -1 : 1) : 0), - day - ); - return ( - - - - - - ); - })} + {calendarDates.slice(weekIndex * 7, weekIndex * 7 + 7).map((cardDate, dayIndex) => ( + + + + + + ))} ))} - + diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettings.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettings.tsx index f92a0d62cf..b44d530913 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettings.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettings.tsx @@ -21,7 +21,7 @@ import { useUpdateUserScheduleSettings, useUserScheduleSettings } from '../../.. import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; import { useToast } from '../../../hooks/toasts.hooks'; -import { useSingleDesignReview } from '../../../hooks/design-reviews.hooks'; +import { useSingleEvent } from '../../../hooks/calendar.hooks'; import { useQuery } from '../../../hooks/utils.hooks'; import { deeplyCopy } from 'shared/src/utils'; import { availabilityTransformer } from '../../../apis/transformers/users.transformers'; @@ -39,7 +39,7 @@ const UserScheduleSettings = ({ user }: { user: AuthenticatedUser }) => { const [edit, setEdit] = useState(false); const toast = useToast(); const query = useQuery(); - const designReviewId = query.get('drId'); + const eventId = query.get('eventId'); const { data, isLoading, isError, error } = useUserScheduleSettings(user.userId); const { @@ -49,16 +49,16 @@ const UserScheduleSettings = ({ user }: { user: AuthenticatedUser }) => { error: updateUserScheduleSettingsError } = useUpdateUserScheduleSettings(); const { - data: designReview, - isError: designReviewIsError, - error: designReviewError, - isLoading: designReviewIsLoading - } = useSingleDesignReview(designReviewId ?? undefined); + data: event, + isError: eventIsError, + error: eventError, + isLoading: eventIsLoading + } = useSingleEvent(eventId ?? undefined); - if (designReviewId && (!designReview || designReviewIsLoading)) return ; + if (eventId && (!event || eventIsLoading)) return ; if (!data || isLoading || updateUserScheduleSettingsIsLoading) return ; - if (designReviewId && designReviewIsError) return ; + if (eventId && eventIsError) return ; if (isError) return ; if (updateUserScheduleSettingsIsError) return ; @@ -121,7 +121,7 @@ const UserScheduleSettings = ({ user }: { user: AuthenticatedUser }) => { {!edit ? ( - + ) : ( { const [availabilityOpen, setAvailabilityOpen] = useState(false); const toast = useToast(); - const defaultOpen = designReview !== undefined; + const defaultOpen = event !== undefined; const [confirmAvailabilityOpen, setConfirmAvailabilityOpen] = useState(defaultOpen || false); const [confirmedAvailabilities, setConfirmedAvailabilities] = useState(new Map()); - const { mutateAsync } = useMarkUserConfirmed(designReview?.designReviewId || ''); - const confirmModalTitle = designReview - ? `Update your availability for the ${designReview?.wbsName} Design Review on the week of ${new Date( - designReview.dateScheduled.getTime() - designReview.dateScheduled.getTimezoneOffset() * -60000 - ).toLocaleDateString()}` - : ''; + const { mutateAsync } = useMarkUserConfirmed(event?.eventId || ''); + + // Get the first scheduled date from the event + const firstScheduledDate = event?.scheduledTimes[0]?.initialDateScheduled; + + // Get work package names for the event title + const workPackageNames = event?.workPackages.map((wp) => wp.wbsElement.name).join(', ') || 'Event'; + + const confirmModalTitle = + event && firstScheduledDate + ? `Update your availability for the ${workPackageNames} Design Review on the week of ${new Date( + firstScheduledDate.getTime() - firstScheduledDate.getTimezoneOffset() * -60000 + ).toLocaleDateString()}` + : ''; const handleConfirm = async (payload: { availability: Availability[] }) => { setConfirmAvailabilityOpen(false); @@ -44,15 +52,17 @@ const UserScheduleSettingsView = ({ } }; + const firstDate = useMemo(() => { + const firstSlot = event?.scheduledTimes[0]; + return firstSlot?.initialDateScheduled ?? new Date(); + }, [event?.scheduledTimes]); + useEffect(() => { if (confirmedAvailabilities.size === 0 && scheduleSettings.availabilities.length > 0) { - const confirmed = getMostRecentAvailabilities( - scheduleSettings.availabilities, - designReview?.initialDate || new Date() - ); + const confirmed = getMostRecentAvailabilities(scheduleSettings.availabilities, firstDate); setConfirmedAvailabilities(new Map(confirmed.map((availability) => [availability.dateSet.getTime(), availability]))); } - }, [scheduleSettings.availabilities, designReview, confirmedAvailabilities]); + }, [confirmedAvailabilities.size, scheduleSettings.availabilities, firstDate]); return ( @@ -69,7 +79,7 @@ const UserScheduleSettingsView = ({ confirmedAvailabilities={confirmedAvailabilities} setConfirmedAvailabilities={setConfirmedAvailabilities} totalAvailabilities={scheduleSettings.availabilities} - initialDate={designReview?.initialDate || new Date()} + initialDate={firstScheduledDate || new Date()} onSubmit={() => handleConfirm({ availability: Array.from(confirmedAvailabilities.values()) })} canChangeDateRange={false} /> diff --git a/src/frontend/src/tests/hooks/DesignReviews.hooks.test.tsx b/src/frontend/src/tests/hooks/DesignReviews.hooks.test.tsx deleted file mode 100644 index 5217699119..0000000000 --- a/src/frontend/src/tests/hooks/DesignReviews.hooks.test.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of NER's FinishLine and licensed under GNU AGPLv3. - * See the LICENSE file in the repository root folder for details. - */ - -import { renderHook, waitFor } from '@testing-library/react'; -import { AxiosResponse } from 'axios'; -import { DesignReview } from 'shared'; -import wrapper from '../../app/AppContextQuery'; -import { mockPromiseAxiosResponse } from '../test-support/test-data/test-utils.stub'; -import { exampleAllDesignReviews, exampleDesignReview1 } from '../test-support/test-data/design-reviews.stub'; -import { getAllDesignReviews, getSingleDesignReview } from '../../apis/design-reviews.api'; -import { useAllDesignReviews, useSingleDesignReview } from '../../hooks/design-reviews.hooks'; - -vi.mock('../../apis/design-reviews.api'); - -describe('design review hooks', () => { - it('handles getting a list of design reviews', async () => { - const mockedGetAllDesignReviews = getAllDesignReviews as jest.Mock>>; - mockedGetAllDesignReviews.mockReturnValue(mockPromiseAxiosResponse(exampleAllDesignReviews)); - - const { result } = renderHook(() => useAllDesignReviews(), { wrapper }); - await waitFor(() => result.current.isSuccess); - expect(result.current.data).toEqual(exampleAllDesignReviews); - }); - - it('handles getting a single design review', async () => { - const mockedGetSingleDesignReview = getSingleDesignReview as jest.Mock>>; - mockedGetSingleDesignReview.mockReturnValue(mockPromiseAxiosResponse(exampleDesignReview1)); - - const { result } = renderHook(() => useSingleDesignReview('1'), { wrapper }); - await waitFor(() => result.current.isSuccess); - expect(result.current.data).toEqual(exampleDesignReview1); - }); -}); diff --git a/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts b/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts index f28717f9ea..51a5ba9eb6 100644 --- a/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts +++ b/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts @@ -3,9 +3,8 @@ * See the LICENSE file in the repository root folder for details. */ -import { DesignReview, DesignReviewStatus, TeamType } from 'shared'; +import { DayOfWeek, Event, EventStatus, TeamType } from 'shared'; import { exampleAdminUser, exampleAppAdminUser } from './users.stub'; -import { exampleWbsProject1 } from './wbs-numbers.stub'; export const teamType1: TeamType = { teamTypeId: '1', @@ -18,44 +17,136 @@ export const teamType1: TeamType = { deletedById: undefined }; -export const exampleDesignReview1: DesignReview = { - designReviewId: '1', - dateScheduled: new Date('2024-03-25'), - meetingTimes: [0, 1, 2, 3], - dateCreated: new Date('2024-03-10'), +export const exampleDesignReviewEvent1: Event = { + eventId: '1', + title: 'Design Review - Impact Attenuator', + approved: true, userCreated: exampleAdminUser, - status: DesignReviewStatus.CONFIRMED, - teamType: teamType1, + dateCreated: new Date('2024-03-10'), + eventTypeId: 'design-review-event-type-id', + approvalRequiredFrom: undefined, + scheduledTimes: [ + { + scheduleSlotId: 'slot-1', + days: [DayOfWeek.TUESDAY], + startTime: new Date('2024-03-25T10:00:00'), + endTime: new Date('2024-03-25T11:00:00'), + recurrenceNumber: 0, + initialDateScheduled: new Date('2024-03-25'), + endDate: new Date('2024-03-25'), + allDay: false + }, + { + scheduleSlotId: 'slot-2', + days: [DayOfWeek.TUESDAY], + startTime: new Date('2024-03-25T11:00:00'), + endTime: new Date('2024-03-25T12:00:00'), + recurrenceNumber: 0, + initialDateScheduled: new Date('2024-03-25'), + endDate: new Date('2024-03-25'), + allDay: false + }, + { + scheduleSlotId: 'slot-3', + days: [DayOfWeek.TUESDAY], + startTime: new Date('2024-03-25T12:00:00'), + endTime: new Date('2024-03-25T13:00:00'), + recurrenceNumber: 0, + initialDateScheduled: new Date('2024-03-25'), + endDate: new Date('2024-03-25'), + allDay: false + }, + { + scheduleSlotId: 'slot-4', + days: [DayOfWeek.TUESDAY], + startTime: new Date('2024-03-25T13:00:00'), + endTime: new Date('2024-03-25T14:00:00'), + recurrenceNumber: 0, + initialDateScheduled: new Date('2024-03-25'), + endDate: new Date('2024-03-25'), + allDay: false + } + ], requiredMembers: [exampleAdminUser], optionalMembers: [], confirmedMembers: [exampleAdminUser], deniedMembers: [], - isOnline: true, - isInPerson: false, - attendees: [exampleAdminUser], - wbsName: '1', - wbsNum: exampleWbsProject1, - initialDate: new Date('2024-03-25') + teams: [], // Design reviews don't link to specific teams + location: undefined, // Online only + zoomLink: 'https://zoom.us/j/example123', + shops: [], + machinery: [], + workPackages: [ + { + workPackageId: 'wp-1', + wbsElement: { + name: 'Impact Attenuator', + carNumber: 0, + projectNumber: 0, + workPackageNumber: 0 + } + } + ], + documentIds: [], + questionDocument: 'https://docs.google.com/document/d/example-questions', + description: undefined, + status: EventStatus.CONFIRMED }; -export const exampleDesignReview2: DesignReview = { - designReviewId: '2', - dateScheduled: new Date('2024-03-25'), - meetingTimes: [0, 4], - dateCreated: new Date('2024-03-10'), +export const exampleDesignReviewEvent2: Event = { + eventId: '2', + title: 'Design Review - Bodywork', + approved: true, userCreated: exampleAppAdminUser, - status: DesignReviewStatus.CONFIRMED, - teamType: teamType1, + dateCreated: new Date('2024-03-10'), + eventTypeId: 'design-review-event-type-id', + approvalRequiredFrom: undefined, + scheduledTimes: [ + { + scheduleSlotId: 'slot-5', + days: [DayOfWeek.TUESDAY], + startTime: new Date('2024-03-25T10:00:00'), + endTime: new Date('2024-03-25T11:00:00'), + recurrenceNumber: 0, + initialDateScheduled: new Date('2024-03-25'), + endDate: new Date('2024-03-25'), + allDay: false + }, + { + scheduleSlotId: 'slot-6', + days: [DayOfWeek.TUESDAY], + startTime: new Date('2024-03-25T14:00:00'), + endTime: new Date('2024-03-25T15:00:00'), + recurrenceNumber: 0, + initialDateScheduled: new Date('2024-03-25'), + endDate: new Date('2024-03-25'), + allDay: false + } + ], requiredMembers: [exampleAppAdminUser], optionalMembers: [], confirmedMembers: [exampleAppAdminUser], deniedMembers: [], - isOnline: false, - isInPerson: true, - attendees: [exampleAppAdminUser], - wbsName: '1', - wbsNum: exampleWbsProject1, - initialDate: new Date('2024-03-25') + teams: [], + location: 'Campus Center Room 101', // In person + zoomLink: undefined, + shops: [], + machinery: [], + workPackages: [ + { + workPackageId: 'wp-2', + wbsElement: { + name: 'Bodywork', + carNumber: 0, + projectNumber: 1, + workPackageNumber: 0 + } + } + ], + documentIds: [], + questionDocument: 'https://docs.google.com/document/d/example-questions-2', + description: undefined, + status: EventStatus.CONFIRMED }; -export const exampleAllDesignReviews: DesignReview[] = [exampleDesignReview1, exampleDesignReview2]; +export const exampleAllDesignReviews: Event[] = [exampleDesignReviewEvent1, exampleDesignReviewEvent2]; diff --git a/src/frontend/src/tests/test-support/test-data/work-packages.stub.ts b/src/frontend/src/tests/test-support/test-data/work-packages.stub.ts index ba4334e634..25a104a2be 100644 --- a/src/frontend/src/tests/test-support/test-data/work-packages.stub.ts +++ b/src/frontend/src/tests/test-support/test-data/work-packages.stub.ts @@ -55,7 +55,7 @@ export const exampleResearchWorkPackage: WorkPackage = { stage: WorkPackageStage.Research, blocking: [], teamTypes: [], - designReviews: [] + events: [] }; export const exampleDesignWorkPackage: WorkPackage = { @@ -101,7 +101,7 @@ export const exampleDesignWorkPackage: WorkPackage = { stage: WorkPackageStage.Design, blocking: [], teamTypes: [], - designReviews: [] + events: [] }; export const exampleManufacturingWorkPackage: WorkPackage = { @@ -137,7 +137,7 @@ export const exampleManufacturingWorkPackage: WorkPackage = { stage: WorkPackageStage.Manufacturing, blocking: [], teamTypes: [], - designReviews: [] + events: [] }; export const exampleInstallWorkPackage: WorkPackage = { @@ -172,7 +172,7 @@ export const exampleInstallWorkPackage: WorkPackage = { stage: WorkPackageStage.Install, blocking: [], teamTypes: [], - designReviews: [], + events: [], deleted: false }; @@ -208,7 +208,7 @@ export const exampleWorkPackage5: WorkPackage = { projectName: 'project3', blocking: [], teamTypes: [], - designReviews: [] + events: [] }; export const exampleAllWorkPackages: WorkPackage[] = [ diff --git a/src/frontend/src/utils/design-review.utils.ts b/src/frontend/src/utils/design-review.utils.ts index 2367926673..189bc0a42a 100644 --- a/src/frontend/src/utils/design-review.utils.ts +++ b/src/frontend/src/utils/design-review.utils.ts @@ -1,4 +1,4 @@ -import { DesignReview, DesignReviewStatus } from 'shared'; +import { Event, EventStatus } from 'shared'; export const enumToArray = (en: { [key: number]: string | number }) => { return Object.keys(en).filter((value: string) => isNaN(Number(value)) === true); @@ -89,36 +89,34 @@ export const getWeekDateRange = (selectedDate: Date) => { return [startDate, endDate]; }; -export const isConfirmed = (designReview: DesignReview): boolean => { +export const isConfirmed = (event: Event): boolean => { return ( - designReview.status === DesignReviewStatus.CONFIRMED || - designReview.status === DesignReviewStatus.SCHEDULED || - designReview.status === DesignReviewStatus.DONE + event.status === EventStatus.CONFIRMED || event.status === EventStatus.SCHEDULED || event.status === EventStatus.DONE ); }; -export const designReviewStatusPipe = (status: DesignReviewStatus) => { +export const eventStatusPipe = (status: EventStatus) => { switch (status) { - case DesignReviewStatus.CONFIRMED: + case EventStatus.CONFIRMED: return 'Ready to Schedule'; - case DesignReviewStatus.UNCONFIRMED: + case EventStatus.UNCONFIRMED: return 'Unconfirmed'; - case DesignReviewStatus.SCHEDULED: + case EventStatus.SCHEDULED: return 'Scheduled'; - case DesignReviewStatus.DONE: + case EventStatus.DONE: return 'Completed'; } }; -export const designReviewStatusColor = (status: DesignReviewStatus) => { +export const eventStatusColor = (status: EventStatus) => { switch (status) { - case DesignReviewStatus.CONFIRMED: + case EventStatus.CONFIRMED: return 'orange'; - case DesignReviewStatus.UNCONFIRMED: + case EventStatus.UNCONFIRMED: return 'grey'; - case DesignReviewStatus.SCHEDULED: + case EventStatus.SCHEDULED: return '#ef4345'; - case DesignReviewStatus.DONE: + case EventStatus.DONE: return 'green'; } }; diff --git a/src/frontend/src/utils/enum-pipes.ts b/src/frontend/src/utils/enum-pipes.ts index 47b22dce70..57926da60c 100644 --- a/src/frontend/src/utils/enum-pipes.ts +++ b/src/frontend/src/utils/enum-pipes.ts @@ -3,14 +3,7 @@ * See the LICENSE file in the repository root folder for details. */ import { yellow, green, blue, purple, grey, orange } from '@mui/material/colors'; -import { - ChangeRequestStatus, - ChangeRequestType, - DesignReviewStatus, - TaskStatus, - WbsElementStatus, - WorkPackageStage -} from 'shared'; +import { ChangeRequestStatus, ChangeRequestType, EventStatus, TaskStatus, WbsElementStatus, WorkPackageStage } from 'shared'; // maps stage to the desired color export const WorkPackageStageColorPipe: (stage: WorkPackageStage | undefined) => string = (stage) => { @@ -89,15 +82,15 @@ export const WbsElementStatusTextPipe: (status: WbsElementStatus) => string = (s } }; -export const DesignReviewStatusTextPipe: (status: DesignReviewStatus) => string = (status) => { +export const DesignReviewEventStatusTextPipe: (status: EventStatus) => string = (status) => { switch (status) { - case DesignReviewStatus.UNCONFIRMED: + case EventStatus.UNCONFIRMED: return 'Unconfirmed'; - case DesignReviewStatus.CONFIRMED: + case EventStatus.CONFIRMED: return 'Confirmed'; - case DesignReviewStatus.DONE: + case EventStatus.DONE: return 'Done'; - case DesignReviewStatus.SCHEDULED: + case EventStatus.SCHEDULED: return 'Scheduled'; } }; diff --git a/src/frontend/src/utils/gantt.utils.tsx b/src/frontend/src/utils/gantt.utils.tsx index 2a8c06c499..7b3d5465a1 100644 --- a/src/frontend/src/utils/gantt.utils.tsx +++ b/src/frontend/src/utils/gantt.utils.tsx @@ -5,8 +5,8 @@ import { addWeeksToDate, - DesignReviewPreview, - DesignReviewStatus, + EventPreview, + EventStatus, isWorkPackage, ProjectGantt, RetrospectiveProjectPreview, @@ -158,12 +158,12 @@ export const getProjectEndDate = (project: ProjectGantt): Date => { }, wpEnd); }; -export const transformDesignReviewToGanttEvent = (designReview: DesignReviewPreview): GanttEvent => { +export const transformDesignReviewEventToGanttEvent = (event: EventPreview): GanttEvent => { return { - date: designReview.dateScheduled, - color: ganttDesignReviewStatusColorPipe(designReview.status), - onClick: () => window.open(`${routes.CALENDAR}/${designReview.designReviewId}`, '_blank'), - name: designReview.wbsName + date: event.dateScheduled, + color: ganttDesignReviewEventStatusColorPipe(event.status), + onClick: () => window.open(`${routes.CALENDAR}/${event.eventId}`, '_blank'), + name: event.wbsName }; }; @@ -448,7 +448,7 @@ export const transformWorkPackageToGanttTask = ( start: workPackage.startDate, end: workPackage.endDate, - events: workPackage.designReviews.map(transformDesignReviewToGanttEvent), + events: workPackage.events.map(transformDesignReviewEventToGanttEvent), blocking: getBlockingGanttTasks(workPackage, allWorkPackages, transformWorkPackageToGanttTask), children: [], overlays: [], @@ -582,8 +582,8 @@ export const sortWbs = (a: { wbsNum: WbsNumber }, b: { wbsNum: WbsNumber }) => { return aWbsNum.workPackageNumber - bWbsNum.workPackageNumber; }; -export const ganttDesignReviewStatusColorPipe = (status: DesignReviewStatus) => { - return status !== DesignReviewStatus.UNCONFIRMED ? '#712f99' : '#876e96'; +export const ganttDesignReviewEventStatusColorPipe = (status: EventStatus) => { + return status !== EventStatus.UNCONFIRMED ? '#712f99' : '#876e96'; }; // Maps task status to the desired color for Gantt Chart diff --git a/src/frontend/src/utils/pipes.ts b/src/frontend/src/utils/pipes.ts index cbeb0c87f7..f8f6a4960e 100644 --- a/src/frontend/src/utils/pipes.ts +++ b/src/frontend/src/utils/pipes.ts @@ -9,10 +9,11 @@ import { isProject, IndexCode, AccountCode, - DesignReview, WorkPackagePreview, WbsElementPreview, - UserPreview + UserPreview, + ScheduleSlot, + Event } from 'shared'; /** @@ -126,8 +127,18 @@ export const daysOrWeeksLeftOrLate = (daysLeft: number) => { return `${daysToDaysOrWeeksPipe(Math.abs(daysLeft))} ${daysLeft > 0 ? 'left' : 'late'}`; }; -export const designReviewNamePipe = (designReview: DesignReview) => { - return `${wbsPipe(designReview.wbsNum)} - ${designReview.wbsName}`; +export const eventNamePipe = (event: Event) => { + const [firstWorkPackage] = event.workPackages; + + if (firstWorkPackage) { + return `${wbsPipe({ + carNumber: firstWorkPackage.wbsElement.carNumber, + projectNumber: firstWorkPackage.wbsElement.projectNumber, + workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber + })} - ${firstWorkPackage.wbsElement.name}`; + } + + return event.title; }; export const dateRangePipe = (startDate: Date, endDate: Date) => { @@ -175,11 +186,16 @@ export const displayEnum = (enumString: string) => { return enumString; }; -export const meetingStartTimePipe = (times: number[], isEndTime = false) => { - if (isEndTime && times[0] % 12 === 0) return '10pm'; - const time = (times[0] % 12) + 10; +export const meetingStartTimePipeScheduleSlot = (scheduledTimes: ScheduleSlot[]): string => { + if (scheduledTimes.length === 0) return ''; + + const firstTime = scheduledTimes[0].startTime; + if (!firstTime) return ''; - return time === 12 ? time + 'pm' : time < 12 ? time + 'am' : time - 12 + 'pm'; + const date = new Date(firstTime); + const hour = date.getHours(); + const displayHour = hour % 12 || 12; + return displayHour + (hour < 12 ? 'am' : 'pm'); }; // takes in a Date and returns it as a string in the form mm/dd/yy diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 2ad0e92847..919e36c86a 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -334,6 +334,7 @@ const bomUnitById = (id: string) => `${bomGetAllUnits()}/${id}`; const bomDeleteUnit = (id: string) => `${bomUnitById(id)}/delete`; /************** Design Review Endpoints *******************************/ +/* const designReviews = () => `${API_URL}/design-reviews`; const designReviewsCreate = () => `${designReviews()}/create`; const designReviewsEdit = (designReviewId: string) => `${designReviews()}/${designReviewId}/edit`; @@ -341,6 +342,7 @@ const designReviewById = (id: string) => `${designReviews()}/${id}`; const designReviewDelete = (id: string) => `${designReviewById(id)}/delete`; const designReviewMarkUserConfirmed = (id: string) => `${designReviewById(id)}/confirm-schedule`; const designReviewSetStatus = (id: string) => `${designReviewById(id)}/set-status`; +*/ /******************* WBS Element Template Endpoints ********************/ @@ -438,12 +440,17 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; /**************** Calendar Endpoints ****************/ const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; +const calendarEvents = () => `${calendar()}/events`; const calendarCreateShop = () => `${calendar()}/shop/create`; const calendarMachinery = () => `${calendar()}/machinery`; const calendarCreateMachinery = () => `${calendar()}/machinery/create`; const calendarEditMachinery = (machineryId: string) => `${calendar()}/machinery/${machineryId}/edit`; const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; const calendarEditShop = (shopId: string) => `${calendar()}/shop/${shopId}/edit`; +const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id}/confirm-schedule`; +const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; +const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; +const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -661,7 +668,7 @@ export const apiUrls = { bomCreateUnit, bomUnitById, bomDeleteUnit, - + /* designReviews, designReviewsCreate, designReviewById, @@ -669,7 +676,7 @@ export const apiUrls = { designReviewMarkUserConfirmed, designReviewDelete, designReviewSetStatus, - +*/ workPackageTemplates, workPackageTemplatesById, workPackageTemplatesEdit, @@ -753,6 +760,11 @@ export const apiUrls = { calendarEditMachinery, calendarAddMachineryToShop, calendarEditShop, + calendarEventMarkUserConfirmed, + calendarGetSingleEvent, + calendarEvents, + calendarDeleteEvent, + calendarEventSetStatus, version }; diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index cd62124251..0b4e2c05dc 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -15,10 +15,18 @@ export interface TeamCalendarPreview { teamName: string; } +export interface TeamTypeCalendarPreview { + teamTypeId: string; + name: string; +} + export interface WorkPackageCalendarPreview { workPackageId: string; wbsElement: { name: string; + carNumber: number; + projectNumber: number; + workPackageNumber: number; }; } @@ -29,16 +37,6 @@ export enum EventStatus { DONE = 'DONE' } -export interface Calendar { - calendarId: string; - name: string; - description: string; - color: string; - userCreated: User; - dateCreated: Date; - eventTypes: EventType[]; -} - export enum DayOfWeek { MONDAY = 'MONDAY', TUESDAY = 'TUESDAY', @@ -49,6 +47,16 @@ export enum DayOfWeek { SUNDAY = 'SUNDAY' } +export interface Calendar { + calendarId: string; + name: string; + description: string; + color: string; + userCreated: User; + dateCreated: Date; + eventTypes: EventType[]; +} + export interface ScheduleSlot { scheduleSlotId: string; days: DayOfWeek[]; @@ -85,12 +93,11 @@ export interface EventType { name: string; userCreated: User; dateCreated: Date; - initialDateScheduled: boolean; - allDay: boolean; - recurring: boolean; + schedule: boolean; requiredMembers: boolean; optionalMembers: boolean; teams: boolean; + teamType: boolean; location: boolean; zoomLink: boolean; shop: boolean; @@ -129,7 +136,7 @@ export interface Event { eventId: string; title: string; approved: boolean; - userCreated: User; + userCreated: UserWithScheduleSettings; dateCreated: Date; eventTypeId: string; approvalRequiredFrom?: User; @@ -139,6 +146,7 @@ export interface Event { confirmedMembers: UserWithScheduleSettings[]; deniedMembers: User[]; teams: TeamCalendarPreview[]; + teamType?: TeamTypeCalendarPreview; location?: string; zoomLink?: string; shops: ShopPreview[]; @@ -149,3 +157,12 @@ export interface Event { description?: string; status: EventStatus; } + +export type EventPreview = { + eventId: string; + title: string; + dateScheduled: Date; + status: EventStatus; + userCreated: User; + wbsName: string; +}; diff --git a/src/shared/src/types/design-review-types.ts b/src/shared/src/types/design-review-types.ts index 3755f2bab2..a3301bb5c4 100644 --- a/src/shared/src/types/design-review-types.ts +++ b/src/shared/src/types/design-review-types.ts @@ -1,3 +1,4 @@ +/* import { WbsNumber } from './project-types'; import { User, UserWithScheduleSettings } from './user-types'; @@ -38,6 +39,7 @@ export enum DesignReviewStatus { SCHEDULED = 'SCHEDULED', DONE = 'DONE' } + */ export interface TeamType { teamTypeId: string; diff --git a/src/shared/src/types/project-types.ts b/src/shared/src/types/project-types.ts index a62ac41e1d..b01080b9b6 100644 --- a/src/shared/src/types/project-types.ts +++ b/src/shared/src/types/project-types.ts @@ -7,7 +7,7 @@ import { User, UserPreview } from './user-types'; import { ImplementedChange } from './change-request-types'; import { WorkPackageStage } from './work-package-types'; import { TeamPreview } from './team-types'; -import { DesignReviewPreview, Task, TeamType } from 'shared'; +import { EventPreview, Task, TeamType } from 'shared'; export interface WbsNumber { carNumber: number; @@ -104,7 +104,7 @@ export interface WorkPackage extends WbsElement { stage?: WorkPackageStage; teamTypes: TeamType[]; projectId: string; - designReviews: DesignReviewPreview[]; + events: EventPreview[]; } export interface WorkPackagePreview extends WbsElementPreview { diff --git a/src/shared/src/utils.ts b/src/shared/src/utils.ts index 98e0ef4eec..b2034a7475 100644 --- a/src/shared/src/utils.ts +++ b/src/shared/src/utils.ts @@ -25,10 +25,10 @@ export const isSubset = (elements: string[], suppliedArray: string[]): boolean = return elements.every((element) => suppliedArray.includes(element)); }; -export const meetingStartTimePipe = (times: number[]) => { - const time = (times[0] % 12) + 10; - - return time <= 12 ? time + 'am' : time - 12 + 'pm'; +export const meetingStartTimePipeNumbers = (hours: number[]) => { + const [hour] = hours; + const displayHour = hour % 12 || 12; // Convert 0 to 12 for midnight, 13-23 to 1-11 + return displayHour + (hour < 12 ? 'am' : 'pm'); }; export const MAX_FILE_SIZE = 25 * 1024 * 1024; // 25MB From a20b895e6b09a2ba75476f01019c817a099fac7e Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 23 Nov 2025 17:33:55 -0500 Subject: [PATCH 242/477] #3636 Changed event name to eventtype and updated calendar to function --- .../AdminToolsScheduleConfig.tsx | 8 +- .../CreateEventTypeModal.tsx} | 13 +- .../EditEventTypeModal.tsx} | 15 +- .../EventTypeFormModal.tsx} | 338 +++++++++++++----- 4 files changed, 274 insertions(+), 100 deletions(-) rename src/frontend/src/pages/AdminToolsPage/ScheduleConfig/{Event/CreateEventModal.tsx => EventType/CreateEventTypeModal.tsx} (65%) rename src/frontend/src/pages/AdminToolsPage/ScheduleConfig/{Event/EditEventModal.tsx => EventType/EditEventTypeModal.tsx} (78%) rename src/frontend/src/pages/AdminToolsPage/ScheduleConfig/{Event/EventFormModal.tsx => EventType/EventTypeFormModal.tsx} (67%) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 852847c0da..5957cc9def 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -23,8 +23,8 @@ import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; -import CreateEventModal from './Event/CreateEventModal'; -import EditEventModal from './Event/EditEventModal'; +import CreateEventTypeModal from './EventType/CreateEventTypeModal'; +import EditEventTypeModal from './EventType/EditEventTypeModal'; import { Shop, EventType, Calendar } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import NERDeleteModal from '../../../components/NERDeleteModal'; @@ -562,11 +562,11 @@ const AdminToolsScheduleConfig: React.FC = () => { /> {/* Create Event Type Modal */} - setOpenCreateEventType(false)} /> + setOpenCreateEventType(false)} /> {/* Edit Event Type Modal */} {editingEventType && ( - setEditingEventType(null)} eventType={editingEventType} /> + setEditingEventType(null)} eventType={editingEventType} /> )} ); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/CreateEventModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx similarity index 65% rename from src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/CreateEventModal.tsx rename to src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx index 69f671200a..23ae150e41 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/CreateEventModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx @@ -2,28 +2,29 @@ import ErrorPage from '../../../ErrorPage'; import LoadingIndicator from '../../../../components/LoadingIndicator'; import { useCreateEventType, EVENT_TYPE_KEY } from '../../../../hooks/calendar.hooks'; import { useQueryClient } from 'react-query'; -import EventFormModal, { EventFormValues } from './EventFormModal'; +import EventTypeFormModal, { EventTypeFormValues } from './EventTypeFormModal'; -interface CreateEventModalProps { +interface CreateEventTypeModalProps { open: boolean; onClose: () => void; } -const CreateEventModal = ({ open, onClose }: CreateEventModalProps) => { +const CreateEventTypeModal = ({ open, onClose }: CreateEventTypeModalProps) => { const { isLoading, isError, error, mutateAsync: createEventType } = useCreateEventType(); const queryClient = useQueryClient(); if (isError) return ; if (isLoading) return ; - const onSubmit = async (data: EventFormValues) => { + const onSubmit = async (data: EventTypeFormValues) => { const result = await createEventType(data); await queryClient.invalidateQueries(EVENT_TYPE_KEY); await queryClient.refetchQueries(EVENT_TYPE_KEY); return result; }; - return ; + return ; }; -export default CreateEventModal; +export default CreateEventTypeModal; + diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx similarity index 78% rename from src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx rename to src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx index dbc75d3374..8582162583 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EditEventModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx @@ -3,15 +3,15 @@ import LoadingIndicator from '../../../../components/LoadingIndicator'; import { useEditEventType, EVENT_TYPE_KEY } from '../../../../hooks/calendar.hooks'; import { useQueryClient } from 'react-query'; import { EventType } from 'shared'; -import EventFormModal, { EventFormValues } from './EventFormModal'; +import EventTypeFormModal, { EventTypeFormValues } from './EventTypeFormModal'; -interface EditEventModalProps { +interface EditEventTypeModalProps { open: boolean; onClose: () => void; eventType: EventType; } -const EditEventModal = ({ open, onClose, eventType }: EditEventModalProps) => { +const EditEventTypeModal = ({ open, onClose, eventType }: EditEventTypeModalProps) => { const queryClient = useQueryClient(); const { @@ -25,7 +25,7 @@ const EditEventModal = ({ open, onClose, eventType }: EditEventModalProps) => { const isError = isEditError; const error = editError; - const eventTypeData: EventFormValues = { + const eventTypeData: EventTypeFormValues = { name: eventType.name, calendarIds: eventType.calendarIds || [], initialDateScheduled: eventType.initialDateScheduled, @@ -49,14 +49,15 @@ const EditEventModal = ({ open, onClose, eventType }: EditEventModalProps) => { if (isError) return ; if (isLoading) return ; - const onSubmit = async (data: EventFormValues) => { + const onSubmit = async (data: EventTypeFormValues) => { const result = await editEventType(data); await queryClient.invalidateQueries(EVENT_TYPE_KEY); await queryClient.refetchQueries(EVENT_TYPE_KEY); return result; }; - return ; + return ; }; -export default EditEventModal; +export default EditEventTypeModal; + diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx similarity index 67% rename from src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx rename to src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx index 592428dbd1..14ec6e89fd 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/Event/EventFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx @@ -1,4 +1,4 @@ -import { Box, FormHelperText, Typography, Checkbox } from '@mui/material'; +import { Box, FormHelperText, Typography, Checkbox, FormControl, Select, MenuItem, Chip } from '@mui/material'; import NERFormModal from '../../../../components/NERFormModal'; import ReactHookTextField from '../../../../components/ReactHookTextField'; import { useToast } from '../../../../hooks/toasts.hooks'; @@ -9,6 +9,7 @@ import { useEffect, useMemo } from 'react'; import { EventType } from 'shared'; import useFormPersist from 'react-hook-form-persist'; import { FormStorageKey } from '../../../../utils/form'; +import { useAllCalendars } from '../../../../hooks/calendar.hooks'; import CalendarTodayIcon from '@mui/icons-material/CalendarToday'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import PeopleIcon from '@mui/icons-material/People'; @@ -18,8 +19,12 @@ import BuildIcon from '@mui/icons-material/Build'; import InventoryIcon from '@mui/icons-material/Inventory'; import DescriptionIcon from '@mui/icons-material/Description'; import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; +import GroupsIcon from '@mui/icons-material/Groups'; +import PersonAddIcon from '@mui/icons-material/PersonAdd'; +import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; +import SupervisorAccountIcon from '@mui/icons-material/SupervisorAccount'; -export interface EventFormValues { +export interface EventTypeFormValues { name: string; calendarIds: string[]; initialDateScheduled: boolean; @@ -40,7 +45,7 @@ export interface EventFormValues { requiresConfirmation: boolean; } -const createSchema = yup.object({ +const eventTypeSchema = yup.object({ name: yup.string().required('Event Type name is required'), calendarIds: yup.array().of(yup.string()).required(), initialDateScheduled: yup.boolean().required(), @@ -61,38 +66,18 @@ const createSchema = yup.object({ requiresConfirmation: yup.boolean().required() }); -const editSchema = yup.object({ - name: yup.string().required('Event Type name is required'), - calendarIds: yup.array().of(yup.string()).required(), - initialDateScheduled: yup.boolean().required(), - allDay: yup.boolean().required(), - recurring: yup.boolean().required(), - requiredMembers: yup.boolean().required(), - optionalMembers: yup.boolean().required(), - teams: yup.boolean().required(), - location: yup.boolean().required(), - zoomLink: yup.boolean().required(), - shop: yup.boolean().required(), - machinery: yup.boolean().required(), - workPackage: yup.boolean().required(), - questionDocument: yup.boolean().required(), - documents: yup.boolean().required(), - description: yup.boolean().required(), - onlyHeadsOrAbove: yup.boolean().required(), - requiresConfirmation: yup.boolean().required() -}); - -interface EventFormModalProps { +interface EventTypeFormModalProps { open: boolean; onClose: () => void; - onSubmit: (data: EventFormValues) => Promise; - initialValues?: EventFormValues; + onSubmit: (data: EventTypeFormValues) => Promise; + initialValues?: EventTypeFormValues; } -export const EventFormModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { +export const EventTypeFormModal: React.FC = ({ open, onClose, onSubmit, initialValues }) => { const toast = useToast(); + const { data: calendars } = useAllCalendars(); - const defaultValues: EventFormValues = useMemo( + const defaultValues: EventTypeFormValues = useMemo( () => ({ name: '', calendarIds: [], @@ -123,8 +108,8 @@ export const EventFormModal: React.FC = ({ open, onClose, o formState: { errors }, watch, setValue - } = useForm({ - resolver: yupResolver(initialValues ? editSchema : createSchema) as any, + } = useForm({ + resolver: yupResolver(eventTypeSchema) as any, defaultValues: initialValues || defaultValues }); @@ -141,7 +126,7 @@ export const EventFormModal: React.FC = ({ open, onClose, o } }, [initialValues, reset]); - const onFormSubmit = async (data: EventFormValues) => { + const onFormSubmit = async (data: EventTypeFormValues) => { try { await onSubmit(data); onClose(); @@ -167,11 +152,11 @@ export const EventFormModal: React.FC = ({ open, onClose, o reset(initialValues || defaultValues)} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} - formId={initialValues ? 'edit-event-form' : 'create-event-form'} + formId={initialValues ? 'edit-event-type-form' : 'create-event-type-form'} showCloseButton > @@ -183,7 +168,6 @@ export const EventFormModal: React.FC = ({ open, onClose, o mb: 1 }} > - <>} /> = ({ open, onClose, o {errors.name?.message} - {/* Calendar Display (visual only) */} + {/* Calendar Selection */} - - - Calendar - - - + + ( + + )} + /> + {errors.calendarIds?.message} + @@ -270,41 +305,99 @@ export const EventFormModal: React.FC = ({ open, onClose, o Monday, March 17 2:00pm - 3:00pm - ( + + )} /> All Day - - Recurring - + ( + onChange(!value)} + > + Recurring + + + )} + /> + + + + {/* Required Members Field */} + + ( + + )} + /> + + + + + + Required Member + + × + + + + Add Required Member + + - {/* Members Field */} + {/* Optional Members Field */} = ({ open, onClose, o + {/* Teams Field */} + + ( + + )} + /> + + + + Select Team + + + + + {/* Location Field */} = ({ open, onClose, o + {/* Question Document Field */} + + ( + + )} + /> + + + + Select Question Document + + + + + {/* Documents Field */} = ({ open, onClose, o + + {/* Only Heads Or Above Field */} + + ( + + )} + /> + + + + Only Heads Or Above + + + ); }; -export default EventFormModal; +export default EventTypeFormModal; From 63e44cd51eac118a90620535c0e317e104612958 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 23 Nov 2025 17:37:59 -0500 Subject: [PATCH 243/477] #3636 added more toggable fields --- .../EventType/EventTypeFormModal.tsx | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx index 14ec6e89fd..d907aa925f 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx @@ -325,26 +325,39 @@ export const EventTypeFormModal: React.FC = ({ open, on control={control} name="recurring" render={({ field: { onChange, value } }) => ( - onChange(e.target.value === 'recurring')} sx={{ minWidth: 100, height: 32, - backgroundColor: value ? 'rgba(255, 255, 255, 0.2)' : 'rgba(255, 255, 255, 0.1)', - border: value ? '1px solid rgba(255, 255, 255, 0.5)' : '1px solid rgba(255, 255, 255, 0.3)', + backgroundColor: 'rgba(255, 255, 255, 0.1)', + border: '1px solid rgba(255, 255, 255, 0.3)', borderRadius: '4px', - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - px: 1.5, - color: value ? 'white' : 'rgba(255, 255, 255, 0.7)', + color: 'rgba(255, 255, 255, 0.7)', fontSize: '14px', - cursor: 'pointer' + '& .MuiOutlinedInput-notchedOutline': { + border: 'none' + }, + '&:hover .MuiOutlinedInput-notchedOutline': { + border: 'none' + }, + '&.Mui-focused .MuiOutlinedInput-notchedOutline': { + border: 'none' + }, + '& .MuiSelect-icon': { + color: 'white' + }, + '& .MuiSelect-select': { + padding: '4px 14px', + display: 'flex', + alignItems: 'center' + } }} - onClick={() => onChange(!value)} > - Recurring - - + Not Recurring + Recurring + )} /> From d53a25f513c720da4b7f11ea0040b37a5437f323 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Sun, 23 Nov 2025 17:42:15 -0500 Subject: [PATCH 244/477] #3636 styling thing --- .../ScheduleConfig/EventType/CreateEventTypeModal.tsx | 1 - .../ScheduleConfig/EventType/EditEventTypeModal.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx index 23ae150e41..9be798f7a0 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx @@ -27,4 +27,3 @@ const CreateEventTypeModal = ({ open, onClose }: CreateEventTypeModalProps) => { }; export default CreateEventTypeModal; - diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx index 8582162583..5bb7fe629f 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx @@ -60,4 +60,3 @@ const EditEventTypeModal = ({ open, onClose, eventType }: EditEventTypeModalProp }; export default EditEventTypeModal; - From d91aaf7fce0ac6b47dbce33e5711c1c49af98632 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 23 Nov 2025 17:47:36 -0500 Subject: [PATCH 245/477] #3754 no migration errors on seed --- .../20251101233144_calendar/migration.sql | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index d81116c27e..4e3905eb8b 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -119,16 +119,9 @@ CREATE TABLE "public"."Event_Type" ( -- CreateEnum CREATE TYPE "public"."Event_Status" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'SCHEDULED', 'DONE'); --- AlterTable -ALTER TABLE "public"."Design_Review" DROP COLUMN "status", -ADD COLUMN "status" "public"."Event_Status" NOT NULL; - -- AlterTable ALTER TABLE "public"."Event" ADD COLUMN "status" "public"."Event_Status" NOT NULL; --- DropEnum -DROP TYPE "public"."Design_Review_Status"; - -- CreateTable CREATE TABLE "public"."_EventToSchedule_Slot" ( "A" TEXT NOT NULL, @@ -406,8 +399,8 @@ SELECT DISTINCT ON (org."organizationId") true, -- questionDocument (docTemplateLink) true, -- documents false, -- description - false, -- onlyHeadsOrAboveForEventCreation - false, -- requiresConfirmation + true, -- onlyHeadsOrAboveForEventCreation + true, -- requiresConfirmation org."organizationId" FROM "public"."Organization" org WHERE EXISTS ( @@ -506,7 +499,7 @@ SELECT CASE WHEN dr."docTemplateLink" IS NOT NULL THEN ARRAY[dr."docTemplateLink"] ELSE ARRAY[]::TEXT[] END, dr."docTemplateLink", -- questionDocument uses docTemplateLink NULL, -- description (not in Design_Review) - dr."status", + dr."status"::"text"::"public"."Event_Status", dr."teamTypeId" FROM "public"."Design_Review" dr JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId"; @@ -685,4 +678,7 @@ DROP TABLE IF EXISTS "public"."_userAttended" CASCADE; -- Drop the old Meeting and Design_Review tables DROP TABLE IF EXISTS "public"."Meeting" CASCADE; -DROP TABLE IF EXISTS "public"."Design_Review" CASCADE; \ No newline at end of file +DROP TABLE IF EXISTS "public"."Design_Review" CASCADE; + +-- DropEnum +DROP TYPE "public"."Design_Review_Status"; \ No newline at end of file From 4b2a2418a335b9978deed439c1e146c7ff750052 Mon Sep 17 00:00:00 2001 From: Saul M Date: Sun, 23 Nov 2025 23:39:29 -0500 Subject: [PATCH 246/477] #3375 Implemented use with the Calendar Table --- .../ScheduleConfig/AdminToolsScheduleConfig.tsx | 7 ++++++- src/frontend/src/utils/urls.ts | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 2e1d9ccc7c..9ed6644d59 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -195,7 +195,12 @@ const AdminToolsScheduleConfig: React.FC = () => { - + setCalendarToDelete(calendar)} + > diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 6318ff6229..8ce14aa24e 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -447,7 +447,7 @@ const calendarDeleteMachinery = (machineryId: string) => `${calendar()}/machiner const calendarAddMachineryToShop = (machineryId: string) => `${calendar()}/machinery/${machineryId}/add-to-shop`; const calendarEditShop = (shopId: string) => `${calendar()}/shop/${shopId}/edit`; const calendarDeleteShop = (shopId: string) => `${calendar()}/shop/${shopId}/delete`; -const calendarDeleteCalendar = (calendarId: string) => `${calendar()}/shop/${calendarId}/delete`; +const calendarDeleteCalendar = (calendarId: string) => `${calendar()}/${calendarId}/delete`; const calendarCreateCalendar = () => `${calendar()}/create`; const calendarEditCalendar = (calendarId: string) => `${calendar()}/${calendarId}/edit`; const calendarCalendars = () => `${calendar()}/calendars`; From 6b5d4e9b43d1ecd416b624b530965dd667a55c29 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 24 Nov 2025 00:06:42 -0500 Subject: [PATCH 247/477] changes --- .../src/pages/NewCalendarPage/FilterModal.tsx | 195 ++++++++++++++++++ .../pages/NewCalendarPage/NewCalendarPage.tsx | 31 +++ 2 files changed, 226 insertions(+) create mode 100644 src/frontend/src/pages/NewCalendarPage/FilterModal.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/FilterModal.tsx b/src/frontend/src/pages/NewCalendarPage/FilterModal.tsx new file mode 100644 index 0000000000..442f2bd8a2 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/FilterModal.tsx @@ -0,0 +1,195 @@ +import React, { useEffect, useState } from 'react'; +import { Autocomplete, Box, Button, Checkbox, FormControl, FormHelperText, TextField, Typography } from '@mui/material'; +import { Controller, useForm } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import type { Shop, User } from 'shared'; +import { useToast } from '../../hooks/toasts.hooks'; +import NERFormModal from '../../components/NERFormModal'; +import ReactHookTextField from '../../components/ReactHookTextField'; +import NERModal from '../../components/NERModal'; +import PeopleIcon from '@mui/icons-material/People'; +import { useAllUsers } from '../../hooks/users.hooks'; +import { width } from '@mui/system'; + +export interface FilterFormValues { + memberIds: string[]; + teamIds: string[]; + showInvited: boolean; + showTeam: boolean; +} + +export interface BaseFilterModalProps { + open: boolean; + onClose: () => void; + filterValues?: FilterFormValues; + setMemberIds: React.Dispatch>; + setTeamIds: React.Dispatch>; + setShowInvited: React.Dispatch>; + setShowTeam: React.Dispatch>; +} + +const FilterModal: React.FC = ({ + open, + onClose, + filterValues, + setMemberIds, + setTeamIds, + setShowInvited, + setShowTeam +}) => { + const [dropDownOpen, setDropDownOpen] = useState(false); + + const MemberDropdown = () => { + const memberIds = filterValues?.memberIds ?? []; + const { isLoading, isError, error, data: allUsers } = useAllUsers(); + + return ( + + {!dropDownOpen && + memberIds.map((id) => { + const user = allUsers?.find((user) => user.userId === id); + return ( + + + {user?.firstName ?? 'John'} {user?.lastName ?? 'Doe'} + + { + setMemberIds(memberIds.filter((mid) => mid !== id)); + }} + style={{ + cursor: 'pointer', + fontSize: '16px', + lineHeight: 1 + }} + > + × + + + ); + })} + {!dropDownOpen && ( + + )} + + {dropDownOpen && ( + { + if (reason !== 'toggleInput') { + setDropDownOpen(false); + } + }} + options={allUsers ?? []} + getOptionLabel={(option) => `${option.firstName} ${option.lastName}`} + value={allUsers?.filter((user) => memberIds.includes(user.userId)) ?? []} + onChange={(_, newValue) => setMemberIds(newValue.map((user) => user.userId))} + filterSelectedOptions + renderInput={(params) => ( + + )} + sx={{ + width: '100%', + '& .MuiAutocomplete-option': { + bgcolor: '#666', + color: 'white', + '&:hover': { + bgcolor: '#777' + } + } + }} + /> + )} + + ); + }; + + return ( + { + onClose(); + }} + title={'Filter Events'} + formId="shop-form" + showCloseButton + > + + + Attendees + + + + { + setShowInvited(e.target.checked); + }} + sx={{ color: 'white', '&.Mui-checked': { color: 'white' } }} + /> + + Show Events I Am Invited To + + + + + Team / Subteam + + + { + setShowTeam(e.target.checked); + }} + sx={{ color: 'white', '&.Mui-checked': { color: 'white' } }} + /> + + Show Events I For Teams I Am On + + + + ); +}; + +export default FilterModal; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 9bfa519691..a7d3f7bd0b 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -3,6 +3,8 @@ * See the LICENSE file in the repository root folder for details. */ import { useState } from 'react'; +import { ArrowDropDown } from '@mui/icons-material'; + import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { DesignReview } from 'shared'; @@ -16,6 +18,8 @@ import LoadingIndicator from '../../components/LoadingIndicator'; import DRCSummaryModal from '../CalendarPage/DesignReviewSummaryModal'; import { useAllTeamTypes } from '../../hooks/team-types.hooks'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; +import { NERButton } from '../../components/NERButton'; +import FilterModal from './FilterModal'; const NewCalendarPage = () => { const theme = useTheme(); @@ -31,6 +35,12 @@ const NewCalendarPage = () => { const [unconfirmedDesignReview, setUnconfirmedDesignReview] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); + const [openFilterModal, setOpenFilterModal] = useState(false); + const [memberIds, setMemberIds] = useState([]); + const [teamIds, setTeamIds] = useState([]); + const [showInvitedEvents, setShowInvitedEvents] = useState(true); + const [showTeamEvents, setShowTeamEvents] = useState(true); + if (isLoading || !allDesignReviews) return ; if (isError) return ; @@ -118,6 +128,18 @@ const NewCalendarPage = () => { > New Event + setOpenFilterModal(true)}> + More Filters + + {}}> + Show Invited Events: {String(showInvitedEvents)} + + {}}> + Show Team Events: {String(showTeamEvents)} + + {}}> + Track Members: {memberIds} + @@ -173,6 +195,15 @@ const NewCalendarPage = () => { + setOpenFilterModal(false)} + filterValues={{ memberIds, teamIds, showInvited: showInvitedEvents, showTeam: showTeamEvents }} + setMemberIds={setMemberIds} + setTeamIds={setTeamIds} + setShowInvited={setShowInvitedEvents} + setShowTeam={setShowTeamEvents} + /> ); From 6b35e2ceea07ce37d89746b9cfa54cf2f42d1ff5 Mon Sep 17 00:00:00 2001 From: Santiordon Date: Mon, 24 Nov 2025 16:49:04 -0500 Subject: [PATCH 248/477] #3706 Fix Merge Conflicts --- src/frontend/src/apis/calendar.api.ts | 5 +++-- src/frontend/src/hooks/calendar.hooks.ts | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 893c8ddc60..d2a5414295 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,8 +1,7 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; -import { Shop, Machinery, FilterArgs, Event } from 'shared'; import { filterEventsTransformer } from './transformers/calendar.transformer'; -import { Shop, Machinery, Calendar } from 'shared'; +import { Shop, Machinery, Calendar, FilterArgs, Event } from 'shared'; export const getAllCalendars = () => { return axios.get(apiUrls.calendarCalendars(), { @@ -41,6 +40,8 @@ export const postFilterEvents = (payload: FilterArgs) => { return axios.post(apiUrls.calendarFilterEvents(), payload, { transformResponse: (data) => filterEventsTransformer(JSON.parse(data) as Event[]) }); +}; + export const postDeleteShop = async (id: string) => { return axios.post(apiUrls.calendarDeleteShop(id)); }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index af97143b08..2e086dd803 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,6 +1,5 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop, Machinery, FilterArgs, Event } from 'shared'; -import { Shop, Machinery, Calendar } from 'shared'; +import { Shop, Machinery, Calendar, FilterArgs, Event } from 'shared'; import { getAllShops, postCreateShop, @@ -14,8 +13,9 @@ import { postFilterEvents } from '../apis/calendar.api'; -export const MACHINERY_KEY = ['machinery'] as const; export const FILTER_EVENTS_KEY = ['filter_events'] as const; + +import { getAllCalendars, postEditCalendar, postCreateCalendar From 29c44117a5a0c335a3cc94d89f16283f37365102 Mon Sep 17 00:00:00 2001 From: Santiordon Date: Mon, 24 Nov 2025 16:54:00 -0500 Subject: [PATCH 249/477] #3706 Prettier and Lint --- src/frontend/src/hooks/calendar.hooks.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 2e086dd803..7bd132c296 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -13,13 +13,9 @@ import { postFilterEvents } from '../apis/calendar.api'; -export const FILTER_EVENTS_KEY = ['filter_events'] as const; +import { getAllCalendars, postEditCalendar, postCreateCalendar } from '../apis/calendar.api'; -import { - getAllCalendars, - postEditCalendar, - postCreateCalendar -} from '../apis/calendar.api'; +export const FILTER_EVENTS_KEY = ['filter_events'] as const; export const MACHINERY_KEY = ['machinery'] as const; const SHOP_KEY = ['shops'] as const; From 8df78bb2d0b9d545426986c9c76337ba64d82e59 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 25 Nov 2025 21:52:31 -0500 Subject: [PATCH 250/477] space --- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index a7d3f7bd0b..6fe0fffdeb 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -36,6 +36,7 @@ const NewCalendarPage = () => { const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); + const [memberIds, setMemberIds] = useState([]); const [teamIds, setTeamIds] = useState([]); const [showInvitedEvents, setShowInvitedEvents] = useState(true); From 276379cf1a99d4bfbe5a8e1d3613a7a5eeabecb7 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Tue, 25 Nov 2025 23:17:59 -0500 Subject: [PATCH 251/477] #3636 minor change to allow only one calendar selection for types --- .../EventType/EventTypeFormModal.tsx | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx index d907aa925f..403ecbe541 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx @@ -1,4 +1,4 @@ -import { Box, FormHelperText, Typography, Checkbox, FormControl, Select, MenuItem, Chip } from '@mui/material'; +import { Box, FormHelperText, Typography, Checkbox, FormControl, Select, MenuItem } from '@mui/material'; import NERFormModal from '../../../../components/NERFormModal'; import ReactHookTextField from '../../../../components/ReactHookTextField'; import { useToast } from '../../../../hooks/toasts.hooks'; @@ -221,8 +221,8 @@ export const EventTypeFormModal: React.FC = ({ open, on control={control} render={({ field }) => ( { + if (!selected || selected.length === 0) { + return Select Calendars; + } + return ( + + {(selected as string[]).map((calendarId) => { + const calendar = calendars?.find((c) => c.calendarId === calendarId); + return ( + + ); + })} + + ); + }} + > + {calendars?.map((calendar) => ( + + + + {calendar.name} + + + ))} + + )} + /> + {errors.calendarIds?.message} + + + + + Select the fields from this template to be included in the new event type. + + + ( + + )} + /> + + + + Monday, March 17 2:00pm - 3:00pm + + + ( + + )} + /> + + All Day + + + ( + onChange(!value)} + > + Recurring + + + )} + /> + + + + {/* Required Members Field */} + + ( + + )} + /> + + + + + + Required Member + + × + + + + Add Required Member + + + + + + + {/* Optional Members Field */} + + ( + + )} + /> + + + + + + Ethan Herrell + + × + + {/* Add Member button (visual only) */} + + + Add Member + + + + + + + {/* Teams Field */} + + ( + + )} + /> + + + + Select Team + + + + + + {/* Location Field */} + + ( + + )} + /> + + + + Location + + + + + {/* Zoom Link Field */} + + ( + + )} + /> + + + + Zoom Link + + + + + {/* Availability Field */} + + ( + + )} + /> + + + + + + Add Availability + + + {/* View Availability button (visual only) */} + + + View Availability + + + + + + + {/* Shop Field */} + + ( + + )} + /> + + + + Select Shop + + + + + + {/* Machinery Field */} + + ( + + )} + /> + + + + Select Machinery + + + + + + {/* Work Package Field */} + + ( + + )} + /> + + + + Select Work Package + + + + + + {/* Question Document Field */} + + ( + + )} + /> + + + + Select Question Document + + + + + + {/* Documents Field */} + + ( + + )} + /> + + + + Documents + + + + + Competitions.pdf + + × + + + + Upload + + + + + + + {/* Description/Attachment Field */} + + ( + + )} + /> + + + + Add a description or attachment + + + + + {/* Only Heads Or Above Field */} + + ( + + )} + /> + + + + Only Heads Or Above + + + + + + ); +}; + +export default EventTypeFormModal; From c50afc2f7989ad1917d5acd9b602f5e8ebc31bd1 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 3 Dec 2025 13:15:42 -0500 Subject: [PATCH 271/477] #3636 added more toggable fields --- .../EventType/EventTypeFormModal.tsx | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx index 14ec6e89fd..d907aa925f 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx @@ -325,26 +325,39 @@ export const EventTypeFormModal: React.FC = ({ open, on control={control} name="recurring" render={({ field: { onChange, value } }) => ( - onChange(e.target.value === 'recurring')} sx={{ minWidth: 100, height: 32, - backgroundColor: value ? 'rgba(255, 255, 255, 0.2)' : 'rgba(255, 255, 255, 0.1)', - border: value ? '1px solid rgba(255, 255, 255, 0.5)' : '1px solid rgba(255, 255, 255, 0.3)', + backgroundColor: 'rgba(255, 255, 255, 0.1)', + border: '1px solid rgba(255, 255, 255, 0.3)', borderRadius: '4px', - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - px: 1.5, - color: value ? 'white' : 'rgba(255, 255, 255, 0.7)', + color: 'rgba(255, 255, 255, 0.7)', fontSize: '14px', - cursor: 'pointer' + '& .MuiOutlinedInput-notchedOutline': { + border: 'none' + }, + '&:hover .MuiOutlinedInput-notchedOutline': { + border: 'none' + }, + '&.Mui-focused .MuiOutlinedInput-notchedOutline': { + border: 'none' + }, + '& .MuiSelect-icon': { + color: 'white' + }, + '& .MuiSelect-select': { + padding: '4px 14px', + display: 'flex', + alignItems: 'center' + } }} - onClick={() => onChange(!value)} > - Recurring - - + Not Recurring + Recurring + )} /> From acbadc11259d67532bdb98cfca2d45760b3109e7 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 3 Dec 2025 13:15:45 -0500 Subject: [PATCH 272/477] #3636 styling thing --- .../ScheduleConfig/EventType/CreateEventTypeModal.tsx | 1 - .../ScheduleConfig/EventType/EditEventTypeModal.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx index 23ae150e41..9be798f7a0 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/CreateEventTypeModal.tsx @@ -27,4 +27,3 @@ const CreateEventTypeModal = ({ open, onClose }: CreateEventTypeModalProps) => { }; export default CreateEventTypeModal; - diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx index 8582162583..5bb7fe629f 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EditEventTypeModal.tsx @@ -60,4 +60,3 @@ const EditEventTypeModal = ({ open, onClose, eventType }: EditEventTypeModalProp }; export default EditEventTypeModal; - From 08618af8af6b9e4ba7b06febe0e76fe9a023a142 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 3 Dec 2025 13:15:49 -0500 Subject: [PATCH 273/477] #3636 minor change to allow only one calendar selection for types --- .../EventType/EventTypeFormModal.tsx | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx index d907aa925f..403ecbe541 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx @@ -1,4 +1,4 @@ -import { Box, FormHelperText, Typography, Checkbox, FormControl, Select, MenuItem, Chip } from '@mui/material'; +import { Box, FormHelperText, Typography, Checkbox, FormControl, Select, MenuItem } from '@mui/material'; import NERFormModal from '../../../../components/NERFormModal'; import ReactHookTextField from '../../../../components/ReactHookTextField'; import { useToast } from '../../../../hooks/toasts.hooks'; @@ -221,8 +221,8 @@ export const EventTypeFormModal: React.FC = ({ open, on control={control} render={({ field }) => ( field.onChange([e.target.value])} + {...field} + value={value && value.length > 0 ? value[0] : ''} + onChange={(e) => { + const selectedValue = e.target.value as string; + onChange(selectedValue ? [selectedValue] : []); + }} displayEmpty sx={{ backgroundColor: 'rgba(255, 255, 255, 0.1)', @@ -242,7 +240,7 @@ export const EventTypeFormModal: React.FC = ({ open, on } const calendar = calendars?.find((c) => c.calendarId === selected); return ( - + = ({ open, on Select the fields from this template to be included in the new event type. + + {/* Initial Date Scheduled Field - Always checked */} - ( - - )} - /> + Monday, March 17 2:00pm - 3:00pm - ( - - )} - /> + All Day - ( - - )} - /> + @@ -481,6 +457,37 @@ export const EventTypeFormModal: React.FC = ({ open, on + {/*Team Types Field */} + + ( + + )} + /> + + + + Select Team Type + + + + + {/* Location Field */} = ({ open, on - Only Heads Or Above + Only Heads Or Above Can Create Events + + + + + {/* Requires Confirmation Field */} + + ( + + )} + /> + + + + Requires Confirmation + + + + + {/* Send Slack Notifications Field */} + + ( + + )} + /> + + + + Send Slack Notifications diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 388c84c4fc..d100ff4347 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -94,9 +94,6 @@ export interface EventType { userCreated: User; dateCreated: Date; calendarIds: string[]; - initialDateScheduled: boolean; - allDay: boolean; - recurring: boolean; requiredMembers: boolean; optionalMembers: boolean; teams: boolean; @@ -117,9 +114,6 @@ export interface EventType { export interface EventTypeCreateArgs { name: string; calendarIds: string[]; - initialDateScheduled: boolean; - allDay: boolean; - recurring: boolean; requiredMembers: boolean; optionalMembers: boolean; teams: boolean; From 54dfeeac6152659bcef2de96940abbceff070178 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 6 Dec 2025 12:23:17 -0500 Subject: [PATCH 288/477] move file --- src/frontend/src/pages/CalendarPage/CalendarPage.tsx | 2 +- src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx | 2 +- .../CalendarComponents => NewCalendarPage}/CalendarDayCard.tsx | 2 +- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/frontend/src/pages/{CalendarPage/CalendarComponents => NewCalendarPage}/CalendarDayCard.tsx (99%) diff --git a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx index 00d398412b..9d473d4c63 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx @@ -7,7 +7,7 @@ import { Box, Grid, Stack, Tooltip, Typography, useMediaQuery, useTheme } from ' import PageLayout from '../../components/PageLayout'; import { Event, EventStatus } from 'shared'; import MonthSelector from '../CalendarPage/CalendarComponents/MonthSelector'; -import CalendarDayCard, { getTeamTypeIcon } from '../CalendarPage/CalendarComponents/CalendarDayCard'; +import CalendarDayCard, { getTeamTypeIcon } from '../NewCalendarPage/CalendarDayCard'; import { DAY_NAMES, enumToArray } from '../../utils/design-review.utils'; import ActionsMenu from '../../components/ActionsMenu'; import { useAllEvents } from '../../hooks/calendar.hooks'; diff --git a/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx index 426dc799ac..1453c1e674 100644 --- a/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx +++ b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx @@ -3,7 +3,7 @@ import NERModal from '../../components/NERModal'; import { Box, Chip, IconButton, Link, Typography } from '@mui/material'; import EditIcon from '@mui/icons-material/Edit'; import { useState } from 'react'; -import { getTeamTypeIcon } from './CalendarComponents/CalendarDayCard'; +import { getTeamTypeIcon } from '../NewCalendarPage/CalendarDayCard'; import { Link as RouterLink, useHistory } from 'react-router-dom'; import { routes } from '../../utils/routes'; import { useCurrentUser } from '../../hooks/users.hooks'; diff --git a/src/frontend/src/pages/CalendarPage/CalendarComponents/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx similarity index 99% rename from src/frontend/src/pages/CalendarPage/CalendarComponents/CalendarDayCard.tsx rename to src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index ca3e7f85a6..401b3e7928 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarComponents/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -5,7 +5,7 @@ import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices'; import TerminalIcon from '@mui/icons-material/Terminal'; import { useState } from 'react'; -import DRCSummaryModal from '../EventSummaryModal'; +import DRCSummaryModal from '../CalendarPage/EventSummaryModal'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import LocationOnIcon from '@mui/icons-material/LocationOn'; import GroupIcon from '@mui/icons-material/Group'; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 4dc4210dc3..21da29387b 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -6,7 +6,7 @@ import { useEffect, useState } from 'react'; import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { DayOfWeek, Event } from 'shared'; -import CalendarDayCard from '../CalendarPage/CalendarComponents/CalendarDayCard'; +import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; From 81d9d2ac357c98f60dd2caa6cbc2d04fbb6a54b1 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 6 Dec 2025 12:49:31 -0500 Subject: [PATCH 289/477] abstraction --- .../pages/NewCalendarPage/CalendarDayCard.tsx | 211 +++++++----------- .../NewCalendarPage/EventPartialInfoView.tsx | 74 ++++++ 2 files changed, 159 insertions(+), 126 deletions(-) create mode 100644 src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index 401b3e7928..41c8ea304b 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -17,6 +17,7 @@ import BusinessCenterIcon from '@mui/icons-material/BusinessCenter'; import DescriptionIcon from '@mui/icons-material/Description'; import ArticleIcon from '@mui/icons-material/Article'; import HelpIcon from '@mui/icons-material/Help'; +import EventPartialInfoView from './EventPartialInfoView'; export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { const teamIcons: Map = new Map([ @@ -38,6 +39,29 @@ export const getStatusIcon = (status: string, isLarge?: boolean) => { return statusIcons.get(status); }; +export const getConvertedStart = (event: Event, dayOfWeek: DayOfWeek) => { + const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); + const startTime = new Date( + specificSlot?.startTime ?? Date.now() - (specificSlot?.startTime?.getTimezoneOffset() ?? Date.now()) * -60000 + ); + + const convertedStartTime = startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); + + return convertedStartTime; +}; + +export const getConvertedEnd = (event: Event, dayOfWeek: DayOfWeek) => { + const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); + + const endTime = new Date( + specificSlot?.endTime ?? Date.now() - (specificSlot?.endTime?.getTimezoneOffset() ?? Date.now()) * -60000 + ); + + const convertedEndTime = endTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); + + return convertedEndTime; +}; + interface CalendarDayCardProps { cardDate: Date; events: Event[]; @@ -53,7 +77,7 @@ const CalendarDayCard: React.FC = ({ teamTypes, eventTypes = [], calendars = [], - dayOfWeek = '' + dayOfWeek = DayOfWeek.MONDAY }) => { const [, setIsCreateModalOpen] = useState(false); const theme = useTheme(); @@ -74,34 +98,11 @@ const CalendarDayCard: React.FC = ({ ); - const getConvertedStart = (event: Event) => { - const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); - const startTime = new Date( - specificSlot?.startTime ?? Date.now() - (specificSlot?.startTime?.getTimezoneOffset() ?? Date.now()) * -60000 - ); - - const convertedStartTime = startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); - - return convertedStartTime; - }; - - const getConvertedEnd = (event: Event) => { - const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); - - const endTime = new Date( - specificSlot?.endTime ?? Date.now() - (specificSlot?.endTime?.getTimezoneOffset() ?? Date.now()) * -60000 - ); - - const convertedEndTime = endTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); - - return convertedEndTime; - }; - const EventPopupInfo = ({ event, color }: { event: Event; color: string }) => { const name = event.workPackages[0]?.wbsElement?.name || event.title; - const convertedStartTime = getConvertedStart(event); - const convertedEndTime = getConvertedEnd(event); + const convertedStartTime = getConvertedStart(event, dayOfWeek); + const convertedEndTime = getConvertedEnd(event, dayOfWeek); return ( <> @@ -313,63 +314,6 @@ const CalendarDayCard: React.FC = ({ ); }; - const MoreInfoEventContent = ({ event, onClick }: { event: Event; onClick: () => void }) => { - const name = event.workPackages[0]?.wbsElement?.name || event.title; - const convertedStartTime = getConvertedStart(event); - const convertedEndTime = getConvertedEnd(event); - const specificEventType = eventTypes?.find((eventType) => eventType.eventTypeId === event.eventTypeId); - const specificCalendar = calendars?.find((calendar) => - calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) - ); - - return ( - { - e.stopPropagation(); - onClick(); - }} - sx={{ cursor: 'pointer', '&:hover': { opacity: 0.8 } }} - > - - - {getTeamTypeIcon(event.teamType?.name ?? '', false)} - - {name} - - - - - - {convertedStartTime} - {convertedEndTime} - - - - - - - - {event.location ?? 'N/A'} - - - - - - {event.requiredMembers[0] - ? `${event.requiredMembers[0].firstName} ${event.requiredMembers[0].lastName}...` - : 'N/A '} - - - - - ); - }; - const EventCard = ({ event }: { event: Event }) => { const [isSummaryModalOpen, setIsSummaryModalOpen] = useState(false); const [markedStatus, setMarkedStatus] = useState(event.status); @@ -442,14 +386,19 @@ const CalendarDayCard: React.FC = ({ > - {name} + {getTeamTypeIcon(event.teamType?.name ?? '')} {name}
@@ -492,53 +441,63 @@ const CalendarDayCard: React.FC = ({ zIndex: 2 }} > - + {extraEvents.map((event) => ( + handleEventClick(event)} + dayOfWeek={dayOfWeek ?? DayOfWeek.MONDAY} + calendars={calendars ?? []} + eventTypes={eventTypes ?? []} + /> + ))} + + } + slotProps={{ + popper: { + sx: { + zIndex: 1200 + } + }, + tooltip: { + sx: { + maxWidth: 'none', + borderRadius: 4, + p: 2, + bgcolor: theme.palette.grey[900], + boxShadow: '0 0 15px rgba(255, 255, 255, 1.0)' + } + }, + arrow: { + sx: { + color: theme.palette.grey[900], + fontSize: 16 + } + } }} > - - {extraEvents.map((event) => ( - handleEventClick(event)} /> - ))} - - } - slotProps={{ - popper: { - sx: { - zIndex: 1200 - } - }, - tooltip: { - sx: { - maxWidth: 'none', - borderRadius: 4, - p: 2, - bgcolor: theme.palette.grey[900], - boxShadow: '0 0 15px rgba(255, 255, 255, 1.0)' - } - }, - arrow: { - sx: { - color: theme.palette.grey[900], - fontSize: 16 - } - } + - + {'+' + extraEvents.length} - - + +
); diff --git a/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx b/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx new file mode 100644 index 0000000000..c90e4e3f99 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx @@ -0,0 +1,74 @@ +import AccessTimeIcon from '@mui/icons-material/AccessTime'; +import LocationOnIcon from '@mui/icons-material/LocationOn'; +import { Calendar, DayOfWeek, Event, EventType } from 'shared'; +import GroupIcon from '@mui/icons-material/Group'; +import { Stack } from '@mui/system'; +import { getConvertedEnd, getConvertedStart, getTeamTypeIcon } from './CalendarDayCard'; +import { Typography } from '@mui/material'; + +interface EventInfoProps { + event: Event; + eventTypes?: EventType[]; + calendars?: Calendar[]; + dayOfWeek: DayOfWeek; + onClick: () => void; +} + +const EventPartialInfoView: React.FC = ({ event, eventTypes, calendars, dayOfWeek, onClick }) => { + const name = event.workPackages[0]?.wbsElement?.name || event.title; + const convertedStartTime = getConvertedStart(event, dayOfWeek); + const convertedEndTime = getConvertedEnd(event, dayOfWeek); + const specificEventType = eventTypes?.find((eventType) => eventType.eventTypeId === event.eventTypeId); + const specificCalendar = calendars?.find((calendar) => + calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) + ); + + return ( + { + e.stopPropagation(); + onClick(); + }} + sx={{ cursor: 'pointer', '&:hover': { opacity: 0.8 } }} + > + + + {getTeamTypeIcon(event.teamType?.name ?? '', false)} + + {name} + + + + + + {convertedStartTime} - {convertedEndTime} + + + + + + + + {event.location ?? 'N/A'} + + + + + + {event.requiredMembers[0] + ? `${event.requiredMembers[0].firstName} ${event.requiredMembers[0].lastName}...` + : 'N/A '} + + + + + ); +}; + +export default EventPartialInfoView; From 68465c319bb944fc60a8531da3bcd42c8673aadc Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 6 Dec 2025 13:03:09 -0500 Subject: [PATCH 290/477] test failure? --- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 21da29387b..1ff5def1dd 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -48,6 +48,7 @@ const NewCalendarPage = () => { memberIds: memberIds.concat(additionalMemberIds), teamIds: teamIds.concat(additionalTeamIds) }); + const { data: allEventTypes } = useAllEventTypes(); const { data: allCalendars } = useAllCalendars(); const { data: allTeams } = useGetUsersTeams(); From 42603c3aae380cce32560c1253befe20889f0432 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 6 Dec 2025 18:48:03 -0500 Subject: [PATCH 291/477] requested fixes --- src/backend/src/routes/calendar.routes.ts | 2 +- src/frontend/src/apis/calendar.api.ts | 2 +- src/frontend/src/utils/urls.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 3450eb8968..df52ae3085 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -157,7 +157,7 @@ calendarRouter.get('/event/:eventId', CalendarController.getSingleEvent); calendarRouter.get('/events', CalendarController.getAllEvents); -calendarRouter.get('/eventTypes', CalendarController.getAllEventTypes); +calendarRouter.get('/event-types', CalendarController.getAllEventTypes); calendarRouter.post('/machinery/create', nonEmptyString(body('name')), validateInputs, CalendarController.createMachinery); diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 46ba3222e9..826be06be8 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -116,7 +116,7 @@ export const getAllEvents = () => { }; export const postFilterEvents = (payload: FilterArgs) => { - return axios.post(apiUrls.calendarFilterEvents(), payload, { + return axios.post(apiUrls.calendarFilterEvents(), payload, { transformResponse: (data) => JSON.parse(data).map(eventTransformer) }); }; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 46e53c2c22..a0b6f9b930 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -442,7 +442,7 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; const calendarEvents = () => `${calendar()}/events`; -const calendarEventTypes = () => `${calendar()}/eventTypes`; +const calendarEventTypes = () => `${calendar()}/event-types`; const calendarCreateShop = () => `${calendar()}/shop/create`; const calendarMachinery = () => `${calendar()}/machinery`; const calendarCreateMachinery = () => `${calendar()}/machinery/create`; From d0c57a0ad60ce9ba4e413c2611b74efe3ab53eef Mon Sep 17 00:00:00 2001 From: Richard Feng Date: Sat, 6 Dec 2025 19:55:33 -0500 Subject: [PATCH 292/477] #3774: delete button removes events --- .ebextensions/02_cloudwatch_agent 2.config | 63 +++++++++++ .github/workflows/deploy-prod 2.yml | 102 ++++++++++++++++++ src/backend/src/routes/calendar.routes.ts | 2 +- .../pages/CalendarPage/EventSummaryModal.tsx | 6 +- .../pages/NewCalendarPage/NewCalendarPage.tsx | 33 ------ src/frontend/src/utils/urls.ts | 2 +- 6 files changed, 170 insertions(+), 38 deletions(-) create mode 100644 .ebextensions/02_cloudwatch_agent 2.config create mode 100644 .github/workflows/deploy-prod 2.yml diff --git a/.ebextensions/02_cloudwatch_agent 2.config b/.ebextensions/02_cloudwatch_agent 2.config new file mode 100644 index 0000000000..14bc226e52 --- /dev/null +++ b/.ebextensions/02_cloudwatch_agent 2.config @@ -0,0 +1,63 @@ +files: + "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json": + mode: "000644" + owner: root + group: root + content: | + { + "agent": { + "metrics_collection_interval": 60, + "run_as_user": "root" + }, + "metrics": { + "namespace": "CWAgent", + "metrics_collected": { + "mem": { + "measurement": [ + { + "name": "mem_used_percent", + "rename": "MemoryUtilization", + "unit": "Percent" + } + ], + "metrics_collection_interval": 60 + }, + "disk": { + "measurement": [ + { + "name": "used_percent", + "rename": "DiskUtilization", + "unit": "Percent" + } + ], + "metrics_collection_interval": 60, + "resources": [ + "*" + ] + } + }, + "append_dimensions": { + "AutoScalingGroupName": "${aws:AutoScalingGroupName}", + "InstanceId": "${aws:InstanceId}" + } + } + } + +commands: + 01_install_cloudwatch_agent: + command: | + if ! command -v amazon-cloudwatch-agent-ctl &> /dev/null; then + wget -q https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm + rpm -U ./amazon-cloudwatch-agent.rpm + rm -f ./amazon-cloudwatch-agent.rpm + fi + test: "[ ! -f /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl ]" + + 02_stop_cloudwatch_agent: + command: | + /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \ + -a fetch-config \ + -m ec2 \ + -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \ + -s + ignoreErrors: true diff --git a/.github/workflows/deploy-prod 2.yml b/.github/workflows/deploy-prod 2.yml new file mode 100644 index 0000000000..ed899ee8be --- /dev/null +++ b/.github/workflows/deploy-prod 2.yml @@ -0,0 +1,102 @@ +name: Deploy to Production + +on: + push: + branches: + - multitenancy + +jobs: + deploy: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout source code + uses: actions/checkout@v3 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Set up Docker Buildx (for multi-platform builds) + uses: docker/setup-buildx-action@v2 + + - name: Build, tag, and push image to Amazon ECR + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: finishline-production + IMAGE_TAG: ${{ github.sha }} + run: | + echo "Building Docker image for AMD64 architecture..." + + # Build for AMD64 architecture (t3.small instances are AMD64) + docker buildx build \ + --platform linux/amd64 \ + --tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \ + --tag $ECR_REGISTRY/$ECR_REPOSITORY:latest \ + --push \ + . + + echo "✅ Image pushed successfully" + echo "Image: $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" + + - name: Update Dockerrun.aws.json + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: finishline-production + IMAGE_TAG: ${{ github.sha }} + run: | + # Create a deployment-specific Dockerrun.aws.json with the commit SHA + cat > Dockerrun.aws.json < = ({ const isScheduled = event.status === EventStatus.SCHEDULED || event.status === EventStatus.DONE; - const handleDelete = () => { + const handleDelete = async () => { try { - deleteEvent(); - history.push(routes.CALENDAR); + await deleteEvent(); + toast.success('Deleted Successfully'); } catch (e: unknown) { if (e instanceof Error) { toast.error(e.message, 3000); diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 32b7ee7990..f983a56c7b 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -11,7 +11,6 @@ import CalendarDayCard from '../CalendarPage/CalendarComponents/CalendarDayCard' import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; import { useAllEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; -import DeleteIcon from '@mui/icons-material/Delete'; import { datePipe } from '../../utils/pipes'; import { useToast } from '../../hooks/toasts.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; @@ -29,38 +28,10 @@ const NewCalendarPage = () => { error: allTeamTypesError } = useAllTeamTypes(); - const DeleteModal = () => { - return ( - setDeleteModal(false)} - title="Warning!" - cancelText="No" - submitText="Yes" - onSubmit={() => handleDelete} - > - Are you sure you want to delete this event? - - ); - }; - - const handleDelete = () => { - try { - // deleteEvent(); - // history.push(routes.CALENDAR); - } catch (e: unknown) { - if (e instanceof Error) { - toast.error(e.message, 3000); - } - } - setDeleteModal(false); - }; - const [displayMonthYear, setDisplayMonthYear] = useState(new Date()); const { isLoading, isError, error, data: allEvents } = useAllEvents(); const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); - const [showDeleteModal, setDeleteModal] = useState(false); const toast = useToast(); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); @@ -132,7 +103,6 @@ const NewCalendarPage = () => { /> )} - @@ -159,9 +129,6 @@ const NewCalendarPage = () => { > New Event - setDeleteModal(true)}> - - diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index ac4b745766..0dcd7c473c 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -456,7 +456,7 @@ const calendarEditCalendar = (calendarId: string) => `${calendar()}/${calendarId const calendarCalendars = () => `${calendar()}/calendars`; const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id}/confirm-schedule`; const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; -const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; +const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; /**************** Other Endpoints ****************/ From 7f4428a58a081ec30b5c2624aa2d2683c3ce48eb Mon Sep 17 00:00:00 2001 From: Richard Feng Date: Sat, 6 Dec 2025 20:09:24 -0500 Subject: [PATCH 293/477] #3774: delete button removes events --- src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx index 808b943d54..53e45168f1 100644 --- a/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx +++ b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx @@ -48,6 +48,7 @@ const EventSummaryModal: React.FC = ({ const handleDelete = async () => { try { await deleteEvent(); + setShowDeleteModal(false); toast.success('Deleted Successfully'); } catch (e: unknown) { if (e instanceof Error) { From 81035a21b3462761d5328deca431e2db4c852f38 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 7 Dec 2025 23:24:33 -0500 Subject: [PATCH 294/477] some requested changes --- src/backend/src/prisma/seed.ts | 29 ++++++++ .../pages/NewCalendarPage/CalendarDayCard.tsx | 15 ++-- .../pages/NewCalendarPage/NewCalendarPage.tsx | 69 ++++++++++++------- 3 files changed, 84 insertions(+), 29 deletions(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 05317d106d..46f2ff315a 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3290,6 +3290,35 @@ const performSeed: () => Promise = async () => { 'Test meeting' ); + await CalendarService.createEvent( + thomasEmrax, + 'Weekly Team Sync Late', + meetingEventType.eventTypeId, + ner, + [], + [], + [justiceLeague.teamId], + [], + [], + [], + [], + [ + { + days: [DayOfWeek.MONDAY], + startTime: new Date('2025-12-21T10:00:00.000Z'), + endTime: new Date('2025-12-21T11:00:00.000Z'), + recurrenceNumber: 2, + initialDateScheduled: new Date('2025-12-21T00:00:00.000Z'), + allDay: false + } + ], + mechanical.teamTypeId, + undefined, + 'Conference Room A', + 'https://zoom.us/j/123456789', + 'December Cheer' + ); + await CalendarService.createEvent( thomasEmrax, 'Weekly Team Sync 2', diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index 41c8ea304b..aa9b53035e 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -41,8 +41,11 @@ export const getStatusIcon = (status: string, isLarge?: boolean) => { export const getConvertedStart = (event: Event, dayOfWeek: DayOfWeek) => { const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); + const initialTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(Date.now()); const startTime = new Date( - specificSlot?.startTime ?? Date.now() - (specificSlot?.startTime?.getTimezoneOffset() ?? Date.now()) * -60000 + // getTimezoneOffset() is based on UTC (in minutes), and we need to inverse it and multiply by milliseconds to get the proper date + // for instance, if we were in UTC+3, it would return -180, which we need to invert and multiply to + initialTime.getTime() ); const convertedStartTime = startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); @@ -53,11 +56,13 @@ export const getConvertedStart = (event: Event, dayOfWeek: DayOfWeek) => { export const getConvertedEnd = (event: Event, dayOfWeek: DayOfWeek) => { const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); - const endTime = new Date( - specificSlot?.endTime ?? Date.now() - (specificSlot?.endTime?.getTimezoneOffset() ?? Date.now()) * -60000 - ); + const endTime = new Date(specificSlot?.endTime ?? Date.now()); - const convertedEndTime = endTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); + const convertedEndTime = endTime.toLocaleTimeString('en-US', { + hour: 'numeric', + minute: '2-digit', + timeZoneName: 'short' + }); return convertedEndTime; }; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 1ff5def1dd..1815f01eeb 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -49,9 +49,19 @@ const NewCalendarPage = () => { teamIds: teamIds.concat(additionalTeamIds) }); - const { data: allEventTypes } = useAllEventTypes(); - const { data: allCalendars } = useAllCalendars(); - const { data: allTeams } = useGetUsersTeams(); + const { + data: allEventTypes, + isLoading: allEventTypesLoading, + isError: allEventTypesIsError, + error: allEventTypesError + } = useAllEventTypes(); + const { + data: allCalendars, + isLoading: allCalendarsLoading, + isError: allCalendarsIsError, + error: allCalendarsError + } = useAllCalendars(); + const { data: allTeams, isLoading: allTeamsLoading, isError: allTeamsIsError, error: allTeamsError } = useGetUsersTeams(); const user = useCurrentUser(); const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); @@ -89,23 +99,24 @@ const NewCalendarPage = () => { }); const convertDayToInt = (day: DayOfWeek) => { - if (day === DayOfWeek.MONDAY) { - return 1; - } else if (day === DayOfWeek.TUESDAY) { - return 2; - } else if (day === DayOfWeek.WEDNESDAY) { - return 3; - } else if (day === DayOfWeek.THURSDAY) { - return 4; - } else if (day === DayOfWeek.FRIDAY) { - return 5; - } else if (day === DayOfWeek.SATURDAY) { - return 6; - } else if (day === DayOfWeek.SUNDAY) { - return 0; + switch (day) { + case DayOfWeek.MONDAY: + return 1; + case DayOfWeek.TUESDAY: + return 2; + case DayOfWeek.WEDNESDAY: + return 3; + case DayOfWeek.THURSDAY: + return 4; + case DayOfWeek.FRIDAY: + return 5; + case DayOfWeek.SATURDAY: + return 6; + case DayOfWeek.SUNDAY: + return 0; + default: + return -1; } - - return -1; }; const eventDict = new Map(); @@ -118,7 +129,9 @@ const NewCalendarPage = () => { // startTime is already a full timestamp, just use it directly const startTimeDate = new Date(slot.initialDateScheduled); - const convertedStartTime = new Date(startTimeDate.getTime() - startTimeDate.getTimezoneOffset() * -60000); + // Accessing the date actually converts it to local time, which causes the date to be off. This is a workaround. + // 60000 is for millisecond conversion + const convertedStartTime = new Date(startTimeDate.getTime() + startTimeDate.getTimezoneOffset() * 60000); const dayInt = convertedStartTime.getDay(); @@ -181,6 +194,15 @@ const NewCalendarPage = () => { if (!allTeamTypes || allTeamTypesLoading) return ; if (allTeamTypesIsError) return ; + if (!allEventTypes || allEventTypesLoading) return ; + if (allEventTypesIsError) return ; + + if (!allCalendars || allCalendarsLoading) return ; + if (allCalendarsIsError) return ; + + if (!allTeams || allTeamsLoading) return ; + if (allTeamsIsError) return ; + return ( <> {selectedEvent && ( @@ -253,16 +275,15 @@ const NewCalendarPage = () => { cardDate={cardDate} events={ eventDict.get( - datePipe(new Date(cardDate.getTime() - cardDate.getTimezoneOffset() * -60000)) + datePipe(new Date(cardDate.getTime() + cardDate.getTimezoneOffset() * 60000)) ) ?? [] } teamTypes={allTeamTypes} eventTypes={allEventTypes ?? []} calendars={allCalendars ?? []} dayOfWeek={ - dayDict.get( - datePipe(new Date(cardDate.getTime() - cardDate.getTimezoneOffset() * -60000)) - ) ?? DayOfWeek.SUNDAY + dayDict.get(datePipe(new Date(cardDate.getTime() + cardDate.getTimezoneOffset() * 60000))) ?? + DayOfWeek.SUNDAY } /> From d052fd8b58bc86f7891fd8106510758b30eccd83 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 7 Dec 2025 23:38:37 -0500 Subject: [PATCH 295/477] more updates (woohoo!) --- .../src/pages/NewCalendarPage/FilterModal.tsx | 8 ++-- .../pages/NewCalendarPage/NewCalendarPage.tsx | 39 ++++++++++++------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/FilterModal.tsx b/src/frontend/src/pages/NewCalendarPage/FilterModal.tsx index 8b7f3e6f99..95fb88500e 100644 --- a/src/frontend/src/pages/NewCalendarPage/FilterModal.tsx +++ b/src/frontend/src/pages/NewCalendarPage/FilterModal.tsx @@ -16,10 +16,10 @@ export interface BaseFilterModalProps { open: boolean; onClose: () => void; filterValues?: FilterArgs; - setMemberIds: React.Dispatch>; - setTeamIds: React.Dispatch>; - setShowInvited: React.Dispatch>; - setShowTeam: React.Dispatch>; + setMemberIds: (ids: string[]) => void; + setTeamIds: (ids: string[]) => void; + setShowInvited: (changed: boolean) => void; + setShowTeam: (changed: boolean) => void; } const FilterModal: React.FC = ({ diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 1815f01eeb..e971332cc9 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -31,12 +31,19 @@ const NewCalendarPage = () => { const [memberIds, setMemberIds] = useState([]); const [teamIds, setTeamIds] = useState([]); - const [additionalMemberIds, setAdditionalMemberIds] = useState([]); - const [additionalTeamIds, setAdditionalTeamIds] = useState([]); + const [showInvitedEvents, setShowInvitedEvents] = useState(true); const [showTeamEvents, setShowTeamEvents] = useState(true); const [displayMonthYear, setDisplayMonthYear] = useState(new Date()); + const { data: allTeams, isLoading: allTeamsLoading, isError: allTeamsIsError, error: allTeamsError } = useGetUsersTeams(); + + const teamList = allTeams?.map((team) => team.teamId) ?? []; + const user = useCurrentUser(); + + const [additionalMemberIds, setAdditionalMemberIds] = useState([user.userId]); + const [additionalTeamIds, setAdditionalTeamIds] = useState(teamList); + const { isLoading, isError, @@ -55,36 +62,38 @@ const NewCalendarPage = () => { isError: allEventTypesIsError, error: allEventTypesError } = useAllEventTypes(); + const { data: allCalendars, isLoading: allCalendarsLoading, isError: allCalendarsIsError, error: allCalendarsError } = useAllCalendars(); - const { data: allTeams, isLoading: allTeamsLoading, isError: allTeamsIsError, error: allTeamsError } = useGetUsersTeams(); - const user = useCurrentUser(); + const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); - useEffect(() => { - const teamList = allTeams?.map((team) => team.teamId) ?? []; + const updateAdditionalTeamIds = (changed: boolean) => { + setShowTeamEvents(changed); - if (showTeamEvents) { + if (changed) { setAdditionalTeamIds(teamList); } else { setAdditionalTeamIds([]); } - }, [allTeams, showTeamEvents]); + }; + + const updateAdditionalMemberIds = (changed: boolean) => { + setShowInvitedEvents(changed); - useEffect(() => { - if (showInvitedEvents) { + if (changed) { setAdditionalMemberIds([user.userId]); } else { setAdditionalMemberIds([]); } - }, [user.userId, showInvitedEvents]); + }; if (isLoading || !allEvents) return ; @@ -345,10 +354,10 @@ const NewCalendarPage = () => { open={openFilterModal} onClose={() => setOpenFilterModal(false)} filterValues={{ memberIds, teamIds, showInvited: showInvitedEvents, showTeam: showTeamEvents }} - setMemberIds={setMemberIds} - setTeamIds={setTeamIds} - setShowInvited={setShowInvitedEvents} - setShowTeam={setShowTeamEvents} + setMemberIds={(ids: string[]) => setMemberIds(ids)} + setTeamIds={(ids: string[]) => setTeamIds(ids)} + setShowInvited={(changed: boolean) => updateAdditionalMemberIds(changed)} + setShowTeam={(changed: boolean) => updateAdditionalTeamIds(changed)} /> From 270150dc36f9406d1335fa49de6a9d188a1ac7cc Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 7 Dec 2025 23:42:27 -0500 Subject: [PATCH 296/477] another round of requested changes --- .../pages/NewCalendarPage/CalendarDayCard.tsx | 29 +------------------ .../pages/NewCalendarPage/NewCalendarPage.tsx | 24 ++------------- src/frontend/src/utils/calendar.utils.ts | 22 ++++++++++++++ src/frontend/src/utils/datetime.utils.ts | 29 +++++++++++++++++++ 4 files changed, 54 insertions(+), 50 deletions(-) create mode 100644 src/frontend/src/utils/calendar.utils.ts diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index aa9b53035e..f81bb1acac 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -18,6 +18,7 @@ import DescriptionIcon from '@mui/icons-material/Description'; import ArticleIcon from '@mui/icons-material/Article'; import HelpIcon from '@mui/icons-material/Help'; import EventPartialInfoView from './EventPartialInfoView'; +import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { const teamIcons: Map = new Map([ @@ -39,34 +40,6 @@ export const getStatusIcon = (status: string, isLarge?: boolean) => { return statusIcons.get(status); }; -export const getConvertedStart = (event: Event, dayOfWeek: DayOfWeek) => { - const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); - const initialTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(Date.now()); - const startTime = new Date( - // getTimezoneOffset() is based on UTC (in minutes), and we need to inverse it and multiply by milliseconds to get the proper date - // for instance, if we were in UTC+3, it would return -180, which we need to invert and multiply to - initialTime.getTime() - ); - - const convertedStartTime = startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); - - return convertedStartTime; -}; - -export const getConvertedEnd = (event: Event, dayOfWeek: DayOfWeek) => { - const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); - - const endTime = new Date(specificSlot?.endTime ?? Date.now()); - - const convertedEndTime = endTime.toLocaleTimeString('en-US', { - hour: 'numeric', - minute: '2-digit', - timeZoneName: 'short' - }); - - return convertedEndTime; -}; - interface CalendarDayCardProps { cardDate: Date; events: Event[]; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index e971332cc9..55bd25492a 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -2,7 +2,7 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { DayOfWeek, Event } from 'shared'; @@ -19,6 +19,7 @@ import FilterModal from './FilterModal'; import { DateCalendar } from '@mui/x-date-pickers'; import { useCurrentUser } from '../../hooks/users.hooks'; import { useGetUsersTeams } from '../../hooks/teams.hooks'; +import { convertDayToInt } from '../../utils/calendar.utils'; const NewCalendarPage = () => { const theme = useTheme(); @@ -107,27 +108,6 @@ const NewCalendarPage = () => { return time1 - time2; }); - const convertDayToInt = (day: DayOfWeek) => { - switch (day) { - case DayOfWeek.MONDAY: - return 1; - case DayOfWeek.TUESDAY: - return 2; - case DayOfWeek.WEDNESDAY: - return 3; - case DayOfWeek.THURSDAY: - return 4; - case DayOfWeek.FRIDAY: - return 5; - case DayOfWeek.SATURDAY: - return 6; - case DayOfWeek.SUNDAY: - return 0; - default: - return -1; - } - }; - const eventDict = new Map(); const dayDict = new Map(); diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts new file mode 100644 index 0000000000..c94ded949c --- /dev/null +++ b/src/frontend/src/utils/calendar.utils.ts @@ -0,0 +1,22 @@ +import { DayOfWeek } from 'shared'; + +export const convertDayToInt = (day: DayOfWeek) => { + switch (day) { + case DayOfWeek.MONDAY: + return 1; + case DayOfWeek.TUESDAY: + return 2; + case DayOfWeek.WEDNESDAY: + return 3; + case DayOfWeek.THURSDAY: + return 4; + case DayOfWeek.FRIDAY: + return 5; + case DayOfWeek.SATURDAY: + return 6; + case DayOfWeek.SUNDAY: + return 0; + default: + return -1; + } +}; diff --git a/src/frontend/src/utils/datetime.utils.ts b/src/frontend/src/utils/datetime.utils.ts index ea7c37442b..588a5129e6 100644 --- a/src/frontend/src/utils/datetime.utils.ts +++ b/src/frontend/src/utils/datetime.utils.ts @@ -1,4 +1,5 @@ import dayjs from 'dayjs'; +import { DayOfWeek, Event } from 'shared'; /** * Returns monday of current week @@ -63,3 +64,31 @@ export const dateMonthDayYear = (date: Date): string => { export const isPastEvent = (startDate: Date, endDate: Date) => { return startDate < endDate; }; + +export const getConvertedStart = (event: Event, dayOfWeek: DayOfWeek) => { + const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); + const initialTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(Date.now()); + const startTime = new Date( + // getTimezoneOffset() is based on UTC (in minutes), and we need to inverse it and multiply by milliseconds to get the proper date + // for instance, if we were in UTC+3, it would return -180, which we need to invert and multiply to + initialTime.getTime() + ); + + const convertedStartTime = startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); + + return convertedStartTime; +}; + +export const getConvertedEnd = (event: Event, dayOfWeek: DayOfWeek) => { + const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); + + const endTime = new Date(specificSlot?.endTime ?? Date.now()); + + const convertedEndTime = endTime.toLocaleTimeString('en-US', { + hour: 'numeric', + minute: '2-digit', + timeZoneName: 'short' + }); + + return convertedEndTime; +}; From aa322751e1cba702419d2a607041b3545c21cdb9 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 7 Dec 2025 23:47:08 -0500 Subject: [PATCH 297/477] forgot about this error --- .../src/pages/NewCalendarPage/EventPartialInfoView.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx b/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx index c90e4e3f99..635d0d1350 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx @@ -3,8 +3,9 @@ import LocationOnIcon from '@mui/icons-material/LocationOn'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; import GroupIcon from '@mui/icons-material/Group'; import { Stack } from '@mui/system'; -import { getConvertedEnd, getConvertedStart, getTeamTypeIcon } from './CalendarDayCard'; +import { getTeamTypeIcon } from './CalendarDayCard'; import { Typography } from '@mui/material'; +import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; interface EventInfoProps { event: Event; From 555021e5304dbc26e5f2c7091dce0ec81a75c6f6 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 8 Dec 2025 20:09:31 -0500 Subject: [PATCH 298/477] Revert "File Combine" This reverts commit 5f4b08bdede0d1c8b152365790c2d89abb8bc7f6, reversing changes made to 61d0a8abf226396ab538c5ad429bfb426b915c3d. --- .dockerignore | 86 +--- .ebextensions/01_healthcheck.config | 16 - .ebextensions/02_cloudwatch_agent.config | 63 --- .ebignore | 108 ----- .github/workflows/deploy-prod.yml | 102 ----- .gitignore | 35 -- Dockerfile | 47 +-- docker-compose.yml | 53 --- docker-entrypoint.sh | 32 -- infrastructure/.gitignore | 5 - infrastructure/bootstrap/.terraform.lock.hcl | 25 -- infrastructure/bootstrap/main.tf | 176 -------- infrastructure/bootstrap/outputs.tf | 52 --- infrastructure/bootstrap/variables.tf | 25 -- .../production/.terraform.lock.hcl | 25 -- .../environments/production/main.tf | 270 ------------ .../environments/production/outputs.tf | 135 ------ .../production/terraform.tfvars.example | 47 --- .../environments/production/variables.tf | 289 ------------- .../modules/amplify-frontend/main.tf | 182 -------- .../modules/amplify-frontend/outputs.tf | 40 -- .../modules/amplify-frontend/variables.tf | 81 ---- infrastructure/modules/dns/main.tf | 111 ----- infrastructure/modules/dns/outputs.tf | 31 -- infrastructure/modules/dns/variables.tf | 31 -- infrastructure/modules/ecr/main.tf | 36 -- infrastructure/modules/ecr/outputs.tf | 14 - infrastructure/modules/ecr/variables.tf | 9 - .../modules/elasticbeanstalk/main.tf | 395 ------------------ .../modules/elasticbeanstalk/outputs.tf | 36 -- .../modules/elasticbeanstalk/variables.tf | 112 ----- infrastructure/modules/iam/main.tf | 184 -------- infrastructure/modules/iam/outputs.tf | 31 -- infrastructure/modules/iam/variables.tf | 22 - infrastructure/modules/monitoring/main.tf | 261 ------------ infrastructure/modules/monitoring/outputs.tf | 11 - .../modules/monitoring/variables.tf | 42 -- infrastructure/modules/network/main.tf | 240 ----------- infrastructure/modules/network/outputs.tf | 46 -- infrastructure/modules/network/variables.tf | 22 - infrastructure/modules/rds/main.tf | 156 ------- infrastructure/modules/rds/outputs.tf | 43 -- infrastructure/modules/rds/variables.tf | 110 ----- infrastructure/modules/secrets/main.tf | 201 --------- infrastructure/modules/secrets/outputs.tf | 151 ------- infrastructure/modules/secrets/variables.tf | 71 ---- infrastructure/scripts/ssh-to-eb.sh | 77 ---- infrastructure/scripts/tunnel-to-rds.sh | 98 ----- src/backend/index.ts | 28 +- src/backend/src/prisma/schema.prisma | 1 - .../ReimbursementProductTable.tsx | 20 +- .../ReimbursementRequestForm.tsx | 1 - .../BOM/MaterialForm/MaterialFormView.tsx | 2 +- 53 files changed, 25 insertions(+), 4462 deletions(-) delete mode 100644 .ebextensions/01_healthcheck.config delete mode 100644 .ebextensions/02_cloudwatch_agent.config delete mode 100644 .ebignore delete mode 100644 .github/workflows/deploy-prod.yml delete mode 100644 docker-compose.yml delete mode 100644 docker-entrypoint.sh delete mode 100644 infrastructure/.gitignore delete mode 100644 infrastructure/bootstrap/.terraform.lock.hcl delete mode 100644 infrastructure/bootstrap/main.tf delete mode 100644 infrastructure/bootstrap/outputs.tf delete mode 100644 infrastructure/bootstrap/variables.tf delete mode 100644 infrastructure/environments/production/.terraform.lock.hcl delete mode 100644 infrastructure/environments/production/main.tf delete mode 100644 infrastructure/environments/production/outputs.tf delete mode 100644 infrastructure/environments/production/terraform.tfvars.example delete mode 100644 infrastructure/environments/production/variables.tf delete mode 100644 infrastructure/modules/amplify-frontend/main.tf delete mode 100644 infrastructure/modules/amplify-frontend/outputs.tf delete mode 100644 infrastructure/modules/amplify-frontend/variables.tf delete mode 100644 infrastructure/modules/dns/main.tf delete mode 100644 infrastructure/modules/dns/outputs.tf delete mode 100644 infrastructure/modules/dns/variables.tf delete mode 100644 infrastructure/modules/ecr/main.tf delete mode 100644 infrastructure/modules/ecr/outputs.tf delete mode 100644 infrastructure/modules/ecr/variables.tf delete mode 100644 infrastructure/modules/elasticbeanstalk/main.tf delete mode 100644 infrastructure/modules/elasticbeanstalk/outputs.tf delete mode 100644 infrastructure/modules/elasticbeanstalk/variables.tf delete mode 100644 infrastructure/modules/iam/main.tf delete mode 100644 infrastructure/modules/iam/outputs.tf delete mode 100644 infrastructure/modules/iam/variables.tf delete mode 100644 infrastructure/modules/monitoring/main.tf delete mode 100644 infrastructure/modules/monitoring/outputs.tf delete mode 100644 infrastructure/modules/monitoring/variables.tf delete mode 100644 infrastructure/modules/network/main.tf delete mode 100644 infrastructure/modules/network/outputs.tf delete mode 100644 infrastructure/modules/network/variables.tf delete mode 100644 infrastructure/modules/rds/main.tf delete mode 100644 infrastructure/modules/rds/outputs.tf delete mode 100644 infrastructure/modules/rds/variables.tf delete mode 100644 infrastructure/modules/secrets/main.tf delete mode 100644 infrastructure/modules/secrets/outputs.tf delete mode 100644 infrastructure/modules/secrets/variables.tf delete mode 100755 infrastructure/scripts/ssh-to-eb.sh delete mode 100755 infrastructure/scripts/tunnel-to-rds.sh diff --git a/.dockerignore b/.dockerignore index d511ae1333..ad8a4db99b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,90 +1,6 @@ -# Dependencies **/node_modules -.yarn/ -.pnp.* - -# Build outputs **/dist -**/build - -# Tests **/tests **/*.test.ts -**/*.test.js -**/*.spec.ts -**/*.spec.js -system-tests/ -coverage/ -__tests__/ - -# AWS & Infrastructure -infrastructure/ -.elasticbeanstalk/ -.ebextensions/ -Dockerrun.aws.json -*.tf -*.tfvars -*.tfstate -*.tfstate.* -ECR_DEPLOYMENT.md -TERRAFORM_CHANGES.md - -# Git -.git/ -.gitignore -.gitattributes -.github/ - -# IDE -.vscode/ -.idea/ -*.swp -*.swo -*~ -.DS_Store - -# Documentation -README.md -*.md -LICENSE - -# Environment files -.env -.env.* -*.env - -# Logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Lock files (keep package.json though) -package-lock.json +.vscode yarn.lock -.yarnrc.yml - -# Prettier -.prettierrc* -.prettierignore - -# TypeScript config (keep for build) -# tsconfig.json - commented out, may need this - -# Docker files -.dockerignore -docker-compose*.yml -docker-compose*.yaml -Dockerfile.* - -# Temporary files -tmp/ -temp/ -*.tmp -*.bak -*.backup - -# Containerization helpers -containerization/ -devContainerization/ -scripts/ diff --git a/.ebextensions/01_healthcheck.config b/.ebextensions/01_healthcheck.config deleted file mode 100644 index 41319bc5a5..0000000000 --- a/.ebextensions/01_healthcheck.config +++ /dev/null @@ -1,16 +0,0 @@ -option_settings: - # Relax health check settings for debugging - aws:elasticbeanstalk:environment:process:default: - HealthCheckInterval: 30 - HealthCheckTimeout: 10 - HealthyThresholdCount: 2 - UnhealthyThresholdCount: 10 - - # Ignore health check failures during deployment - aws:elasticbeanstalk:command: - IgnoreHealthCheck: true - Timeout: 900 - - # Enhanced health reporting settings - aws:elasticbeanstalk:healthreporting:system: - HealthCheckSuccessThreshold: Ok diff --git a/.ebextensions/02_cloudwatch_agent.config b/.ebextensions/02_cloudwatch_agent.config deleted file mode 100644 index 14bc226e52..0000000000 --- a/.ebextensions/02_cloudwatch_agent.config +++ /dev/null @@ -1,63 +0,0 @@ -files: - "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json": - mode: "000644" - owner: root - group: root - content: | - { - "agent": { - "metrics_collection_interval": 60, - "run_as_user": "root" - }, - "metrics": { - "namespace": "CWAgent", - "metrics_collected": { - "mem": { - "measurement": [ - { - "name": "mem_used_percent", - "rename": "MemoryUtilization", - "unit": "Percent" - } - ], - "metrics_collection_interval": 60 - }, - "disk": { - "measurement": [ - { - "name": "used_percent", - "rename": "DiskUtilization", - "unit": "Percent" - } - ], - "metrics_collection_interval": 60, - "resources": [ - "*" - ] - } - }, - "append_dimensions": { - "AutoScalingGroupName": "${aws:AutoScalingGroupName}", - "InstanceId": "${aws:InstanceId}" - } - } - } - -commands: - 01_install_cloudwatch_agent: - command: | - if ! command -v amazon-cloudwatch-agent-ctl &> /dev/null; then - wget -q https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm - rpm -U ./amazon-cloudwatch-agent.rpm - rm -f ./amazon-cloudwatch-agent.rpm - fi - test: "[ ! -f /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl ]" - - 02_stop_cloudwatch_agent: - command: | - /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \ - -a fetch-config \ - -m ec2 \ - -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \ - -s - ignoreErrors: true diff --git a/.ebignore b/.ebignore deleted file mode 100644 index 8ffde698a6..0000000000 --- a/.ebignore +++ /dev/null @@ -1,108 +0,0 @@ -# Dockerfiles (use pre-built images from ECR) -Dockerfile -Dockerfile.* - -# Docker Compose -docker-compose*.yml -docker-compose*.yaml - -# Terraform -infrastructure/ -*.tf -*.tfvars -*.tfstate -*.tfstate.* - -# Containerization helpers -containerization/ -devContainerization/ - -# Git -.git/ -.gitignore -.gitattributes - -# Documentation -README.md -*.md -CHANGELOG.md -LICENSE -TERRAFORM_CHANGES.md -ECR_DEPLOYMENT.md - -# IDE and Editor -.vscode/ -.idea/ -*.swp -*.swo -*~ -.DS_Store - -# Node -node_modules/ -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.yarn/ -.pnp.* - -# Build artifacts -dist/ -build/ -*.log - -# Tests -__tests__/ -*.test.js -*.test.ts -*.spec.js -*.spec.ts -test/ -tests/ -system-tests/ -coverage/ - -# CI/CD -.github/ - -# Environment files (secrets should be in Terraform) -.env -.env.* -*.env - -# Elastic Beanstalk files that shouldn't be re-deployed -.elasticbeanstalk/* -!.elasticbeanstalk/*.cfg.yml -!.elasticbeanstalk/*.global.yml - -# Source code (we deploy pre-built containers) -src/ - -# Package manager files -package-lock.json -yarn.lock -.yarnrc.yml - -# TypeScript -tsconfig.json -tsconfig.*.json - -# Prettier -.prettierrc* -.prettierignore - -# Backup files -*.bak -*.backup -*.old - -# Temporary files -tmp/ -temp/ -*.tmp - -# Scripts -scripts/ - -# eb-deploy directory (if it exists) -eb-deploy/ diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml deleted file mode 100644 index ed899ee8be..0000000000 --- a/.github/workflows/deploy-prod.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: Deploy to Production - -on: - push: - branches: - - multitenancy - -jobs: - deploy: - runs-on: ubuntu-latest - timeout-minutes: 30 - - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-east-1 - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - - - name: Set up Docker Buildx (for multi-platform builds) - uses: docker/setup-buildx-action@v2 - - - name: Build, tag, and push image to Amazon ECR - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: finishline-production - IMAGE_TAG: ${{ github.sha }} - run: | - echo "Building Docker image for AMD64 architecture..." - - # Build for AMD64 architecture (t3.small instances are AMD64) - docker buildx build \ - --platform linux/amd64 \ - --tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \ - --tag $ECR_REGISTRY/$ECR_REPOSITORY:latest \ - --push \ - . - - echo "✅ Image pushed successfully" - echo "Image: $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" - - - name: Update Dockerrun.aws.json - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: finishline-production - IMAGE_TAG: ${{ github.sha }} - run: | - # Create a deployment-specific Dockerrun.aws.json with the commit SHA - cat > Dockerrun.aws.json < { - name = dvo.resource_record_name - record = dvo.resource_record_value - type = dvo.resource_record_type - } - } - - allow_overwrite = true - name = each.value.name - records = [each.value.record] - ttl = 60 - type = each.value.type - zone_id = data.aws_route53_zone.main.zone_id -} - -# Wait for certificate validation to complete -resource "aws_acm_certificate_validation" "frontend" { - certificate_arn = aws_acm_certificate.frontend.arn - validation_record_fqdns = [for record in aws_route53_record.frontend_cert_validation : record.fqdn] -} - -############# -# ACM Certificate for Backend (Elastic Beanstalk) -############# -resource "aws_acm_certificate" "backend" { - domain_name = var.backend_domain - validation_method = "DNS" - - lifecycle { - create_before_destroy = true - } - - tags = { - Name = "${var.project_name}-${var.environment}-backend-cert" - Environment = var.environment - Project = var.project_name - Purpose = "Elastic Beanstalk Backend" - } -} - -# DNS validation records for backend certificate -resource "aws_route53_record" "backend_cert_validation" { - for_each = { - for dvo in aws_acm_certificate.backend.domain_validation_options : dvo.domain_name => { - name = dvo.resource_record_name - record = dvo.resource_record_value - type = dvo.resource_record_type - } - } - - allow_overwrite = true - name = each.value.name - records = [each.value.record] - ttl = 60 - type = each.value.type - zone_id = data.aws_route53_zone.main.zone_id -} - -# Wait for certificate validation to complete -resource "aws_acm_certificate_validation" "backend" { - certificate_arn = aws_acm_certificate.backend.arn - validation_record_fqdns = [for record in aws_route53_record.backend_cert_validation : record.fqdn] -} - -############# -# Route53 Record - Backend (Points to Elastic Beanstalk) -############# -resource "aws_route53_record" "backend" { - zone_id = data.aws_route53_zone.main.zone_id - name = var.backend_domain - type = "CNAME" - ttl = 300 - records = [var.backend_cname] -} - -############# -# Route53 Record - Frontend (Managed by Amplify) -############# -# Note: Amplify automatically manages DNS records when you configure -# a custom domain. We don't create Route53 records manually for Amplify. -# Instead, Amplify will provide you with DNS records to verify domain ownership. diff --git a/infrastructure/modules/dns/outputs.tf b/infrastructure/modules/dns/outputs.tf deleted file mode 100644 index 815f66e007..0000000000 --- a/infrastructure/modules/dns/outputs.tf +++ /dev/null @@ -1,31 +0,0 @@ -# DNS Module Outputs - -output "hosted_zone_id" { - description = "Route53 hosted zone ID" - value = data.aws_route53_zone.main.zone_id -} - -output "frontend_certificate_arn" { - description = "ARN of ACM certificate for frontend" - value = aws_acm_certificate.frontend.arn -} - -output "backend_certificate_arn" { - description = "ARN of ACM certificate for backend" - value = aws_acm_certificate.backend.arn -} - -output "frontend_domain" { - description = "Frontend domain name" - value = var.frontend_domain -} - -output "backend_domain" { - description = "Backend domain name" - value = var.backend_domain -} - -output "backend_url" { - description = "Full backend URL with HTTPS" - value = "https://${var.backend_domain}" -} diff --git a/infrastructure/modules/dns/variables.tf b/infrastructure/modules/dns/variables.tf deleted file mode 100644 index 10bdfd30cc..0000000000 --- a/infrastructure/modules/dns/variables.tf +++ /dev/null @@ -1,31 +0,0 @@ -# DNS Module Variables - -variable "project_name" { - description = "Name of the project" - type = string -} - -variable "environment" { - description = "Environment name" - type = string -} - -variable "hosted_zone_name" { - description = "Name of the Route53 hosted zone (e.g., finishlinebyner.com)" - type = string -} - -variable "frontend_domain" { - description = "Frontend domain name (e.g., finishlinebyner.com)" - type = string -} - -variable "backend_domain" { - description = "Backend domain name (e.g., api-finishlinebyner.com)" - type = string -} - -variable "backend_cname" { - description = "Elastic Beanstalk CNAME to point backend domain to" - type = string -} diff --git a/infrastructure/modules/ecr/main.tf b/infrastructure/modules/ecr/main.tf deleted file mode 100644 index b16d7e62d6..0000000000 --- a/infrastructure/modules/ecr/main.tf +++ /dev/null @@ -1,36 +0,0 @@ -# ECR Module - Container Registry - -resource "aws_ecr_repository" "main" { - name = "${var.project_name}-${var.environment}" - image_tag_mutability = "MUTABLE" - - image_scanning_configuration { - scan_on_push = true - } - - tags = { - Name = "${var.project_name}-${var.environment}" - Environment = var.environment - Project = var.project_name - } -} - -# Lifecycle policy to keep only recent images -resource "aws_ecr_lifecycle_policy" "main" { - repository = aws_ecr_repository.main.name - - policy = jsonencode({ - rules = [{ - rulePriority = 1 - description = "Keep last 10 images" - selection = { - tagStatus = "any" - countType = "imageCountMoreThan" - countNumber = 10 - } - action = { - type = "expire" - } - }] - }) -} diff --git a/infrastructure/modules/ecr/outputs.tf b/infrastructure/modules/ecr/outputs.tf deleted file mode 100644 index e649139124..0000000000 --- a/infrastructure/modules/ecr/outputs.tf +++ /dev/null @@ -1,14 +0,0 @@ -output "repository_url" { - description = "URL of the ECR repository" - value = aws_ecr_repository.main.repository_url -} - -output "repository_name" { - description = "Name of the ECR repository" - value = aws_ecr_repository.main.name -} - -output "repository_arn" { - description = "ARN of the ECR repository" - value = aws_ecr_repository.main.arn -} diff --git a/infrastructure/modules/ecr/variables.tf b/infrastructure/modules/ecr/variables.tf deleted file mode 100644 index 3e784ffd9a..0000000000 --- a/infrastructure/modules/ecr/variables.tf +++ /dev/null @@ -1,9 +0,0 @@ -variable "project_name" { - description = "Name of the project" - type = string -} - -variable "environment" { - description = "Environment name" - type = string -} diff --git a/infrastructure/modules/elasticbeanstalk/main.tf b/infrastructure/modules/elasticbeanstalk/main.tf deleted file mode 100644 index de90607115..0000000000 --- a/infrastructure/modules/elasticbeanstalk/main.tf +++ /dev/null @@ -1,395 +0,0 @@ -# Elastic Beanstalk Module - -############# -# Elastic Beanstalk Application -############# -resource "aws_elastic_beanstalk_application" "main" { - name = "${var.project_name}-${var.environment}" - description = "FinishLine application for ${var.environment}" - - appversion_lifecycle { - service_role = var.eb_service_role_arn - max_count = 10 - delete_source_from_s3 = true - } - - tags = { - Name = "${var.project_name}-${var.environment}" - Environment = var.environment - Project = var.project_name - } -} - -############# -# Elastic Beanstalk Environment -############# -resource "aws_elastic_beanstalk_environment" "main" { - name = "${var.project_name}-${var.environment}-env" - application = aws_elastic_beanstalk_application.main.name - solution_stack_name = var.solution_stack_name - tier = "WebServer" - - ##################### - # VPC Configuration - ##################### - setting { - namespace = "aws:ec2:vpc" - name = "VPCId" - value = var.vpc_id - } - - setting { - namespace = "aws:ec2:vpc" - name = "Subnets" - value = join(",", var.subnet_ids) - } - - setting { - namespace = "aws:ec2:vpc" - name = "ELBSubnets" - value = join(",", var.elb_subnet_ids) - } - - setting { - namespace = "aws:ec2:vpc" - name = "AssociatePublicIpAddress" - value = "true" - } - - ##################### - # Instance Configuration - ##################### - setting { - namespace = "aws:autoscaling:launchconfiguration" - name = "InstanceType" - value = var.instance_type - } - - setting { - namespace = "aws:autoscaling:launchconfiguration" - name = "IamInstanceProfile" - value = var.instance_profile_name - } - - setting { - namespace = "aws:autoscaling:launchconfiguration" - name = "SecurityGroups" - value = var.instance_security_group_id - } - - ##################### - # Auto Scaling Configuration - ##################### - setting { - namespace = "aws:autoscaling:asg" - name = "MinSize" - value = var.min_instance_count - } - - setting { - namespace = "aws:autoscaling:asg" - name = "MaxSize" - value = var.max_instance_count - } - - setting { - namespace = "aws:autoscaling:trigger" - name = "MeasureName" - value = "CPUUtilization" - } - - setting { - namespace = "aws:autoscaling:trigger" - name = "Statistic" - value = "Average" - } - - setting { - namespace = "aws:autoscaling:trigger" - name = "Unit" - value = "Percent" - } - - setting { - namespace = "aws:autoscaling:trigger" - name = "UpperThreshold" - value = "70" - } - - setting { - namespace = "aws:autoscaling:trigger" - name = "LowerThreshold" - value = "20" - } - - ##################### - # Load Balancer Configuration - ##################### - setting { - namespace = "aws:elasticbeanstalk:environment" - name = "LoadBalancerType" - value = "application" - } - - setting { - namespace = "aws:elbv2:loadbalancer" - name = "SecurityGroups" - value = var.alb_security_group_id - } - - setting { - namespace = "aws:elbv2:loadbalancer" - name = "ManagedSecurityGroup" - value = var.alb_security_group_id - } - - # HTTP Listener (default) - setting { - namespace = "aws:elbv2:listener:default" - name = "ListenerEnabled" - value = "true" - } - - setting { - namespace = "aws:elbv2:listener:default" - name = "Protocol" - value = "HTTP" - } - - # HTTPS Listener (Port 443) - Enabled when enable_https is true - dynamic "setting" { - for_each = var.enable_https ? [1] : [] - content { - namespace = "aws:elbv2:listener:443" - name = "ListenerEnabled" - value = "true" - } - } - - dynamic "setting" { - for_each = var.enable_https ? [1] : [] - content { - namespace = "aws:elbv2:listener:443" - name = "Protocol" - value = "HTTPS" - } - } - - # Only set custom certificate if one is provided, otherwise EB uses default cert - dynamic "setting" { - for_each = var.enable_https && var.ssl_certificate_arn != "" ? [1] : [] - content { - namespace = "aws:elbv2:listener:443" - name = "SSLCertificateArns" - value = var.ssl_certificate_arn - } - } - - dynamic "setting" { - for_each = var.enable_https ? [1] : [] - content { - namespace = "aws:elbv2:listener:443" - name = "SSLPolicy" - value = "ELBSecurityPolicy-TLS13-1-2-2021-06" - } - } - - # Health check configuration - setting { - namespace = "aws:elasticbeanstalk:environment:process:default" - name = "HealthCheckPath" - value = var.health_check_path - } - - setting { - namespace = "aws:elasticbeanstalk:environment:process:default" - name = "Port" - value = "80" - } - - setting { - namespace = "aws:elasticbeanstalk:environment:process:default" - name = "Protocol" - value = "HTTP" - } - - setting { - namespace = "aws:elasticbeanstalk:environment:process:default" - name = "HealthCheckInterval" - value = "15" - } - - setting { - namespace = "aws:elasticbeanstalk:environment:process:default" - name = "HealthCheckTimeout" - value = "5" - } - - setting { - namespace = "aws:elasticbeanstalk:environment:process:default" - name = "HealthyThresholdCount" - value = "3" - } - - setting { - namespace = "aws:elasticbeanstalk:environment:process:default" - name = "UnhealthyThresholdCount" - value = "5" - } - - ##################### - # Deployment Configuration - ##################### - setting { - namespace = "aws:elasticbeanstalk:command" - name = "DeploymentPolicy" - value = var.deployment_policy - } - - setting { - namespace = "aws:elasticbeanstalk:command" - name = "BatchSizeType" - value = "Percentage" - } - - setting { - namespace = "aws:elasticbeanstalk:command" - name = "BatchSize" - value = "50" - } - - setting { - namespace = "aws:elasticbeanstalk:command" - name = "Timeout" - value = "600" - } - - ##################### - # Enhanced Health Reporting - ##################### - setting { - namespace = "aws:elasticbeanstalk:healthreporting:system" - name = "SystemType" - value = "enhanced" - } - - setting { - namespace = "aws:elasticbeanstalk:healthreporting:system" - name = "EnhancedHealthAuthEnabled" - value = "true" - } - - ##################### - # CloudWatch Logs - ##################### - setting { - namespace = "aws:elasticbeanstalk:cloudwatch:logs" - name = "StreamLogs" - value = "true" - } - - setting { - namespace = "aws:elasticbeanstalk:cloudwatch:logs" - name = "DeleteOnTerminate" - value = var.environment == "production" ? "false" : "true" - } - - setting { - namespace = "aws:elasticbeanstalk:cloudwatch:logs" - name = "RetentionInDays" - value = var.log_retention_days - } - - setting { - namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" - name = "HealthStreamingEnabled" - value = "true" - } - - setting { - namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" - name = "DeleteOnTerminate" - value = var.environment == "production" ? "false" : "true" - } - - setting { - namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" - name = "RetentionInDays" - value = var.log_retention_days - } - - ##################### - # Managed Updates - ##################### - setting { - namespace = "aws:elasticbeanstalk:managedactions" - name = "ManagedActionsEnabled" - value = "true" - } - - setting { - namespace = "aws:elasticbeanstalk:managedactions" - name = "PreferredStartTime" - value = "Sun:03:00" - } - - setting { - namespace = "aws:elasticbeanstalk:managedactions:platformupdate" - name = "UpdateLevel" - value = "minor" - } - - ##################### - # Service Role - ##################### - setting { - namespace = "aws:elasticbeanstalk:environment" - name = "ServiceRole" - value = var.eb_service_role_name - } - - ##################### - # Environment Variables - ##################### - setting { - namespace = "aws:elasticbeanstalk:application:environment" - name = "NODE_ENV" - value = var.environment == "production" ? "production" : "development" - } - - setting { - namespace = "aws:elasticbeanstalk:application:environment" - name = "PORT" - value = "3001" - } - - # Database URL will be set via environment variable - dynamic "setting" { - for_each = var.environment_variables - content { - namespace = "aws:elasticbeanstalk:application:environment" - name = setting.key - value = setting.value - } - } - - ##################### - # Docker Configuration - ##################### - setting { - namespace = "aws:elasticbeanstalk:environment:proxy" - name = "ProxyServer" - value = "none" - } - - tags = { - Name = "${var.project_name}-${var.environment}-env" - Environment = var.environment - Project = var.project_name - } - - # Ensure the service role exists before creating the environment - depends_on = [ - aws_elastic_beanstalk_application.main - ] -} diff --git a/infrastructure/modules/elasticbeanstalk/outputs.tf b/infrastructure/modules/elasticbeanstalk/outputs.tf deleted file mode 100644 index 6f2d3318b4..0000000000 --- a/infrastructure/modules/elasticbeanstalk/outputs.tf +++ /dev/null @@ -1,36 +0,0 @@ -# Elastic Beanstalk Module Outputs - -output "application_name" { - description = "Name of the Elastic Beanstalk application" - value = aws_elastic_beanstalk_application.main.name -} - -output "environment_name" { - description = "Name of the Elastic Beanstalk environment" - value = aws_elastic_beanstalk_environment.main.name -} - -output "environment_id" { - description = "ID of the Elastic Beanstalk environment" - value = aws_elastic_beanstalk_environment.main.id -} - -output "environment_cname" { - description = "CNAME of the Elastic Beanstalk environment" - value = aws_elastic_beanstalk_environment.main.cname -} - -output "environment_endpoint_url" { - description = "URL endpoint of the environment" - value = var.enable_https ? "https://${aws_elastic_beanstalk_environment.main.cname}" : "http://${aws_elastic_beanstalk_environment.main.cname}" -} - -output "load_balancers" { - description = "List of load balancers attached to the environment" - value = aws_elastic_beanstalk_environment.main.load_balancers -} - -output "autoscaling_groups" { - description = "List of autoscaling groups attached to the environment" - value = aws_elastic_beanstalk_environment.main.autoscaling_groups -} diff --git a/infrastructure/modules/elasticbeanstalk/variables.tf b/infrastructure/modules/elasticbeanstalk/variables.tf deleted file mode 100644 index 5d8e41e9d1..0000000000 --- a/infrastructure/modules/elasticbeanstalk/variables.tf +++ /dev/null @@ -1,112 +0,0 @@ -# Elastic Beanstalk Module Variables - -variable "project_name" { - description = "Name of the project" - type = string -} - -variable "environment" { - description = "Environment name (e.g., production, staging)" - type = string -} - -variable "solution_stack_name" { - description = "Elastic Beanstalk solution stack name" - type = string - # Find the latest: aws elasticbeanstalk list-available-solution-stacks - default = "64bit Amazon Linux 2023 v4.7.4 running Docker" -} - -variable "vpc_id" { - description = "VPC ID" - type = string -} - -variable "subnet_ids" { - description = "List of subnet IDs for EC2 instances" - type = list(string) -} - -variable "elb_subnet_ids" { - description = "List of subnet IDs for the load balancer" - type = list(string) -} - -variable "instance_type" { - description = "EC2 instance type" - type = string - default = "t3.small" -} - -variable "min_instance_count" { - description = "Minimum number of instances" - type = number - default = 1 -} - -variable "max_instance_count" { - description = "Maximum number of instances" - type = number - default = 4 -} - -variable "instance_profile_name" { - description = "IAM instance profile name" - type = string -} - -variable "eb_service_role_name" { - description = "Elastic Beanstalk service role name" - type = string -} - -variable "eb_service_role_arn" { - description = "Elastic Beanstalk service role ARN" - type = string -} - -variable "instance_security_group_id" { - description = "Security group ID for EC2 instances" - type = string -} - -variable "alb_security_group_id" { - description = "Security group ID for Application Load Balancer" - type = string -} - -variable "deployment_policy" { - description = "Deployment policy (Rolling, RollingWithAdditionalBatch, Immutable)" - type = string - default = "RollingWithAdditionalBatch" -} - -variable "health_check_path" { - description = "Path for health check" - type = string - default = "/health" -} - -variable "log_retention_days" { - description = "Number of days to retain logs" - type = number - default = 7 -} - -variable "environment_variables" { - description = "Map of environment variables" - type = map(string) - default = {} -} - -variable "enable_https" { - description = "Enable HTTPS listener on ALB" - type = bool - default = false -} - -variable "ssl_certificate_arn" { - description = "ARN of SSL certificate for HTTPS listener" - type = string - default = "" -} diff --git a/infrastructure/modules/iam/main.tf b/infrastructure/modules/iam/main.tf deleted file mode 100644 index f2414303c7..0000000000 --- a/infrastructure/modules/iam/main.tf +++ /dev/null @@ -1,184 +0,0 @@ -# IAM Module - Roles and Policies - -############# -# Elastic Beanstalk Service Role -############# -resource "aws_iam_role" "eb_service_role" { - name = "${var.project_name}-${var.environment}-eb-service-role" - - assume_role_policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Action = "sts:AssumeRole" - Effect = "Allow" - Principal = { - Service = "elasticbeanstalk.amazonaws.com" - } - } - ] - }) - - tags = { - Name = "${var.project_name}-${var.environment}-eb-service-role" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_iam_role_policy_attachment" "eb_service_role_policy" { - role = aws_iam_role.eb_service_role.name - policy_arn = "arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkService" -} - -resource "aws_iam_role_policy_attachment" "eb_enhanced_health" { - role = aws_iam_role.eb_service_role.name - policy_arn = "arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkEnhancedHealth" -} - -############# -# EC2 Instance Profile for Elastic Beanstalk -############# -resource "aws_iam_role" "eb_ec2_role" { - name = "${var.project_name}-${var.environment}-eb-ec2-role" - - assume_role_policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Action = "sts:AssumeRole" - Effect = "Allow" - Principal = { - Service = "ec2.amazonaws.com" - } - } - ] - }) - - tags = { - Name = "${var.project_name}-${var.environment}-eb-ec2-role" - Environment = var.environment - Project = var.project_name - } -} - -# Attach AWS managed policies -resource "aws_iam_role_policy_attachment" "eb_web_tier" { - role = aws_iam_role.eb_ec2_role.name - policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier" -} - -resource "aws_iam_role_policy_attachment" "eb_worker_tier" { - role = aws_iam_role.eb_ec2_role.name - policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier" -} - -resource "aws_iam_role_policy_attachment" "eb_multicontainer_docker" { - role = aws_iam_role.eb_ec2_role.name - policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker" -} - -# Custom policy for SSM Parameter Store and Secrets Manager access -resource "aws_iam_role_policy" "eb_secrets_access" { - name = "${var.project_name}-${var.environment}-eb-secrets-access" - role = aws_iam_role.eb_ec2_role.id - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Sid = "AllowSSMParameterAccess" - Effect = "Allow" - Action = [ - "ssm:GetParameter", - "ssm:GetParameters", - "ssm:GetParametersByPath" - ] - Resource = "arn:aws:ssm:${var.aws_region}:*:parameter/${var.project_name}/${var.environment}/*" - }, - { - Sid = "AllowSecretsManagerAccess" - Effect = "Allow" - Action = [ - "secretsmanager:GetSecretValue", - "secretsmanager:DescribeSecret" - ] - Resource = "arn:aws:secretsmanager:${var.aws_region}:*:secret:${var.project_name}/${var.environment}/*" - }, - { - Sid = "AllowKMSDecrypt" - Effect = "Allow" - Action = [ - "kms:Decrypt", - "kms:DescribeKey" - ] - Resource = "*" - } - ] - }) -} - -# Custom policy for CloudWatch Logs -resource "aws_iam_role_policy" "eb_cloudwatch_logs" { - name = "${var.project_name}-${var.environment}-eb-cloudwatch" - role = aws_iam_role.eb_ec2_role.id - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Effect = "Allow" - Action = [ - "logs:CreateLogGroup", - "logs:CreateLogStream", - "logs:PutLogEvents", - "logs:DescribeLogStreams" - ] - Resource = "arn:aws:logs:${var.aws_region}:*:log-group:/aws/elasticbeanstalk/${var.project_name}-${var.environment}/*" - } - ] - }) -} - -# Custom policy for ECR access -resource "aws_iam_role_policy" "eb_ecr_access" { - name = "${var.project_name}-${var.environment}-eb-ecr-access" - role = aws_iam_role.eb_ec2_role.id - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Sid = "AllowECRPull" - Effect = "Allow" - Action = [ - "ecr:GetAuthorizationToken", - "ecr:BatchCheckLayerAvailability", - "ecr:GetDownloadUrlForLayer", - "ecr:BatchGetImage" - ] - Resource = "*" - } - ] - }) -} - -# EC2 Instance Profile -resource "aws_iam_instance_profile" "eb_ec2_profile" { - name = "${var.project_name}-${var.environment}-eb-ec2-profile" - role = aws_iam_role.eb_ec2_role.name - - tags = { - Name = "${var.project_name}-${var.environment}-eb-ec2-profile" - Environment = var.environment - Project = var.project_name - } -} - -############# -# CloudFront OAI for S3 Access (Frontend) -############# -resource "aws_cloudfront_origin_access_identity" "frontend" { - count = var.create_cloudfront_oai ? 1 : 0 - comment = "${var.project_name}-${var.environment} CloudFront OAI for frontend" -} diff --git a/infrastructure/modules/iam/outputs.tf b/infrastructure/modules/iam/outputs.tf deleted file mode 100644 index 8c3f91eb70..0000000000 --- a/infrastructure/modules/iam/outputs.tf +++ /dev/null @@ -1,31 +0,0 @@ -# IAM Module Outputs - -output "eb_service_role_name" { - description = "Name of the Elastic Beanstalk service role" - value = aws_iam_role.eb_service_role.name -} - -output "eb_service_role_arn" { - description = "ARN of the Elastic Beanstalk service role" - value = aws_iam_role.eb_service_role.arn -} - -output "eb_ec2_instance_profile_name" { - description = "Name of the EC2 instance profile for Elastic Beanstalk" - value = aws_iam_instance_profile.eb_ec2_profile.name -} - -output "eb_ec2_role_name" { - description = "Name of the EC2 role for Elastic Beanstalk" - value = aws_iam_role.eb_ec2_role.name -} - -output "cloudfront_oai_iam_arn" { - description = "IAM ARN of the CloudFront Origin Access Identity" - value = var.create_cloudfront_oai ? aws_cloudfront_origin_access_identity.frontend[0].iam_arn : null -} - -output "cloudfront_oai_path" { - description = "Path of the CloudFront Origin Access Identity" - value = var.create_cloudfront_oai ? aws_cloudfront_origin_access_identity.frontend[0].cloudfront_access_identity_path : null -} diff --git a/infrastructure/modules/iam/variables.tf b/infrastructure/modules/iam/variables.tf deleted file mode 100644 index 1a88cb5873..0000000000 --- a/infrastructure/modules/iam/variables.tf +++ /dev/null @@ -1,22 +0,0 @@ -# IAM Module Variables - -variable "project_name" { - description = "Name of the project" - type = string -} - -variable "environment" { - description = "Environment name (e.g., production, staging)" - type = string -} - -variable "aws_region" { - description = "AWS region" - type = string -} - -variable "create_cloudfront_oai" { - description = "Whether to create CloudFront Origin Access Identity" - type = bool - default = false -} diff --git a/infrastructure/modules/monitoring/main.tf b/infrastructure/modules/monitoring/main.tf deleted file mode 100644 index 1f84c01fb0..0000000000 --- a/infrastructure/modules/monitoring/main.tf +++ /dev/null @@ -1,261 +0,0 @@ -# Monitoring Module - CloudWatch Dashboards and Alarms - -############# -# CloudWatch Dashboard -############# -resource "aws_cloudwatch_dashboard" "main" { - dashboard_name = "${var.project_name}-${var.environment}-dashboard" - - dashboard_body = jsonencode({ - widgets = [ - # EC2 CPU Utilization - { - type = "metric" - properties = { - metrics = [ - ["AWS/EC2", "CPUUtilization", "AutoScalingGroupName", var.eb_autoscaling_group_name, { stat = "Average" }] - ] - period = 300 - stat = "Average" - region = var.aws_region - title = "EC2 CPU Utilization (%)" - yAxis = { - left = { - min = 0 - max = 100 - } - } - } - }, - # EC2 Memory Utilization - { - type = "metric" - properties = { - metrics = [ - ["CWAgent", "mem_used_percent", "AutoScalingGroupName", var.eb_autoscaling_group_name, { stat = "Average" }] - ] - period = 300 - stat = "Average" - region = var.aws_region - title = "EC2 Memory Utilization (%)" - yAxis = { - left = { - min = 0 - max = 100 - } - } - } - }, - # EB Request Count - { - type = "metric" - properties = { - metrics = [ - ["AWS/ElasticBeanstalk", "RequestCount", "EnvironmentName", var.eb_environment_name, { stat = "Sum" }] - ] - period = 300 - stat = "Sum" - region = var.aws_region - title = "Request Count" - } - }, - # HTTP 5xx Errors - { - type = "metric" - properties = { - metrics = [ - ["AWS/ElasticBeanstalk", "ApplicationRequests5xx", "EnvironmentName", var.eb_environment_name, { stat = "Sum" }] - ] - period = 300 - stat = "Sum" - region = var.aws_region - title = "HTTP 5xx Errors" - } - }, - # RDS CPU Utilization - { - type = "metric" - properties = { - metrics = [ - ["AWS/RDS", "CPUUtilization", "DBInstanceIdentifier", var.rds_instance_id, { stat = "Average" }] - ] - period = 300 - stat = "Average" - region = var.aws_region - title = "RDS CPU Utilization (%)" - yAxis = { - left = { - min = 0 - max = 100 - } - } - } - }, - # RDS Read/Write IOPS - { - type = "metric" - properties = { - metrics = [ - ["AWS/RDS", "ReadIOPS", "DBInstanceIdentifier", var.rds_instance_id, { stat = "Average", label = "Read IOPS" }], - [".", "WriteIOPS", ".", ".", { stat = "Average", label = "Write IOPS" }] - ] - period = 300 - stat = "Average" - region = var.aws_region - title = "RDS Read/Write IOPS" - } - }, - # RDS Network Throughput - { - type = "metric" - properties = { - metrics = [ - ["AWS/RDS", "NetworkReceiveThroughput", "DBInstanceIdentifier", var.rds_instance_id, { stat = "Average", label = "Network In" }], - [".", "NetworkTransmitThroughput", ".", ".", { stat = "Average", label = "Network Out" }] - ] - period = 300 - stat = "Average" - region = var.aws_region - title = "RDS Network Throughput (Bytes/sec)" - } - }, - # RDS Database Connections - { - type = "metric" - properties = { - metrics = [ - ["AWS/RDS", "DatabaseConnections", "DBInstanceIdentifier", var.rds_instance_id, { stat = "Average" }] - ] - period = 300 - stat = "Average" - region = var.aws_region - title = "RDS Database Connections" - } - }, - # RDS Freeable Memory - { - type = "metric" - properties = { - metrics = [ - ["AWS/RDS", "FreeableMemory", "DBInstanceIdentifier", var.rds_instance_id, { stat = "Average" }] - ] - period = 300 - stat = "Average" - region = var.aws_region - title = "RDS Freeable Memory (Bytes)" - } - } - ] - }) -} - -############# -# EB CloudWatch Alarms -############# - -# High CPU Alarm -resource "aws_cloudwatch_metric_alarm" "eb_cpu_high" { - alarm_name = "${var.project_name}-${var.environment}-eb-cpu-high" - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 2 - metric_name = "CPUUtilization" - namespace = "AWS/EC2" - period = 300 - statistic = "Average" - threshold = 80 - alarm_description = "This metric monitors EC2 CPU utilization" - alarm_actions = [var.sns_topic_arn] - - dimensions = { - AutoScalingGroupName = var.eb_autoscaling_group_name - } - - tags = { - Environment = var.environment - Project = var.project_name - } -} - -# High Memory Alarm -resource "aws_cloudwatch_metric_alarm" "eb_memory_high" { - alarm_name = "${var.project_name}-${var.environment}-eb-memory-high" - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 2 - metric_name = "mem_used_percent" - namespace = "CWAgent" - period = 300 - statistic = "Average" - threshold = 80 - alarm_description = "This metric monitors EC2 memory utilization" - alarm_actions = [var.sns_topic_arn] - - dimensions = { - AutoScalingGroupName = var.eb_autoscaling_group_name - } - - tags = { - Environment = var.environment - Project = var.project_name - } -} - -# Critical Memory Alarm -resource "aws_cloudwatch_metric_alarm" "eb_memory_critical" { - alarm_name = "${var.project_name}-${var.environment}-eb-memory-critical" - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 2 - metric_name = "mem_used_percent" - namespace = "CWAgent" - period = 300 - statistic = "Average" - threshold = 90 - alarm_description = "This metric monitors EC2 memory utilization - CRITICAL" - alarm_actions = [var.sns_topic_arn] - - dimensions = { - AutoScalingGroupName = var.eb_autoscaling_group_name - } - - tags = { - Environment = var.environment - Project = var.project_name - } -} - -# HTTP 5xx Error Rate Alarm -# This monitors server errors which indicate application health issues -resource "aws_cloudwatch_metric_alarm" "eb_http_5xx_errors" { - alarm_name = "${var.project_name}-${var.environment}-eb-http-5xx-high" - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 2 - metric_name = "ApplicationRequests5xx" - namespace = "AWS/ElasticBeanstalk" - period = 300 - statistic = "Sum" - threshold = 10 # Alert if more than 10 5xx errors in 5 minutes - alarm_description = "High rate of HTTP 5xx errors indicates application issues" - alarm_actions = [var.sns_topic_arn] - - dimensions = { - EnvironmentName = var.eb_environment_name - } - - tags = { - Environment = var.environment - Project = var.project_name - } -} - -############# -# Log Groups -############# -resource "aws_cloudwatch_log_group" "eb_logs" { - name = "/aws/elasticbeanstalk/${var.project_name}-${var.environment}" - retention_in_days = var.log_retention_days - - tags = { - Name = "${var.project_name}-${var.environment}-eb-logs" - Environment = var.environment - Project = var.project_name - } -} diff --git a/infrastructure/modules/monitoring/outputs.tf b/infrastructure/modules/monitoring/outputs.tf deleted file mode 100644 index a3d3c4824b..0000000000 --- a/infrastructure/modules/monitoring/outputs.tf +++ /dev/null @@ -1,11 +0,0 @@ -# Monitoring Module Outputs - -output "dashboard_name" { - description = "Name of the CloudWatch dashboard" - value = aws_cloudwatch_dashboard.main.dashboard_name -} - -output "log_group_name" { - description = "Name of the CloudWatch log group" - value = aws_cloudwatch_log_group.eb_logs.name -} diff --git a/infrastructure/modules/monitoring/variables.tf b/infrastructure/modules/monitoring/variables.tf deleted file mode 100644 index 54f97f3bf8..0000000000 --- a/infrastructure/modules/monitoring/variables.tf +++ /dev/null @@ -1,42 +0,0 @@ -# Monitoring Module Variables - -variable "project_name" { - description = "Name of the project" - type = string -} - -variable "environment" { - description = "Environment name (e.g., production, staging)" - type = string -} - -variable "aws_region" { - description = "AWS region" - type = string -} - -variable "eb_environment_name" { - description = "Elastic Beanstalk environment name" - type = string -} - -variable "eb_autoscaling_group_name" { - description = "Elastic Beanstalk autoscaling group name" - type = string -} - -variable "rds_instance_id" { - description = "RDS instance ID" - type = string -} - -variable "log_retention_days" { - description = "Number of days to retain logs" - type = number - default = 7 -} - -variable "sns_topic_arn" { - description = "ARN of the SNS topic for alarm notifications" - type = string -} diff --git a/infrastructure/modules/network/main.tf b/infrastructure/modules/network/main.tf deleted file mode 100644 index c11cd989bc..0000000000 --- a/infrastructure/modules/network/main.tf +++ /dev/null @@ -1,240 +0,0 @@ -# Network Module - VPC, Subnets, Security Groups -# This creates the networking foundation for the application - -# Need 2 AZs for ALB and networking stuff but we will only use 1 for EB and RDS -locals { - availability_zones = ["${var.aws_region}a", "${var.aws_region}b"] -} - -############# -# VPC -############# -resource "aws_vpc" "main" { - cidr_block = var.vpc_cidr - enable_dns_hostnames = true - enable_dns_support = true - - - tags = { - Name = "${var.project_name}-${var.environment}-vpc" - Environment = var.environment - Project = var.project_name - } -} - -############# -# Internet Gateway -############# -resource "aws_internet_gateway" "main" { - vpc_id = aws_vpc.main.id - - tags = { - Name = "${var.project_name}-${var.environment}-igw" - Environment = var.environment - Project = var.project_name - } -} - -############# -# Public Subnets (for ALB and EB instances) -############# -resource "aws_subnet" "public" { - count = length(local.availability_zones) - - vpc_id = aws_vpc.main.id - cidr_block = cidrsubnet(var.vpc_cidr, 4, count.index) - availability_zone = local.availability_zones[count.index] - map_public_ip_on_launch = true - - tags = { - Name = "${var.project_name}-${var.environment}-public-${local.availability_zones[count.index]}" - Environment = var.environment - Project = var.project_name - Type = "public" - } -} - -############# -# Private Subnets (for RDS) -############# -resource "aws_subnet" "private" { - count = length(local.availability_zones) - - vpc_id = aws_vpc.main.id - cidr_block = cidrsubnet(var.vpc_cidr, 4, count.index + 2) - availability_zone = local.availability_zones[count.index] - - tags = { - Name = "${var.project_name}-${var.environment}-private-${local.availability_zones[count.index]}" - Environment = var.environment - Project = var.project_name - Type = "private" - } -} - -############# -# Route Table for Public Subnets -############# -resource "aws_route_table" "public" { - vpc_id = aws_vpc.main.id - - route { - cidr_block = "0.0.0.0/0" - gateway_id = aws_internet_gateway.main.id - } - - tags = { - Name = "${var.project_name}-${var.environment}-public-rt" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_route_table_association" "public" { - count = length(aws_subnet.public) - - subnet_id = aws_subnet.public[count.index].id - route_table_id = aws_route_table.public.id -} - -############# -# Security Group - Application Load Balancer -############# -resource "aws_security_group" "alb" { - name_prefix = "${var.project_name}-${var.environment}-alb-" - description = "Security group for Application Load Balancer" - vpc_id = aws_vpc.main.id - - ingress { - description = "HTTP from internet" - from_port = 80 - to_port = 80 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - ingress { - description = "HTTPS from internet" - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - description = "Allow all outbound traffic" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "${var.project_name}-${var.environment}-alb-sg" - Environment = var.environment - Project = var.project_name - } - - lifecycle { - create_before_destroy = true - } -} - -############# -# Security Group - Elastic Beanstalk Instances -############# -resource "aws_security_group" "eb_instance" { - name_prefix = "${var.project_name}-${var.environment}-eb-" - description = "Security group for Elastic Beanstalk instances" - vpc_id = aws_vpc.main.id - - ingress { - description = "HTTP from ALB" - from_port = 80 - to_port = 80 - protocol = "tcp" - security_groups = [aws_security_group.alb.id] - } - - ingress { - description = "Application port from ALB" - from_port = 3001 - to_port = 3001 - protocol = "tcp" - security_groups = [aws_security_group.alb.id] - } - - egress { - description = "Allow all outbound traffic" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "${var.project_name}-${var.environment}-eb-sg" - Environment = var.environment - Project = var.project_name - } - - lifecycle { - create_before_destroy = true - } -} - -############# -# Security Group - RDS Database -############# -resource "aws_security_group" "rds" { - name_prefix = "${var.project_name}-${var.environment}-rds-" - description = "Security group for RDS database" - vpc_id = aws_vpc.main.id - - # No inline rules - all rules defined separately below - - egress { - description = "Allow all outbound traffic" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = { - Name = "${var.project_name}-${var.environment}-rds-sg" - Environment = var.environment - Project = var.project_name - } - - lifecycle { - create_before_destroy = true - } -} - -############# -# Security Group Rule - RDS Access from EB Instances -############# -resource "aws_security_group_rule" "rds_from_eb" { - type = "ingress" - description = "PostgreSQL from EB instances" - from_port = 5432 - to_port = 5432 - protocol = "tcp" - source_security_group_id = aws_security_group.eb_instance.id - security_group_id = aws_security_group.rds.id -} - -############# -# DB Subnet Group for RDS (Private Subnets) -############# -resource "aws_db_subnet_group" "main" { - name = "${var.project_name}-${var.environment}-db-subnet-group" - subnet_ids = aws_subnet.private[*].id - - tags = { - Name = "${var.project_name}-${var.environment}-db-subnet-group" - Environment = var.environment - Project = var.project_name - } -} diff --git a/infrastructure/modules/network/outputs.tf b/infrastructure/modules/network/outputs.tf deleted file mode 100644 index 7b316a1f9c..0000000000 --- a/infrastructure/modules/network/outputs.tf +++ /dev/null @@ -1,46 +0,0 @@ -# Network Module Outputs - -output "vpc_id" { - description = "ID of the VPC" - value = aws_vpc.main.id -} - -output "vpc_cidr" { - description = "CIDR block of the VPC" - value = aws_vpc.main.cidr_block -} - -output "public_subnet_ids" { - description = "IDs of public subnets" - value = aws_subnet.public[*].id -} - -output "private_subnet_ids" { - description = "IDs of private subnets" - value = aws_subnet.private[*].id -} - -output "alb_security_group_id" { - description = "ID of the ALB security group" - value = aws_security_group.alb.id -} - -output "eb_instance_security_group_id" { - description = "ID of the EB instance security group" - value = aws_security_group.eb_instance.id -} - -output "rds_security_group_id" { - description = "ID of the RDS security group" - value = aws_security_group.rds.id -} - -output "db_subnet_group_name" { - description = "Name of the DB subnet group (private subnets)" - value = aws_db_subnet_group.main.name -} - -output "availability_zones" { - description = "List of availability zones used" - value = local.availability_zones -} diff --git a/infrastructure/modules/network/variables.tf b/infrastructure/modules/network/variables.tf deleted file mode 100644 index 720de301b7..0000000000 --- a/infrastructure/modules/network/variables.tf +++ /dev/null @@ -1,22 +0,0 @@ -# Network Module Variables - -variable "project_name" { - description = "Name of the project" - type = string -} - -variable "environment" { - description = "Environment name (e.g., production, staging)" - type = string -} - -variable "aws_region" { - description = "AWS region" - type = string -} - -variable "vpc_cidr" { - description = "CIDR block for VPC" - type = string - default = "10.0.0.0/16" -} diff --git a/infrastructure/modules/rds/main.tf b/infrastructure/modules/rds/main.tf deleted file mode 100644 index c074bf0d5a..0000000000 --- a/infrastructure/modules/rds/main.tf +++ /dev/null @@ -1,156 +0,0 @@ -# RDS Module - PostgreSQL Database - -############# -# RDS Instance -############# -resource "aws_db_instance" "main" { - identifier = "${var.project_name}-${var.environment}-db" - - # Engine Configuration - engine = "postgres" - engine_version = var.postgres_version - instance_class = var.instance_class - allocated_storage = var.allocated_storage - storage_type = var.storage_type - storage_encrypted = true - - # Database Configuration - db_name = var.database_name - username = var.master_username - password = var.master_password - port = 5432 - - # Network Configuration - db_subnet_group_name = var.db_subnet_group_name - vpc_security_group_ids = [var.security_group_id] - publicly_accessible = var.publicly_accessible - - # Backup Configuration - backup_retention_period = var.backup_retention_period - backup_window = var.backup_window - maintenance_window = var.maintenance_window - skip_final_snapshot = false - final_snapshot_identifier = "${var.project_name}-${var.environment}-final-snapshot" - - # Multi-AZ configuration - multi_az = var.multi_az - - # Performance Insights - enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"] - performance_insights_enabled = var.performance_insights_enabled - performance_insights_retention_period = var.performance_insights_enabled ? 7 : null - - # Auto Minor Version Upgrade - auto_minor_version_upgrade = true - - # Apply changes immediately instead of during maintenance window - apply_immediately = true - - # Deletion Protection - deletion_protection = var.deletion_protection - - # Copy tags to snapshots - copy_tags_to_snapshot = true - - tags = { - Name = "${var.project_name}-${var.environment}-db" - Environment = var.environment - Project = var.project_name - } - - lifecycle { - # Ignore password changes after initial creation - ignore_changes = [password] - } -} - -############# -# CloudWatch Alarms for RDS -############# -resource "aws_cloudwatch_metric_alarm" "database_cpu" { - alarm_name = "${var.project_name}-${var.environment}-db-cpu-high" - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 2 - metric_name = "CPUUtilization" - namespace = "AWS/RDS" - period = 300 - statistic = "Average" - threshold = 80 - alarm_description = "This metric monitors RDS CPU utilization" - alarm_actions = var.alarm_actions - - dimensions = { - DBInstanceIdentifier = aws_db_instance.main.id - } - - tags = { - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_cloudwatch_metric_alarm" "database_memory" { - alarm_name = "${var.project_name}-${var.environment}-db-memory-low" - comparison_operator = "LessThanThreshold" - evaluation_periods = 2 - metric_name = "FreeableMemory" - namespace = "AWS/RDS" - period = 300 - statistic = "Average" - threshold = 268435456 # 256 MB in bytes - alarm_description = "This metric monitors RDS freeable memory" - alarm_actions = var.alarm_actions - - dimensions = { - DBInstanceIdentifier = aws_db_instance.main.id - } - - tags = { - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_cloudwatch_metric_alarm" "database_storage" { - alarm_name = "${var.project_name}-${var.environment}-db-storage-low" - comparison_operator = "LessThanThreshold" - evaluation_periods = 1 - metric_name = "FreeStorageSpace" - namespace = "AWS/RDS" - period = 300 - statistic = "Average" - threshold = 5368709120 # 5 GB in bytes - alarm_description = "This metric monitors RDS free storage space" - alarm_actions = var.alarm_actions - - dimensions = { - DBInstanceIdentifier = aws_db_instance.main.id - } - - tags = { - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_cloudwatch_metric_alarm" "database_connections" { - alarm_name = "${var.project_name}-${var.environment}-db-connections-high" - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 2 - metric_name = "DatabaseConnections" - namespace = "AWS/RDS" - period = 300 - statistic = "Average" - threshold = 80 - alarm_description = "This metric monitors RDS database connections" - alarm_actions = var.alarm_actions - - dimensions = { - DBInstanceIdentifier = aws_db_instance.main.id - } - - tags = { - Environment = var.environment - Project = var.project_name - } -} diff --git a/infrastructure/modules/rds/outputs.tf b/infrastructure/modules/rds/outputs.tf deleted file mode 100644 index f7da28dbed..0000000000 --- a/infrastructure/modules/rds/outputs.tf +++ /dev/null @@ -1,43 +0,0 @@ -# RDS Module Outputs - -output "db_instance_id" { - description = "The RDS instance ID" - value = aws_db_instance.main.id -} - -output "db_instance_arn" { - description = "The ARN of the RDS instance" - value = aws_db_instance.main.arn -} - -output "db_instance_endpoint" { - description = "The connection endpoint" - value = aws_db_instance.main.endpoint -} - -output "db_instance_address" { - description = "The hostname of the RDS instance" - value = aws_db_instance.main.address -} - -output "db_instance_port" { - description = "The database port" - value = aws_db_instance.main.port -} - -output "db_instance_name" { - description = "The database name" - value = aws_db_instance.main.db_name -} - -output "db_instance_username" { - description = "The master username for the database" - value = aws_db_instance.main.username - sensitive = true -} - -output "database_url" { - description = "The complete database URL (format: postgresql://user:pass@host:port/dbname)" - value = "postgresql://${aws_db_instance.main.username}:${var.master_password}@${aws_db_instance.main.endpoint}/${aws_db_instance.main.db_name}" - sensitive = true -} diff --git a/infrastructure/modules/rds/variables.tf b/infrastructure/modules/rds/variables.tf deleted file mode 100644 index 8b0f3470d5..0000000000 --- a/infrastructure/modules/rds/variables.tf +++ /dev/null @@ -1,110 +0,0 @@ -# RDS Module Variables - -variable "project_name" { - description = "Name of the project" - type = string -} - -variable "environment" { - description = "Environment name (e.g., production, staging)" - type = string -} - -variable "instance_class" { - description = "The instance type of the RDS instance" - type = string - default = "db.t4g.medium" -} - -variable "allocated_storage" { - description = "The allocated storage in gigabytes" - type = number - default = 20 -} - -variable "storage_type" { - description = "One of 'standard' (magnetic), 'gp2' (general purpose SSD), or 'io1' (provisioned IOPS SSD)" - type = string - default = "gp2" -} - -variable "postgres_version" { - description = "PostgreSQL major version (minor versions auto-update)" - type = string - default = "16" -} - -variable "database_name" { - description = "The name of the database to create" - type = string -} - -variable "master_username" { - description = "Username for the master DB user" - type = string - default = "postgres" -} - -variable "master_password" { - description = "Password for the master DB user" - type = string - sensitive = true -} - -variable "db_subnet_group_name" { - description = "Name of DB subnet group" - type = string -} - -variable "security_group_id" { - description = "Security group ID for RDS" - type = string -} - -variable "publicly_accessible" { - description = "Bool to control if instance is publicly accessible" - type = bool - default = false -} - -variable "multi_az" { - description = "Enable Multi-AZ deployment for high availability (creates standby replica in different AZ)" - type = bool - default = false -} - -variable "backup_retention_period" { - description = "The days to retain backups for" - type = number - default = 7 -} - -variable "backup_window" { - description = "The daily time range during which automated backups are created" - type = string - default = "03:00-04:00" -} - -variable "maintenance_window" { - description = "The window to perform maintenance in" - type = string - default = "Mon:04:00-Mon:05:00" -} - -variable "deletion_protection" { - description = "If the DB instance should have deletion protection enabled" - type = bool - default = true -} - -variable "performance_insights_enabled" { - description = "Specifies whether Performance Insights are enabled" - type = bool - default = false -} - -variable "alarm_actions" { - description = "List of ARNs to notify when alarm triggers" - type = list(string) - default = [] -} diff --git a/infrastructure/modules/secrets/main.tf b/infrastructure/modules/secrets/main.tf deleted file mode 100644 index e9c7daefce..0000000000 --- a/infrastructure/modules/secrets/main.tf +++ /dev/null @@ -1,201 +0,0 @@ -# Secrets Module - AWS Secrets Manager - -############# -# Database Password Secret -############# -resource "aws_secretsmanager_secret" "db_password" { - name = "${var.project_name}/${var.environment}/db-password" - description = "RDS master password for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-db-password" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "db_password" { - secret_id = aws_secretsmanager_secret.db_password.id - secret_string = var.db_master_password -} - -############# -# Session Secret -############# -resource "aws_secretsmanager_secret" "session_secret" { - name = "${var.project_name}/${var.environment}/session-secret" - description = "Session secret for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-session-secret" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "session_secret" { - secret_id = aws_secretsmanager_secret.session_secret.id - secret_string = var.session_secret -} - -############# -# Google Client Secret -############# -resource "aws_secretsmanager_secret" "google_client_secret" { - name = "${var.project_name}/${var.environment}/google-client-secret" - description = "Google OAuth client secret for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-google-client-secret" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "google_client_secret" { - secret_id = aws_secretsmanager_secret.google_client_secret.id - secret_string = var.google_client_secret -} - -############# -# Google Drive Refresh Token -############# -resource "aws_secretsmanager_secret" "drive_refresh_token" { - name = "${var.project_name}/${var.environment}/drive-refresh-token" - description = "Google Drive refresh token for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-drive-refresh-token" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "drive_refresh_token" { - secret_id = aws_secretsmanager_secret.drive_refresh_token.id - secret_string = var.drive_refresh_token -} - -############# -# Encryption Key -############# -resource "aws_secretsmanager_secret" "encryption_key" { - name = "${var.project_name}/${var.environment}/encryption-key" - description = "Application encryption key for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-encryption-key" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "encryption_key" { - secret_id = aws_secretsmanager_secret.encryption_key.id - secret_string = var.encryption_key -} - -############# -# Slack Bot Token -############# -resource "aws_secretsmanager_secret" "slack_bot_token" { - name = "${var.project_name}/${var.environment}/slack-bot-token" - description = "Slack bot token for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-slack-bot-token" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "slack_bot_token" { - secret_id = aws_secretsmanager_secret.slack_bot_token.id - secret_string = var.slack_bot_token -} - -############# -# Slack Token Secret -############# -resource "aws_secretsmanager_secret" "slack_token_secret" { - name = "${var.project_name}/${var.environment}/slack-token-secret" - description = "Slack OAuth token secret for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-slack-token-secret" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "slack_token_secret" { - secret_id = aws_secretsmanager_secret.slack_token_secret.id - secret_string = var.slack_token_secret -} - -############# -# Slack Signing Secret -############# -resource "aws_secretsmanager_secret" "slack_signing_secret" { - name = "${var.project_name}/${var.environment}/slack-signing-secret" - description = "Slack signing secret for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-slack-signing-secret" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "slack_signing_secret" { - secret_id = aws_secretsmanager_secret.slack_signing_secret.id - secret_string = var.slack_signing_secret -} - -############# -# Notification Endpoint Secret -############# -resource "aws_secretsmanager_secret" "notification_endpoint_secret" { - name = "${var.project_name}/${var.environment}/notification-endpoint-secret" - description = "Notification endpoint secret for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-notification-endpoint-secret" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "notification_endpoint_secret" { - secret_id = aws_secretsmanager_secret.notification_endpoint_secret.id - secret_string = var.notification_endpoint_secret -} - -############# -# Calendar Refresh Token -############# -resource "aws_secretsmanager_secret" "calendar_refresh_token" { - name = "${var.project_name}/${var.environment}/calendar-refresh-token" - description = "Google Calendar refresh token for ${var.project_name} ${var.environment}" - recovery_window_in_days = 7 - - tags = { - Name = "${var.project_name}-${var.environment}-calendar-refresh-token" - Environment = var.environment - Project = var.project_name - } -} - -resource "aws_secretsmanager_secret_version" "calendar_refresh_token" { - secret_id = aws_secretsmanager_secret.calendar_refresh_token.id - secret_string = var.calendar_refresh_token -} diff --git a/infrastructure/modules/secrets/outputs.tf b/infrastructure/modules/secrets/outputs.tf deleted file mode 100644 index bf8d46f05a..0000000000 --- a/infrastructure/modules/secrets/outputs.tf +++ /dev/null @@ -1,151 +0,0 @@ -# Secrets Module Outputs - -############# -# Database Password -############# -output "db_password_secret_arn" { - description = "ARN of the database password secret" - value = aws_secretsmanager_secret.db_password.arn -} - -output "db_password_secret_name" { - description = "Name of the database password secret" - value = aws_secretsmanager_secret.db_password.name -} - -output "db_password" { - description = "Database password value (sensitive)" - value = aws_secretsmanager_secret_version.db_password.secret_string - sensitive = true -} - -############# -# Session Secret -############# -output "session_secret_arn" { - description = "ARN of the session secret" - value = aws_secretsmanager_secret.session_secret.arn -} - -output "session_secret_name" { - description = "Name of the session secret" - value = aws_secretsmanager_secret.session_secret.name -} - -output "session_secret" { - description = "Session secret value (sensitive)" - value = aws_secretsmanager_secret_version.session_secret.secret_string - sensitive = true -} - -############# -# Google Client Secret -############# -output "google_client_secret_arn" { - description = "ARN of the Google client secret" - value = aws_secretsmanager_secret.google_client_secret.arn -} - -output "google_client_secret" { - description = "Google client secret value (sensitive)" - value = aws_secretsmanager_secret_version.google_client_secret.secret_string - sensitive = true -} - -############# -# Drive Refresh Token -############# -output "drive_refresh_token_arn" { - description = "ARN of the Drive refresh token" - value = aws_secretsmanager_secret.drive_refresh_token.arn -} - -output "drive_refresh_token" { - description = "Drive refresh token value (sensitive)" - value = aws_secretsmanager_secret_version.drive_refresh_token.secret_string - sensitive = true -} - -############# -# Encryption Key -############# -output "encryption_key_arn" { - description = "ARN of the encryption key" - value = aws_secretsmanager_secret.encryption_key.arn -} - -output "encryption_key" { - description = "Encryption key value (sensitive)" - value = aws_secretsmanager_secret_version.encryption_key.secret_string - sensitive = true -} - -############# -# Slack Bot Token -############# -output "slack_bot_token_arn" { - description = "ARN of the Slack bot token" - value = aws_secretsmanager_secret.slack_bot_token.arn -} - -output "slack_bot_token" { - description = "Slack bot token value (sensitive)" - value = aws_secretsmanager_secret_version.slack_bot_token.secret_string - sensitive = true -} - -############# -# Slack Token Secret -############# -output "slack_token_secret_arn" { - description = "ARN of the Slack token secret" - value = aws_secretsmanager_secret.slack_token_secret.arn -} - -output "slack_token_secret" { - description = "Slack token secret value (sensitive)" - value = aws_secretsmanager_secret_version.slack_token_secret.secret_string - sensitive = true -} - -############# -# Slack Signing Secret -############# -output "slack_signing_secret_arn" { - description = "ARN of the Slack signing secret" - value = aws_secretsmanager_secret.slack_signing_secret.arn -} - -output "slack_signing_secret" { - description = "Slack signing secret value (sensitive)" - value = aws_secretsmanager_secret_version.slack_signing_secret.secret_string - sensitive = true -} - -############# -# Notification Endpoint Secret -############# -output "notification_endpoint_secret_arn" { - description = "ARN of the notification endpoint secret" - value = aws_secretsmanager_secret.notification_endpoint_secret.arn -} - -output "notification_endpoint_secret" { - description = "Notification endpoint secret value (sensitive)" - value = aws_secretsmanager_secret_version.notification_endpoint_secret.secret_string - sensitive = true -} - -############# -# Calendar Refresh Token -############# -output "calendar_refresh_token_arn" { - description = "ARN of the calendar refresh token" - value = aws_secretsmanager_secret.calendar_refresh_token.arn -} - -output "calendar_refresh_token" { - description = "Calendar refresh token value (sensitive)" - value = aws_secretsmanager_secret_version.calendar_refresh_token.secret_string - sensitive = true -} diff --git a/infrastructure/modules/secrets/variables.tf b/infrastructure/modules/secrets/variables.tf deleted file mode 100644 index beaa1de854..0000000000 --- a/infrastructure/modules/secrets/variables.tf +++ /dev/null @@ -1,71 +0,0 @@ -# Secrets Module Variables - -variable "project_name" { - description = "Name of the project" - type = string -} - -variable "environment" { - description = "Environment name (e.g., production, staging)" - type = string -} - -variable "db_master_password" { - description = "Master password for the database" - type = string - sensitive = true -} - -variable "session_secret" { - description = "Secret key for session management" - type = string - sensitive = true -} - -variable "google_client_secret" { - description = "Google OAuth client secret" - type = string - sensitive = true -} - -variable "drive_refresh_token" { - description = "Google Drive refresh token" - type = string - sensitive = true -} - -variable "encryption_key" { - description = "Application encryption key" - type = string - sensitive = true -} - -variable "slack_bot_token" { - description = "Slack bot token" - type = string - sensitive = true -} - -variable "slack_token_secret" { - description = "Slack OAuth token secret" - type = string - sensitive = true -} - -variable "slack_signing_secret" { - description = "Slack signing secret for request verification" - type = string - sensitive = true -} - -variable "notification_endpoint_secret" { - description = "Secret for notification endpoint authentication" - type = string - sensitive = true -} - -variable "calendar_refresh_token" { - description = "Google Calendar refresh token" - type = string - sensitive = true -} diff --git a/infrastructure/scripts/ssh-to-eb.sh b/infrastructure/scripts/ssh-to-eb.sh deleted file mode 100755 index 54d26dd79b..0000000000 --- a/infrastructure/scripts/ssh-to-eb.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash -# Script to SSH into an EB instance -# Usage: ./ssh-to-eb.sh - -set -e - -# Configuration -ENV_NAME="finishline-production-env" -KEY_PATH="~/.ssh/aws-eb" - -echo "🔍 Finding running EB instance..." -INSTANCE_ID=$(aws elasticbeanstalk describe-environment-resources \ - --environment-name $ENV_NAME \ - --query 'EnvironmentResources.Instances[0].Id' \ - --output text) - -if [ -z "$INSTANCE_ID" ] || [ "$INSTANCE_ID" == "None" ]; then - echo "❌ No running instances found in environment $ENV_NAME" - exit 1 -fi - -echo "✅ Found instance: $INSTANCE_ID" -echo "" - -echo "🔍 Getting instance public IP..." -INSTANCE_IP=$(aws ec2 describe-instances \ - --instance-ids $INSTANCE_ID \ - --query 'Reservations[0].Instances[0].PublicIpAddress' \ - --output text) - -if [ -z "$INSTANCE_IP" ] || [ "$INSTANCE_IP" == "None" ]; then - echo "❌ Could not get public IP for instance $INSTANCE_ID" - exit 1 -fi - -echo "✅ Instance IP: $INSTANCE_IP" -echo "" - -# Expand tilde in key path -KEY_PATH_EXPANDED="${KEY_PATH/#\~/$HOME}" - -# Check if key file exists -if [ ! -f "$KEY_PATH_EXPANDED" ]; then - echo "❌ SSH key not found at $KEY_PATH_EXPANDED" - exit 1 -fi - -# Check key permissions -KEY_PERMS=$(stat -f "%A" "$KEY_PATH_EXPANDED" 2>/dev/null || stat -c "%a" "$KEY_PATH_EXPANDED" 2>/dev/null) -if [ "$KEY_PERMS" != "400" ] && [ "$KEY_PERMS" != "600" ]; then - echo "⚠️ Warning: SSH key has permissions $KEY_PERMS, should be 400 or 600" - echo " Run: chmod 400 $KEY_PATH_EXPANDED" - echo "" -fi - -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "🔌 Connecting to EB instance..." -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "" -echo "Instance: $INSTANCE_IP ($INSTANCE_ID)" -echo "User: ec2-user" -echo "" -echo "Useful commands once connected:" -echo " docker ps # See running containers" -echo " docker logs # View container logs" -echo " sudo tail -f /var/log/eb-* # View EB logs" -echo "" -echo "To exit: type 'exit' or press Ctrl+D" -echo "" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "" - -# SSH into the instance -ssh -i "$KEY_PATH_EXPANDED" \ - -o StrictHostKeyChecking=no \ - -o UserKnownHostsFile=/dev/null \ - ec2-user@$INSTANCE_IP diff --git a/infrastructure/scripts/tunnel-to-rds.sh b/infrastructure/scripts/tunnel-to-rds.sh deleted file mode 100755 index dfb1f657f6..0000000000 --- a/infrastructure/scripts/tunnel-to-rds.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# Script to create SSH tunnel to RDS through EB instance -# Usage: ./tunnel-to-rds.sh - -set -e - -# Configuration -ENV_NAME="finishline-production-env" -DB_IDENTIFIER="finishline-production-db" -KEY_PATH="~/.ssh/aws-eb" -LOCAL_PORT=5434 - -echo "🔍 Finding RDS endpoint..." -RDS_ENDPOINT=$(aws rds describe-db-instances \ - --db-instance-identifier $DB_IDENTIFIER \ - --query 'DBInstances[0].Endpoint.Address' \ - --output text) - -if [ -z "$RDS_ENDPOINT" ] || [ "$RDS_ENDPOINT" == "None" ]; then - echo "❌ Could not find RDS endpoint for $DB_IDENTIFIER" - exit 1 -fi - -echo "✅ RDS Endpoint: $RDS_ENDPOINT" -echo "" - -echo "🔍 Finding running EB instance..." -INSTANCE_ID=$(aws elasticbeanstalk describe-environment-resources \ - --environment-name $ENV_NAME \ - --query 'EnvironmentResources.Instances[0].Id' \ - --output text) - -if [ -z "$INSTANCE_ID" ] || [ "$INSTANCE_ID" == "None" ]; then - echo "❌ No running instances found in environment $ENV_NAME" - exit 1 -fi - -echo "✅ Found instance: $INSTANCE_ID" -echo "" - -echo "🔍 Getting instance public IP..." -INSTANCE_IP=$(aws ec2 describe-instances \ - --instance-ids $INSTANCE_ID \ - --query 'Reservations[0].Instances[0].PublicIpAddress' \ - --output text) - -if [ -z "$INSTANCE_IP" ] || [ "$INSTANCE_IP" == "None" ]; then - echo "❌ Could not get public IP for instance $INSTANCE_ID" - exit 1 -fi - -echo "✅ Instance IP: $INSTANCE_IP" -echo "" - -# Expand tilde in key path -KEY_PATH_EXPANDED="${KEY_PATH/#\~/$HOME}" - -# Check if key file exists -if [ ! -f "$KEY_PATH_EXPANDED" ]; then - echo "❌ SSH key not found at $KEY_PATH_EXPANDED" - exit 1 -fi - -# Check key permissions -KEY_PERMS=$(stat -f "%A" "$KEY_PATH_EXPANDED" 2>/dev/null || stat -c "%a" "$KEY_PATH_EXPANDED" 2>/dev/null) -if [ "$KEY_PERMS" != "400" ] && [ "$KEY_PERMS" != "600" ]; then - echo "⚠️ Warning: SSH key has permissions $KEY_PERMS, should be 400 or 600" - echo " Run: chmod 400 $KEY_PATH_EXPANDED" - echo "" -fi - -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "🚇 Creating SSH tunnel..." -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "" -echo "Tunnel Details:" -echo " Local Port: localhost:$LOCAL_PORT" -echo " RDS Endpoint: $RDS_ENDPOINT:5432" -echo " Via Instance: $INSTANCE_IP" -echo "" -echo "Once connected, open a NEW terminal and run:" -echo " psql -h localhost -p $LOCAL_PORT -U postgres -d finishline" -echo "" -echo "Or use connection string:" -echo " psql postgresql://postgres:YOUR_PASSWORD@localhost:$LOCAL_PORT/finishline" -echo "" -echo "To exit psql: \\q or Ctrl+D" -echo "To close tunnel: Press Ctrl+C in this window" -echo "" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "" - -# Create the SSH tunnel -ssh -i "$KEY_PATH_EXPANDED" \ - -o StrictHostKeyChecking=no \ - -o UserKnownHostsFile=/dev/null \ - -L $LOCAL_PORT:$RDS_ENDPOINT:5432 \ - ec2-user@$INSTANCE_IP diff --git a/src/backend/index.ts b/src/backend/index.ts index e0198b4bea..ac3887d693 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -33,26 +33,13 @@ const isProd = process.env.NODE_ENV === 'production'; // cors options const allowedHeaders = isProd ? prodHeaders : '*'; - -// Build list of allowed origins -const allowedOrigins = [ - 'http://localhost:3000', - 'http://127.0.0.1:3000', - 'https://finishlinebyner.com', - 'https://qa.finishlinebyner.com' -]; - const options: cors.CorsOptions = { - origin: (origin, callback) => { - // allow requests with no origin like postman or curl requests - if (!origin) return callback(null, true); - - if (allowedOrigins.includes(origin)) { - return callback(null, true); - } - - callback(new Error('Not allowed by CORS')); - }, + origin: [ + 'http://localhost:3000', + 'http://127.0.0.1:3000', + 'https://finishlinebyner.com', + 'https://qa.finishlinebyner.com' + ], methods: 'GET, POST, DELETE', credentials: true, preflightContinue: true, @@ -64,9 +51,6 @@ const options: cors.CorsOptions = { // so we can listen to slack messages // NOTE: must be done before using json app.use('/slack', slackEvents.requestListener()); -app.get('/health', (_req, res) => { - res.status(200).json({ status: 'healthy' }); -}); // so that we can use cookies and json app.use(cookieParser()); diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index a960c28097..8c9852162c 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -10,7 +10,6 @@ generator client { provider = "prisma-client-js" previewFeatures = ["relationJoins"] engineType = "library" - binaryTargets = ["native", "linux-arm64-openssl-1.1.x"] } enum CR_Type { diff --git a/src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementProductTable.tsx b/src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementProductTable.tsx index eea5de3e67..ed4f1a179a 100644 --- a/src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementProductTable.tsx +++ b/src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementProductTable.tsx @@ -86,7 +86,6 @@ const ReimbursementProductTable: React.FC = ({ cost: number; index: number; id?: string; - reason: WbsNumber | OtherProductReason; }[] >(); @@ -106,9 +105,9 @@ const ReimbursementProductTable: React.FC = ({ const productReason = hasWbsNum ? wbsPipe(product.reason as WbsNumber) : (product.reason as OtherProductReason).name; if (uniqueWbsElementsWithProducts.has(productReason)) { const products = uniqueWbsElementsWithProducts.get(productReason); - products?.push({ ...product, index, id: product.id, reason: product.reason }); + products?.push({ ...product, index, id: product.id }); } else { - uniqueWbsElementsWithProducts.set(productReason, [{ ...product, index, id: product.id, reason: product.reason }]); + uniqueWbsElementsWithProducts.set(productReason, [{ ...product, index, id: product.id }]); } }); @@ -706,15 +705,12 @@ const ReimbursementProductTable: React.FC = ({ /> } onClick={(e) => { - const existingProducts = uniqueWbsElementsWithProducts.get(key); - if (existingProducts && existingProducts.length > 0) { - appendProduct({ - reason: existingProducts[0].reason, - name: '', - cost: 0, - refundSources: [] - }); - } + appendProduct({ + reason: key.includes('.') ? validateWBS(key) : ({ name: key } as OtherProductReason), + name: '', + cost: 0, + refundSources: [] + }); e.currentTarget.blur(); }} > diff --git a/src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementRequestForm.tsx b/src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementRequestForm.tsx index a97574dda2..724e4445c9 100644 --- a/src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementRequestForm.tsx +++ b/src/frontend/src/pages/FinancePage/ReimbursementRequestForm/ReimbursementRequestForm.tsx @@ -99,7 +99,6 @@ const schema = yup.object().shape({ .of( yup.object().shape({ name: yup.string().required('Description is required'), - reason: yup.mixed().required(), refundSources: yup.array().of( yup.object({ amount: yup diff --git a/src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/MaterialForm/MaterialFormView.tsx b/src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/MaterialForm/MaterialFormView.tsx index ae5753b9f0..c9d5ba681e 100644 --- a/src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/MaterialForm/MaterialFormView.tsx +++ b/src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/MaterialForm/MaterialFormView.tsx @@ -475,7 +475,7 @@ const MaterialFormView: React.FC = ({ displayEmpty: true, renderValue: (selected) => selected ? ( - assemblies.find((a) => a.assemblyId === selected)?.name + assemblies.find((a) => a.assemblyId === selected)?.assemblyId ) : ( Enter Assembly Details From 019f50e7104715c2fe3f7ffeac72e801a440c852 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 8 Dec 2025 21:10:14 -0500 Subject: [PATCH 299/477] seed data test --- src/backend/src/prisma/seed.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 4f89b4a76f..6a82282ebe 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3290,6 +3290,35 @@ const performSeed: () => Promise = async () => { undefined ); + await CalendarService.createEvent( + thomasEmrax, + 'Weekly Team Sync 2', + meetingEventType.eventTypeId, + ner, + [], + [], + [justiceLeague.teamId], + [], + [], + [], + [], + [ + { + days: [DayOfWeek.MONDAY], + startTime: new Date('2025-10-21T10:00:00.000Z'), + endTime: new Date('2025-10-21T11:00:00.000Z'), + recurrenceNumber: 1, + initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), + allDay: false + } + ], + mechanical.teamTypeId, + undefined, + 'Conference Room A', + 'https://zoom.us/j/123456789', + undefined + ); + await CalendarService.createEvent( thomasEmrax, 'Impact Attenuator Design Review', From 9587a95d69c5ab60b548addae3d02a1038e27558 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 8 Dec 2025 22:04:06 -0500 Subject: [PATCH 300/477] updates --- .../src/controllers/calendar.controllers.ts | 11 + .../20251101233144_calendar/migration.sql | 703 ------------------ .../20251209025316_calendar/migration.sql | 461 ++++++++++++ src/backend/src/prisma/schema.prisma | 8 +- src/backend/src/routes/calendar.routes.ts | 2 + src/backend/src/services/calendar.services.ts | 41 +- .../src/transformers/calendar.transformer.ts | 21 +- .../pages/NewCalendarPage/YourEventsPage.tsx | 21 +- .../test-data/design-reviews.stub.ts | 6 +- src/shared/src/types/calendar-types.ts | 8 +- 10 files changed, 560 insertions(+), 722 deletions(-) delete mode 100644 src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql create mode 100644 src/backend/src/prisma/migrations/20251209025316_calendar/migration.sql diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 51258df66a..1e44160034 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -362,6 +362,17 @@ export default class CalendarController { } } + static async denyEvent(req: Request, res: Response, next: NextFunction) { + try { + const { eventId } = req.params; + + const event = await CalendarService.approveEvent(req.currentUser, eventId, req.organization); + res.status(200).json(event); + } catch (error: unknown) { + next(error); + } + } + // Mark the current user as confirmed for the given event static async markUserConfirmed(req: Request, res: Response, next: NextFunction) { try { diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql deleted file mode 100644 index a4f2bcf242..0000000000 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ /dev/null @@ -1,703 +0,0 @@ --- CreateEnum -CREATE TYPE "public"."DayOfWeek" AS ENUM ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'); - --- CreateTable -CREATE TABLE "public"."Shop" ( - "shopId" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "description" TEXT NOT NULL, - "organizationId" TEXT NOT NULL, - - CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId") -); - --- CreateTable -CREATE TABLE "public"."Machinery" ( - "machineryId" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "organizationId" TEXT NOT NULL, - - CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId") -); - --- CreateTable -CREATE TABLE "public"."Shop_Machinery" ( - "shopMachineryId" TEXT NOT NULL, - "shopId" TEXT NOT NULL, - "machineryId" TEXT NOT NULL, - "quantity" INTEGER NOT NULL DEFAULT 1, - - CONSTRAINT "Shop_Machinery_pkey" PRIMARY KEY ("shopMachineryId") -); - --- CreateTable -CREATE TABLE "public"."Schedule_Slot" ( - "scheduleSlotId" TEXT NOT NULL, - "days" "public"."DayOfWeek"[], - "startTime" TIMESTAMP(3), - "endTime" TIMESTAMP(3), - "recurrenceNumber" INTEGER NOT NULL, - "initialDateScheduled" DATE NOT NULL, - "endDate" DATE NOT NULL, - "allDay" BOOLEAN NOT NULL DEFAULT false, - - CONSTRAINT "Schedule_Slot_pkey" PRIMARY KEY ("scheduleSlotId") -); - --- CreateTable -CREATE TABLE "public"."Event" ( - "eventId" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "title" TEXT NOT NULL, - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "eventTypeId" TEXT NOT NULL, - "approved" BOOLEAN NOT NULL DEFAULT false, - "approvalRequiredFromUserId" TEXT, - "location" TEXT, - "zoomLink" TEXT, - "documentIds" TEXT[], - "questionDocument" TEXT, - "description" TEXT, - "teamTypeId" TEXT, - - CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId") -); - --- CreateTable -CREATE TABLE "public"."Calendar" ( - "calendarId" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "description" TEXT NOT NULL, - "colorHexCode" TEXT NOT NULL, - "organizationId" TEXT NOT NULL, - - CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId") -); - --- CreateTable -CREATE TABLE "public"."Event_Type" ( - "eventTypeId" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "optionalMembers" BOOLEAN NOT NULL DEFAULT FALSE, - "requiredMembers" BOOLEAN NOT NULL DEFAULT FALSE, - "teams" BOOLEAN NOT NULL DEFAULT FALSE, - "teamType" BOOLEAN NOT NULL DEFAULT FALSE, - "location" BOOLEAN NOT NULL DEFAULT FALSE, - "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, - "shop" BOOLEAN NOT NULL DEFAULT FALSE, - "machinery" BOOLEAN NOT NULL DEFAULT FALSE, - "workPackage" BOOLEAN NOT NULL DEFAULT FALSE, - "questionDocument" BOOLEAN NOT NULL DEFAULT FALSE, - "documents" BOOLEAN NOT NULL DEFAULT FALSE, - "description" BOOLEAN NOT NULL DEFAULT FALSE, - "onlyHeadsOrAboveForEventCreation" BOOLEAN NOT NULL DEFAULT FALSE, - "requiresConfirmation" BOOLEAN NOT NULL DEFAULT FALSE, - "sendSlackNotifications" BOOLEAN NOT NULL DEFAULT FALSE, - "organizationId" TEXT NOT NULL, - - CONSTRAINT "Event_Type_pkey" PRIMARY KEY ("eventTypeId") -); - --- CreateEnum -CREATE TYPE "public"."Event_Status" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'SCHEDULED', 'DONE'); - --- AlterTable -ALTER TABLE "public"."Event" ADD COLUMN "status" "public"."Event_Status" NOT NULL; - --- CreateTable -CREATE TABLE "public"."_EventToSchedule_Slot" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToSchedule_Slot_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_affiliatedTeam" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_affiliatedTeam_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_EventToShop" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToShop_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_EventToMachinery" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToMachinery_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_EventToWork_Package" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToWork_Package_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_CalendarToEvent_Type" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_CalendarToEvent_Type_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_requiredEventAttendee" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_requiredEventAttendee_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_optionalEventAttendee" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_optionalEventAttendee_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_confirmedEventAttendee" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_confirmedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "public"."_deniedEventAttendee" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_deniedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateIndex -CREATE INDEX "_requiredEventAttendee_B_index" ON "public"."_requiredEventAttendee"("B"); - --- CreateIndex -CREATE INDEX "_optionalEventAttendee_B_index" ON "public"."_optionalEventAttendee"("B"); - --- CreateIndex -CREATE INDEX "_confirmedEventAttendee_B_index" ON "public"."_confirmedEventAttendee"("B"); - --- CreateIndex -CREATE INDEX "_deniedEventAttendee_B_index" ON "public"."_deniedEventAttendee"("B"); - --- AddForeignKey -ALTER TABLE "public"."_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - --- CreateIndex -CREATE INDEX "Shop_Machinery_machineryId_idx" ON "public"."Shop_Machinery"("machineryId"); - --- CreateIndex -CREATE UNIQUE INDEX "Shop_Machinery_shopId_machineryId_key" ON "public"."Shop_Machinery"("shopId", "machineryId"); - --- CreateIndex -CREATE INDEX "Schedule_Slot_initialDateScheduled_endDate_idx" ON "public"."Schedule_Slot"("initialDateScheduled", "endDate"); - --- CreateIndex -CREATE INDEX "_EventToSchedule_Slot_B_index" ON "public"."_EventToSchedule_Slot"("B"); - --- CreateIndex -CREATE INDEX "_affiliatedTeam_B_index" ON "public"."_affiliatedTeam"("B"); - --- CreateIndex -CREATE INDEX "_EventToShop_B_index" ON "public"."_EventToShop"("B"); - --- CreateIndex -CREATE INDEX "_EventToMachinery_B_index" ON "public"."_EventToMachinery"("B"); - --- CreateIndex -CREATE INDEX "_EventToWork_Package_B_index" ON "public"."_EventToWork_Package"("B"); - --- CreateIndex -CREATE INDEX "_CalendarToEvent_Type_B_index" ON "public"."_CalendarToEvent_Type"("B"); - --- AddForeignKey -ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Shop_Machinery" ADD CONSTRAINT "Shop_Machinery_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("shopId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Shop_Machinery" ADD CONSTRAINT "Shop_Machinery_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("machineryId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "public"."Event_Type"("eventTypeId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_approvalRequiredFromUserId_fkey" FOREIGN KEY ("approvalRequiredFromUserId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_teamTypeId_fkey" FOREIGN KEY ("teamTypeId") REFERENCES "public"."Team_Type"("teamTypeId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event_Type" ADD CONSTRAINT "Event_Type_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event_Type" ADD CONSTRAINT "Event_Type_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."Event_Type" ADD CONSTRAINT "Event_Type_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Schedule_Slot"("scheduleSlotId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Team"("teamId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToShop" ADD CONSTRAINT "_EventToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToShop" ADD CONSTRAINT "_EventToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Work_Package"("workPackageId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Calendar"("calendarId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Event_Type"("eventTypeId") ON DELETE CASCADE ON UPDATE CASCADE; - --- Create Event_Types for Design Review (one per organization) -INSERT INTO "public"."Event_Type" ( - "eventTypeId", - "name", - "dateCreated", - "userCreatedId", - "requiredMembers", - "optionalMembers", - "teams", - "teamType", - "location", - "zoomLink", - "shop", - "machinery", - "workPackage", - "questionDocument", - "documents", - "description", - "onlyHeadsOrAboveForEventCreation", - "requiresConfirmation", - "organizationId" -) -SELECT DISTINCT ON (org."organizationId") - gen_random_uuid(), - 'Design Review', - NOW(), - org."userCreatedId", - true, -- requiredMembers - true, -- optionalMembers - false, -- teams - true, -- team type - true, -- location - true, -- zoomLink - false, -- shop - false, -- machinery - true, -- workPackage (based on wbsElementId) - true, -- questionDocument (docTemplateLink) - true, -- documents - false, -- description - true, -- onlyHeadsOrAboveForEventCreation - true, -- requiresConfirmation - org."organizationId" -FROM "public"."Organization" org -WHERE EXISTS ( - SELECT 1 FROM "public"."Design_Review" dr - JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId" - WHERE w."organizationId" = org."organizationId" - AND dr."dateDeleted" IS NULL -); - --- Create Event_Types for Meeting (one per organization) -INSERT INTO "public"."Event_Type" ( - "eventTypeId", - "name", - "dateCreated", - "userCreatedId", - "requiredMembers", - "optionalMembers", - "teams", - "teamType", - "location", - "zoomLink", - "shop", - "machinery", - "workPackage", - "questionDocument", - "documents", - "description", - "onlyHeadsOrAboveForEventCreation", - "requiresConfirmation", - "organizationId" -) -SELECT DISTINCT ON (org."organizationId") - gen_random_uuid(), - 'Meeting', - NOW(), - org."userCreatedId", - false, -- requiredMembers - false, -- optionalMembers - true, -- teams - false, -- team type - false, -- location - false, -- zoomLink - false, -- shop - false, -- machinery - false, -- workPackage - false, -- questionDocument - false, -- documents - false, -- description - false, -- onlyHeadsOrAboveForEventCreation - false, -- requiresConfirmation - org."organizationId" -FROM "public"."Organization" org -WHERE EXISTS ( - SELECT 1 FROM "public"."Meeting" m - JOIN "public"."Team" t ON m."teamId" = t."teamId" - WHERE t."organizationId" = org."organizationId" -); - --- Migrate Design_Review records to Event table -INSERT INTO "public"."Event" ( - "eventId", - "dateCreated", - "dateDeleted", - "title", - "userCreatedId", - "userDeletedId", - "eventTypeId", - "approved", - "approvalRequiredFromUserId", - "location", - "zoomLink", - "documentIds", - "questionDocument", - "description", - "status", - "teamTypeId" -) -SELECT - dr."designReviewId", - dr."dateCreated", - dr."dateDeleted", - 'Design Review - ' || w."name", -- Generate title from WBS element name - dr."userCreatedId", - dr."userDeletedId", - (SELECT et."eventTypeId" - FROM "public"."Event_Type" et - WHERE et."name" = 'Design Review' - AND et."organizationId" = w."organizationId" - LIMIT 1), - CASE WHEN dr."status" IN ('CONFIRMED', 'SCHEDULED', 'DONE') THEN true ELSE false END, - NULL, -- approvalRequiredFromUserId (not in Design_Review) - dr."location", - dr."zoomLink", - CASE WHEN dr."docTemplateLink" IS NOT NULL THEN ARRAY[dr."docTemplateLink"] ELSE ARRAY[]::TEXT[] END, - dr."docTemplateLink", -- questionDocument uses docTemplateLink - NULL, -- description (not in Design_Review) - dr."status"::"text"::"public"."Event_Status", - dr."teamTypeId" -FROM "public"."Design_Review" dr -JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId"; - --- Create Schedule_Slot records for Design Reviews --- This creates one slot per time per design review --- Design Reviews are non-recurring, so endDate = dateScheduled -CREATE TEMP TABLE temp_dr_schedule_slots AS -SELECT - dr."designReviewId" as event_id, - gen_random_uuid() as slot_id, - ARRAY[CASE EXTRACT(DOW FROM dr."dateScheduled") - WHEN 0 THEN 'SUNDAY'::public."DayOfWeek" - WHEN 1 THEN 'MONDAY'::public."DayOfWeek" - WHEN 2 THEN 'TUESDAY'::public."DayOfWeek" - WHEN 3 THEN 'WEDNESDAY'::public."DayOfWeek" - WHEN 4 THEN 'THURSDAY'::public."DayOfWeek" - WHEN 5 THEN 'FRIDAY'::public."DayOfWeek" - WHEN 6 THEN 'SATURDAY'::public."DayOfWeek" - END] as days, - dr."dateScheduled" + ((10 + time_slot) * INTERVAL '1 hour') as start_time, - dr."dateScheduled" + ((11 + time_slot) * INTERVAL '1 hour') as end_time, - 0 as recurrence_number, - dr."initialDateScheduled" as initial_date, - dr."dateScheduled" as end_date, - false as all_day -FROM "public"."Design_Review" dr -CROSS JOIN LATERAL unnest(dr."meetingTimes") AS time_slot; - --- Insert schedule slots from temp table -INSERT INTO "public"."Schedule_Slot" ( - "scheduleSlotId", - "days", - "startTime", - "endTime", - "recurrenceNumber", - "initialDateScheduled", - "endDate", - "allDay" -) -SELECT - slot_id, - days, - start_time, - end_time, - recurrence_number, - initial_date, - end_date, - all_day -FROM temp_dr_schedule_slots; - --- Link Schedule_Slots to Events using the temp table -INSERT INTO "public"."_EventToSchedule_Slot" ("A", "B") -SELECT event_id, slot_id -FROM temp_dr_schedule_slots; - --- Drop temp table -DROP TABLE temp_dr_schedule_slots; - --- Migrate Design Review member relationships -INSERT INTO "public"."_requiredEventAttendee" ("A", "B") -SELECT dr."designReviewId", ra."B" -FROM "public"."Design_Review" dr -JOIN "public"."_requiredAttendee" ra ON dr."designReviewId" = ra."A"; - -INSERT INTO "public"."_optionalEventAttendee" ("A", "B") -SELECT dr."designReviewId", oa."B" -FROM "public"."Design_Review" dr -JOIN "public"."_optionalAttendee" oa ON dr."designReviewId" = oa."A"; - -INSERT INTO "public"."_confirmedEventAttendee" ("A", "B") -SELECT dr."designReviewId", ca."B" -FROM "public"."Design_Review" dr -JOIN "public"."_confirmedAttendee" ca ON dr."designReviewId" = ca."A"; - -INSERT INTO "public"."_deniedEventAttendee" ("A", "B") -SELECT dr."designReviewId", da."B" -FROM "public"."Design_Review" dr -JOIN "public"."_deniedAttendee" da ON dr."designReviewId" = da."A"; - --- Link Design Reviews to Work Packages (via wbsElementId) -INSERT INTO "public"."_EventToWork_Package" ("A", "B") -SELECT dr."designReviewId", wp."workPackageId" -FROM "public"."Design_Review" dr -JOIN "public"."Work_Package" wp ON dr."wbsElementId" = wp."wbsElementId"; - --- Migrate Meeting records to Event table -INSERT INTO "public"."Event" ( - "eventId", - "dateCreated", - "title", - "userCreatedId", - "eventTypeId", - "approved", - "status" -) -SELECT - m."meetingId", - NOW(), - m."title", - t."headId", -- Use the team head as the creator - (SELECT et."eventTypeId" - FROM "public"."Event_Type" et - WHERE et."name" = 'Meeting' - AND et."organizationId" = t."organizationId" - LIMIT 1), - false, -- Meetings aren't pre-approved - 'UNCONFIRMED'::public."Event_Status" -FROM "public"."Meeting" m -JOIN "public"."Team" t ON m."teamId" = t."teamId"; - --- Create Schedule_Slot records for Meetings --- This creates one slot per time per meeting -CREATE TEMP TABLE temp_meeting_schedule_slots AS -SELECT - m."meetingId" as event_id, - gen_random_uuid() as slot_id, - ARRAY[CASE EXTRACT(DOW FROM m."dateSet") - WHEN 0 THEN 'SUNDAY'::public."DayOfWeek" - WHEN 1 THEN 'MONDAY'::public."DayOfWeek" - WHEN 2 THEN 'TUESDAY'::public."DayOfWeek" - WHEN 3 THEN 'WEDNESDAY'::public."DayOfWeek" - WHEN 4 THEN 'THURSDAY'::public."DayOfWeek" - WHEN 5 THEN 'FRIDAY'::public."DayOfWeek" - WHEN 6 THEN 'SATURDAY'::public."DayOfWeek" - END] as days, - m."dateSet" + ((10 + time_slot) * INTERVAL '1 hour') as start_time, - m."dateSet" + ((11 + time_slot) * INTERVAL '1 hour') as end_time, - CASE WHEN m."recurringInterval" > 0 THEN m."recurringInterval" ELSE 0 END as recurrence_number, - m."dateSet"::DATE as initial_date, - CASE - WHEN m."recurringInterval" > 0 THEN (m."dateSet" + INTERVAL '1 year')::DATE - ELSE m."dateSet"::DATE - END as end_date, - false as all_day -FROM "public"."Meeting" m -CROSS JOIN LATERAL unnest(m."meetingTimes") AS time_slot; - --- Insert schedule slots from temp table -INSERT INTO "public"."Schedule_Slot" ( - "scheduleSlotId", - "days", - "startTime", - "endTime", - "recurrenceNumber", - "initialDateScheduled", - "endDate", - "allDay" -) -SELECT - slot_id, - days, - start_time, - end_time, - recurrence_number, - initial_date, - end_date, - all_day -FROM temp_meeting_schedule_slots; - --- Link Schedule_Slots to Events using the temp table -INSERT INTO "public"."_EventToSchedule_Slot" ("A", "B") -SELECT event_id, slot_id -FROM temp_meeting_schedule_slots; - --- Drop temp table -DROP TABLE temp_meeting_schedule_slots; - --- Link Meetings to Teams -INSERT INTO "public"."_affiliatedTeam" ("A", "B") -SELECT m."meetingId", m."teamId" -FROM "public"."Meeting" m; - -ALTER TABLE "Message_Info" ADD COLUMN "eventId" TEXT; - -UPDATE "Message_Info" -SET "eventId" = "designReviewId" -WHERE "designReviewId" IS NOT NULL; - -DROP INDEX IF EXISTS "Message_Info_designReviewId_idx"; - -ALTER TABLE "Message_Info" DROP COLUMN IF EXISTS "designReviewId"; - -CREATE INDEX IF NOT EXISTS "Message_Info_eventId_idx" ON "Message_Info"("eventId"); - -ALTER TABLE "Message_Info" -ADD CONSTRAINT "Message_Info_eventId_fkey" -FOREIGN KEY ("eventId") -REFERENCES "Event"("eventId") -ON DELETE SET NULL -ON UPDATE CASCADE; - --- Drop old relation tables for Design_Review -DROP TABLE "public"."_requiredAttendee" CASCADE; -DROP TABLE "public"."_optionalAttendee" CASCADE; -DROP TABLE "public"."_confirmedAttendee" CASCADE; -DROP TABLE "public"."_deniedAttendee" CASCADE; -DROP TABLE "public"."_userAttended" CASCADE; - --- Drop the old Meeting and Design_Review tables -DROP TABLE "public"."Meeting" CASCADE; -DROP TABLE "public"."Design_Review" CASCADE; - --- DropEnum -DROP TYPE "public"."Design_Review_Status"; \ No newline at end of file diff --git a/src/backend/src/prisma/migrations/20251209025316_calendar/migration.sql b/src/backend/src/prisma/migrations/20251209025316_calendar/migration.sql new file mode 100644 index 0000000000..b4ac2c71ef --- /dev/null +++ b/src/backend/src/prisma/migrations/20251209025316_calendar/migration.sql @@ -0,0 +1,461 @@ +/* + Warnings: + + - You are about to drop the column `designReviewId` on the `Message_Info` table. All the data in the column will be lost. + - You are about to drop the `Design_Review` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `Meeting` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `_confirmedAttendee` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `_deniedAttendee` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `_optionalAttendee` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `_requiredAttendee` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `_userAttended` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- CreateEnum +CREATE TYPE "Event_Status" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'SCHEDULED', 'DONE'); + +-- CreateEnum +CREATE TYPE "DayOfWeek" AS ENUM ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'); + +-- CreateEnum +CREATE TYPE "ConflictStatus" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'DENIED'); + +-- DropForeignKey +ALTER TABLE "public"."Design_Review" DROP CONSTRAINT "Design_Review_teamTypeId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Design_Review" DROP CONSTRAINT "Design_Review_userCreatedId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Design_Review" DROP CONSTRAINT "Design_Review_userDeletedId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Design_Review" DROP CONSTRAINT "Design_Review_wbsElementId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Meeting" DROP CONSTRAINT "Meeting_teamId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."Message_Info" DROP CONSTRAINT "Message_Info_designReviewId_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_confirmedAttendee" DROP CONSTRAINT "_confirmedAttendee_A_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_confirmedAttendee" DROP CONSTRAINT "_confirmedAttendee_B_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_deniedAttendee" DROP CONSTRAINT "_deniedAttendee_A_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_deniedAttendee" DROP CONSTRAINT "_deniedAttendee_B_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_optionalAttendee" DROP CONSTRAINT "_optionalAttendee_A_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_optionalAttendee" DROP CONSTRAINT "_optionalAttendee_B_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_requiredAttendee" DROP CONSTRAINT "_requiredAttendee_A_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_requiredAttendee" DROP CONSTRAINT "_requiredAttendee_B_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_userAttended" DROP CONSTRAINT "_userAttended_A_fkey"; + +-- DropForeignKey +ALTER TABLE "public"."_userAttended" DROP CONSTRAINT "_userAttended_B_fkey"; + +-- DropIndex +DROP INDEX "public"."Message_Info_designReviewId_idx"; + +-- AlterTable +ALTER TABLE "Message_Info" DROP COLUMN "designReviewId", +ADD COLUMN "eventId" TEXT; + +-- DropTable +DROP TABLE "public"."Design_Review"; + +-- DropTable +DROP TABLE "public"."Meeting"; + +-- DropTable +DROP TABLE "public"."_confirmedAttendee"; + +-- DropTable +DROP TABLE "public"."_deniedAttendee"; + +-- DropTable +DROP TABLE "public"."_optionalAttendee"; + +-- DropTable +DROP TABLE "public"."_requiredAttendee"; + +-- DropTable +DROP TABLE "public"."_userAttended"; + +-- DropEnum +DROP TYPE "public"."Design_Review_Status"; + +-- CreateTable +CREATE TABLE "Shop" ( + "shopId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "description" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId") +); + +-- CreateTable +CREATE TABLE "Machinery" ( + "machineryId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId") +); + +-- CreateTable +CREATE TABLE "Shop_Machinery" ( + "shopMachineryId" TEXT NOT NULL, + "shopId" TEXT NOT NULL, + "machineryId" TEXT NOT NULL, + "quantity" INTEGER NOT NULL DEFAULT 1, + + CONSTRAINT "Shop_Machinery_pkey" PRIMARY KEY ("shopMachineryId") +); + +-- CreateTable +CREATE TABLE "Schedule_Slot" ( + "scheduleSlotId" TEXT NOT NULL, + "days" "DayOfWeek"[], + "startTime" TIMESTAMP(3), + "endTime" TIMESTAMP(3), + "recurrenceNumber" INTEGER NOT NULL, + "initialDateScheduled" DATE NOT NULL, + "endDate" DATE NOT NULL, + "allDay" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "Schedule_Slot_pkey" PRIMARY KEY ("scheduleSlotId") +); + +-- CreateTable +CREATE TABLE "Event" ( + "eventId" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "title" TEXT NOT NULL, + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "eventTypeId" TEXT NOT NULL, + "approved" "ConflictStatus", + "approvalRequiredFromUserId" TEXT, + "teamTypeId" TEXT, + "location" TEXT, + "zoomLink" TEXT, + "documentIds" TEXT[], + "status" "Event_Status" NOT NULL, + "questionDocument" TEXT, + "description" TEXT, + + CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId") +); + +-- CreateTable +CREATE TABLE "Calendar" ( + "calendarId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "description" TEXT NOT NULL, + "colorHexCode" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId") +); + +-- CreateTable +CREATE TABLE "Event_Type" ( + "eventTypeId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "requiredMembers" BOOLEAN NOT NULL, + "optionalMembers" BOOLEAN NOT NULL, + "teams" BOOLEAN NOT NULL, + "teamType" BOOLEAN NOT NULL, + "location" BOOLEAN NOT NULL, + "zoomLink" BOOLEAN NOT NULL, + "shop" BOOLEAN NOT NULL, + "machinery" BOOLEAN NOT NULL, + "workPackage" BOOLEAN NOT NULL, + "questionDocument" BOOLEAN NOT NULL, + "documents" BOOLEAN NOT NULL, + "description" BOOLEAN NOT NULL, + "onlyHeadsOrAboveForEventCreation" BOOLEAN NOT NULL, + "requiresConfirmation" BOOLEAN NOT NULL, + "sendSlackNotifications" BOOLEAN NOT NULL, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Event_Type_pkey" PRIMARY KEY ("eventTypeId") +); + +-- CreateTable +CREATE TABLE "_EventToSchedule_Slot" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToSchedule_Slot_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_requiredEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_requiredEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_optionalEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_optionalEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_confirmedEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_confirmedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_deniedEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_deniedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_affiliatedTeam" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_affiliatedTeam_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_EventToShop" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToShop_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_EventToMachinery" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToMachinery_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_EventToWork_Package" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToWork_Package_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_CalendarToEvent_Type" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_CalendarToEvent_Type_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Shop_name_key" ON "Shop"("name"); + +-- CreateIndex +CREATE INDEX "Shop_Machinery_machineryId_idx" ON "Shop_Machinery"("machineryId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Shop_Machinery_shopId_machineryId_key" ON "Shop_Machinery"("shopId", "machineryId"); + +-- CreateIndex +CREATE INDEX "Schedule_Slot_initialDateScheduled_endDate_idx" ON "Schedule_Slot"("initialDateScheduled", "endDate"); + +-- CreateIndex +CREATE INDEX "_EventToSchedule_Slot_B_index" ON "_EventToSchedule_Slot"("B"); + +-- CreateIndex +CREATE INDEX "_requiredEventAttendee_B_index" ON "_requiredEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_optionalEventAttendee_B_index" ON "_optionalEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_confirmedEventAttendee_B_index" ON "_confirmedEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_deniedEventAttendee_B_index" ON "_deniedEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_affiliatedTeam_B_index" ON "_affiliatedTeam"("B"); + +-- CreateIndex +CREATE INDEX "_EventToShop_B_index" ON "_EventToShop"("B"); + +-- CreateIndex +CREATE INDEX "_EventToMachinery_B_index" ON "_EventToMachinery"("B"); + +-- CreateIndex +CREATE INDEX "_EventToWork_Package_B_index" ON "_EventToWork_Package"("B"); + +-- CreateIndex +CREATE INDEX "_CalendarToEvent_Type_B_index" ON "_CalendarToEvent_Type"("B"); + +-- CreateIndex +CREATE INDEX "Message_Info_eventId_idx" ON "Message_Info"("eventId"); + +-- AddForeignKey +ALTER TABLE "Message_Info" ADD CONSTRAINT "Message_Info_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Shop" ADD CONSTRAINT "Shop_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Shop" ADD CONSTRAINT "Shop_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Shop_Machinery" ADD CONSTRAINT "Shop_Machinery_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "Shop"("shopId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Shop_Machinery" ADD CONSTRAINT "Shop_Machinery_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "Machinery"("machineryId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Event" ADD CONSTRAINT "Event_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Event" ADD CONSTRAINT "Event_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "Event_Type"("eventTypeId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Event" ADD CONSTRAINT "Event_approvalRequiredFromUserId_fkey" FOREIGN KEY ("approvalRequiredFromUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Event" ADD CONSTRAINT "Event_teamTypeId_fkey" FOREIGN KEY ("teamTypeId") REFERENCES "Team_Type"("teamTypeId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Event_Type" ADD CONSTRAINT "Event_Type_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Event_Type" ADD CONSTRAINT "Event_Type_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Event_Type" ADD CONSTRAINT "Event_Type_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_B_fkey" FOREIGN KEY ("B") REFERENCES "Schedule_Slot"("scheduleSlotId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_B_fkey" FOREIGN KEY ("B") REFERENCES "Team"("teamId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_EventToShop" ADD CONSTRAINT "_EventToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_EventToShop" ADD CONSTRAINT "_EventToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_B_fkey" FOREIGN KEY ("B") REFERENCES "Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_B_fkey" FOREIGN KEY ("B") REFERENCES "Work_Package"("workPackageId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_A_fkey" FOREIGN KEY ("A") REFERENCES "Calendar"("calendarId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_B_fkey" FOREIGN KEY ("B") REFERENCES "Event_Type"("eventTypeId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 8c9852162c..2ff8721ec3 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1029,6 +1029,12 @@ model Schedule_Slot { @@index([initialDateScheduled, endDate]) } +enum ConflictStatus { + UNCONFIRMED + CONFIRMED + DENIED +} + model Event { eventId String @id @default(uuid()) dateCreated DateTime @default(now()) @@ -1040,7 +1046,7 @@ model Event { userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventDeleter") eventTypeId String eventType Event_Type @relation(fields: [eventTypeId], references: [eventTypeId]) - approved Boolean @default(false) + approved ConflictStatus? // when approval is false, approved by holds who needs to approve the event // when approval is true, approved by holds who actually approved the event approvalRequiredFromUserId String? diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 0dd576674f..3bf5603acc 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -134,6 +134,8 @@ calendarRouter.post( calendarRouter.post('/event/:eventId/approve', CalendarController.approveEvent); +calendarRouter.post('/event/:eventId/deny', CalendarController.approveEvent); + calendarRouter.post( '/event/:eventId/confirm-schedule', body('availability').isArray(), diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 4c25c80d7d..e26a58411e 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,6 +1,6 @@ import { calendarTransformer, eventTransformer, machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; -import { Event_Status, Organization } from '@prisma/client'; +import { ConflictStatus, Event_Status, Organization } from '@prisma/client'; import { isAdmin, isHead, @@ -460,7 +460,7 @@ export default class CalendarService { })) }, status: foundEventType.requiresConfirmation ? Event_Status.UNCONFIRMED : Event_Status.CONFIRMED, - approved: !hasConflict, + approved: hasConflict ? ConflictStatus.UNCONFIRMED : null, approvalRequiredFromUserId: hasConflict ? approverUserId : null, location, zoomLink, @@ -884,7 +884,8 @@ export default class CalendarService { }, // If schedule/location changed and there's a conflict, set approved=false and track who needs to approve // Otherwise keep existing approval state - approved: scheduleChanged || locationChanged ? !hasConflict : foundEvent.approved, + approved: + scheduleChanged || locationChanged ? (hasConflict ? ConflictStatus.UNCONFIRMED : null) : foundEvent.approved, approvalRequiredFromUserId: scheduleChanged || locationChanged ? hasConflict @@ -940,13 +941,13 @@ export default class CalendarService { event.approvalRequiredFromUserId === submitter.userId; if (!hasPermission) { - throw new AccessDeniedException('Only admins or heads or the owner of the conflicting event can this approve event!'); + throw new AccessDeniedException('Only admins or heads or the owner of the conflicting event can approve this event!'); } const approvedEvent = await prisma.event.update({ where: { eventId }, data: { - approved: true, + approved: ConflictStatus.CONFIRMED, approvalRequiredFromUserId: submitter.userId }, ...getEventQueryArgs(organization.organizationId) @@ -955,6 +956,34 @@ export default class CalendarService { return eventTransformer(approvedEvent); } + static async denyEvent(submitter: User, eventId: string, organization: Organization): Promise { + const event = await prisma.event.findUnique({ + where: { eventId } + }); + + if (!event) throw new NotFoundException('Event', eventId); + if (event.dateDeleted) throw new DeletedException('Event', eventId); + + const hasPermission = + (await userHasPermission(submitter.userId, organization.organizationId, isHead)) || + event.approvalRequiredFromUserId === submitter.userId; + + if (!hasPermission) { + throw new AccessDeniedException('Only admins or heads or the owner of the conflicting event can deny this event!'); + } + + const deniedEvent = await prisma.event.update({ + where: { eventId }, + data: { + approved: ConflictStatus.DENIED, + approvalRequiredFromUserId: submitter.userId + }, + ...getEventQueryArgs(organization.organizationId) + }); + + return eventTransformer(deniedEvent); + } + /** * Edits an event by confirming a given user's availability and also updating their schedule settings with the given availability * @param submitter the member that is being confirmed @@ -2068,7 +2097,7 @@ export default class CalendarService { eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, teams: teamIds?.length ? { some: { teamId: { in: teamIds } } } : undefined, - approved: approvalStatus !== undefined ? { equals: approvalStatus } : undefined, + approved: undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...memberOrCreator, ...fromCalendar diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 1c93277bf1..e865b08e56 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -1,4 +1,9 @@ -import { Prisma, DayOfWeek as PrismaDayOfWeek, Event_Status as PrismaEventStatus } from '@prisma/client'; +import { + Prisma, + DayOfWeek as PrismaDayOfWeek, + Event_Status as PrismaEventStatus, + ConflictStatus as PrismaConflictStatus +} from '@prisma/client'; import { Machinery, Shop, @@ -9,7 +14,8 @@ import { ScheduleSlot, EventStatus, EventPreview, - DayOfWeek + DayOfWeek, + ConflictStatus } from 'shared'; import { MachineryQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { userTransformer, userWithScheduleSettingsTransformer } from './user.transformer'; @@ -115,7 +121,7 @@ export const eventTransformer = (event: Prisma.EventGetPayload): workPackages: event.workPackages, documentIds: event.documentIds, scheduledTimes: event.scheduledTimes.map(scheduleTimesTransformer), - approved: event.approved, + approved: event.approved ? conflictStatusTransformer(event.approved) : undefined, approvalRequiredFrom: event.approvalRequiredBy ?? undefined, location: event.location ?? undefined, zoomLink: event.zoomLink ?? undefined, @@ -152,6 +158,15 @@ export const dayOfWeekTransformer = (day: PrismaDayOfWeek): DayOfWeek => { return mapping[day]; }; +export const conflictStatusTransformer = (day: PrismaConflictStatus): ConflictStatus => { + const mapping: Record = { + CONFIRMED: ConflictStatus.CONFIRMED, + UNCONFIRMED: ConflictStatus.UNCONFIRMED, + DENIED: ConflictStatus.DENIED + }; + return mapping[day]; +}; + export const eventStatusTransformer = (status: PrismaEventStatus): EventStatus => { const mapping: Record = { UNCONFIRMED: EventStatus.UNCONFIRMED, diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 1282318f5b..296d581725 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -8,7 +8,7 @@ import TableCellHuge from './YourEventsComponents/TableCellHuge'; import { useFilterEvents } from '../../hooks/calendar.hooks'; import { useCurrentUser } from '../../hooks/users.hooks'; import { useEffect, useState } from 'react'; -import { ScheduleSlot } from 'shared'; +import { ConflictStatus, ScheduleSlot } from 'shared'; import { Event } from 'shared'; interface YourEventsHeadCells { @@ -148,7 +148,10 @@ const YourEventsPage = () => { {!timeAway.passed ? ` - In ${timeAway.months}m : ${timeAway.days}d` : '- Passed'} - {new Date(earliestSchedule.startTime).toLocaleTimeString()}{' '} + {new Date(earliestSchedule.startTime).toLocaleTimeString('en-US', { + hour: 'numeric', + minute: '2-digit' + })}{' '} {!timeAway.passed ? ` - In ${timeAway.hours}h ${timeAway.minutes}m ${timeAway.seconds}s` : '- Passed'} @@ -165,11 +168,19 @@ const YourEventsPage = () => { )} - {!event.approved - ? `${event.approvalRequiredFrom?.firstName} ${event.approvalRequiredFrom?.lastName}` + {event.approvalRequiredFrom + ? `${event.approvalRequiredFrom.firstName} ${event.approvalRequiredFrom.lastName}` : 'N/A'} - {event.approved ? 'Approved' : 'Pending'} + + {event.approved === ConflictStatus.CONFIRMED + ? 'Approved' + : event.approved === ConflictStatus.UNCONFIRMED + ? 'PENDING' + : event.approved === ConflictStatus.DENIED + ? 'DENIED' + : 'N/A'} + ); }) diff --git a/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts b/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts index 51a5ba9eb6..74daed5846 100644 --- a/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts +++ b/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts @@ -3,7 +3,7 @@ * See the LICENSE file in the repository root folder for details. */ -import { DayOfWeek, Event, EventStatus, TeamType } from 'shared'; +import { ConflictStatus, DayOfWeek, Event, EventStatus, TeamType } from 'shared'; import { exampleAdminUser, exampleAppAdminUser } from './users.stub'; export const teamType1: TeamType = { @@ -20,7 +20,7 @@ export const teamType1: TeamType = { export const exampleDesignReviewEvent1: Event = { eventId: '1', title: 'Design Review - Impact Attenuator', - approved: true, + approved: ConflictStatus.CONFIRMED, userCreated: exampleAdminUser, dateCreated: new Date('2024-03-10'), eventTypeId: 'design-review-event-type-id', @@ -96,7 +96,7 @@ export const exampleDesignReviewEvent1: Event = { export const exampleDesignReviewEvent2: Event = { eventId: '2', title: 'Design Review - Bodywork', - approved: true, + approved: ConflictStatus.CONFIRMED, userCreated: exampleAppAdminUser, dateCreated: new Date('2024-03-10'), eventTypeId: 'design-review-event-type-id', diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index b21a55dd96..fc3f4a029e 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -47,6 +47,12 @@ export enum DayOfWeek { SUNDAY = 'SUNDAY' } +export enum ConflictStatus { + UNCONFIRMED = 'UNCOMFIRMED', + CONFIRMED = 'CONFIRMED', + DENIED = 'DENIED' +} + export interface Calendar { calendarId: string; name: string; @@ -136,7 +142,7 @@ export interface Machinery { export interface Event { eventId: string; title: string; - approved: boolean; + approved?: ConflictStatus; userCreated: UserWithScheduleSettings; dateCreated: Date; eventTypeId: string; From 7268461abebbc75487a6e34a839dfcb46849d31d Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 8 Dec 2025 22:06:37 -0500 Subject: [PATCH 301/477] temp removal --- src/backend/src/controllers/calendar.controllers.ts | 2 +- src/backend/src/routes/calendar.routes.ts | 2 +- src/backend/src/services/calendar.services.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 1e44160034..021cd7cf35 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -366,7 +366,7 @@ export default class CalendarController { try { const { eventId } = req.params; - const event = await CalendarService.approveEvent(req.currentUser, eventId, req.organization); + const event = await CalendarService.denyEvent(req.currentUser, eventId, req.organization); res.status(200).json(event); } catch (error: unknown) { next(error); diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 3bf5603acc..d2aba1e229 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -134,7 +134,7 @@ calendarRouter.post( calendarRouter.post('/event/:eventId/approve', CalendarController.approveEvent); -calendarRouter.post('/event/:eventId/deny', CalendarController.approveEvent); +calendarRouter.post('/event/:eventId/deny', CalendarController.denyEvent); calendarRouter.post( '/event/:eventId/confirm-schedule', diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index e26a58411e..d71bb4b5d7 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1988,7 +1988,7 @@ export default class CalendarService { * @throws NotFoundException If the given event type Ids, member IDs, team IDs, or event IDs are not found. */ static async getFilteredEvents(filters: FilterArgs, organization: Organization): Promise { - const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvalStatus, startPeriod, endPeriod } = filters; + const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, startPeriod, endPeriod } = filters; // validate memberIds if (memberIds?.length) { From 4c4868ed1879eafce256a753a08a325ecc9c5704 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 8 Dec 2025 22:36:20 -0500 Subject: [PATCH 302/477] weather update. just kiddings its a warning tooltip --- src/backend/tests/unit/calendar.test.ts | 6 +- .../pages/NewCalendarPage/YourEventsPage.tsx | 106 ++++++++++++++++-- 2 files changed, 101 insertions(+), 11 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 2e5531cb39..82a88dc616 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -913,7 +913,7 @@ describe('Calendar Tests', () => { expect(result.scheduledTimes).toHaveLength(1); expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); expect(result.teamType).toBe(undefined); - expect(result.approved).toBe(true); + expect(result.approved).toBe(undefined); expect(result.approvalRequiredFrom).toBe(undefined); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); @@ -1025,7 +1025,7 @@ describe('Calendar Tests', () => { expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.teamType).toBe(undefined); - expect(result.approved).toBe(true); + expect(result.approved).toBe(undefined); expect(result.approvalRequiredFrom).toBeUndefined(); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); @@ -1952,7 +1952,7 @@ describe('Calendar Tests', () => { expect(result.optionalMembers).toHaveLength(1); expect(result.optionalMembers[0].userId).toBe(adminUser.userId); expect(result.documentIds).toEqual(['doc2', 'doc3']); - expect(result.approved).toBe(true); + expect(result.approved).toBe(undefined); expect(result.approvalRequiredFrom).toBe(undefined); expect(result.questionDocument).toBe('https://updated.com/questions.pdf'); expect(result.location).toBe('Updated Location'); diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 296d581725..ea5bf83cc5 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -2,14 +2,29 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material'; +import { + Box, + Button, + Link, + Stack, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Tooltip, + Typography +} from '@mui/material'; import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; import { useFilterEvents } from '../../hooks/calendar.hooks'; import { useCurrentUser } from '../../hooks/users.hooks'; -import { useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { ConflictStatus, ScheduleSlot } from 'shared'; import { Event } from 'shared'; +import WarningIcon from '@mui/icons-material/Warning'; +import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; interface YourEventsHeadCells { id: string; @@ -173,13 +188,88 @@ const YourEventsPage = () => { : 'N/A'} - {event.approved === ConflictStatus.CONFIRMED - ? 'Approved' - : event.approved === ConflictStatus.UNCONFIRMED - ? 'PENDING' - : event.approved === ConflictStatus.DENIED - ? 'DENIED' + + + {event.approved + ? event.approved === ConflictStatus.CONFIRMED + ? 'Approved' + : event.approved === ConflictStatus.UNCONFIRMED + ? 'Pending' + : 'Denied' : 'N/A'} + + {event.approved && ( + + + + Your meeting approval has been denied, please reschedule or change your meeting location. + + + + } + > + + + )} + ); From c84279c4b299b9111c0be3ef43ad25cef0608d64 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 8 Dec 2025 22:43:34 -0500 Subject: [PATCH 303/477] oops --- src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index ea5bf83cc5..890c2e69a1 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -198,7 +198,7 @@ const YourEventsPage = () => { : 'Denied' : 'N/A'} - {event.approved && ( + {event.approved && event.approved === ConflictStatus.DENIED && ( Date: Mon, 8 Dec 2025 22:54:02 -0500 Subject: [PATCH 304/477] filter update --- src/backend/src/routes/calendar.routes.ts | 2 +- src/backend/src/services/calendar.services.ts | 4 ++-- src/shared/src/types/calendar-types.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index d2aba1e229..95f6cefeab 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -227,7 +227,7 @@ calendarRouter.post( body('eventTypeIds.*').optional().isString(), body('eventIds').isArray().optional(), body('eventIds.*').isString().optional(), - body('approvalStatus').isBoolean().optional(), + body('approvedEvents').isBoolean().optional(), isDate(body('startPeriod')), isDate(body('endPeriod')), validateInputs, diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index d71bb4b5d7..f2ea112cf5 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1988,7 +1988,7 @@ export default class CalendarService { * @throws NotFoundException If the given event type Ids, member IDs, team IDs, or event IDs are not found. */ static async getFilteredEvents(filters: FilterArgs, organization: Organization): Promise { - const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, startPeriod, endPeriod } = filters; + const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvedEvents, startPeriod, endPeriod } = filters; // validate memberIds if (memberIds?.length) { @@ -2097,7 +2097,7 @@ export default class CalendarService { eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, teams: teamIds?.length ? { some: { teamId: { in: teamIds } } } : undefined, - approved: undefined, + OR: approvedEvents ? [{ approved: 'CONFIRMED' }, { approved: null }] : undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...memberOrCreator, ...fromCalendar diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index fc3f4a029e..c712d9445c 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -89,7 +89,7 @@ export interface FilterArgs { calendarIds?: string[]; eventTypeIds?: string[]; eventIds?: string[]; - approvalStatus?: boolean; + approvedEvents?: boolean; startPeriod: Date; endPeriod: Date; } From e69596645c09078fd549fcdae999ef1e02296697 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 9 Dec 2025 19:35:03 -0500 Subject: [PATCH 305/477] updated stuff --- .../20251209025316_calendar/migration.sql | 461 ------------ .../20251210001906_calendar/migration.sql | 706 ++++++++++++++++++ src/backend/src/prisma/schema.prisma | 7 +- src/backend/src/services/calendar.services.ts | 12 +- .../src/transformers/calendar.transformer.ts | 9 +- src/backend/tests/unit/calendar.test.ts | 8 +- .../pages/NewCalendarPage/YourEventsPage.tsx | 16 +- .../test-data/design-reviews.stub.ts | 4 +- src/shared/src/types/calendar-types.ts | 9 +- 9 files changed, 742 insertions(+), 490 deletions(-) delete mode 100644 src/backend/src/prisma/migrations/20251209025316_calendar/migration.sql create mode 100644 src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql diff --git a/src/backend/src/prisma/migrations/20251209025316_calendar/migration.sql b/src/backend/src/prisma/migrations/20251209025316_calendar/migration.sql deleted file mode 100644 index b4ac2c71ef..0000000000 --- a/src/backend/src/prisma/migrations/20251209025316_calendar/migration.sql +++ /dev/null @@ -1,461 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `designReviewId` on the `Message_Info` table. All the data in the column will be lost. - - You are about to drop the `Design_Review` table. If the table is not empty, all the data it contains will be lost. - - You are about to drop the `Meeting` table. If the table is not empty, all the data it contains will be lost. - - You are about to drop the `_confirmedAttendee` table. If the table is not empty, all the data it contains will be lost. - - You are about to drop the `_deniedAttendee` table. If the table is not empty, all the data it contains will be lost. - - You are about to drop the `_optionalAttendee` table. If the table is not empty, all the data it contains will be lost. - - You are about to drop the `_requiredAttendee` table. If the table is not empty, all the data it contains will be lost. - - You are about to drop the `_userAttended` table. If the table is not empty, all the data it contains will be lost. - -*/ --- CreateEnum -CREATE TYPE "Event_Status" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'SCHEDULED', 'DONE'); - --- CreateEnum -CREATE TYPE "DayOfWeek" AS ENUM ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'); - --- CreateEnum -CREATE TYPE "ConflictStatus" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'DENIED'); - --- DropForeignKey -ALTER TABLE "public"."Design_Review" DROP CONSTRAINT "Design_Review_teamTypeId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Design_Review" DROP CONSTRAINT "Design_Review_userCreatedId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Design_Review" DROP CONSTRAINT "Design_Review_userDeletedId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Design_Review" DROP CONSTRAINT "Design_Review_wbsElementId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Meeting" DROP CONSTRAINT "Meeting_teamId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."Message_Info" DROP CONSTRAINT "Message_Info_designReviewId_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_confirmedAttendee" DROP CONSTRAINT "_confirmedAttendee_A_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_confirmedAttendee" DROP CONSTRAINT "_confirmedAttendee_B_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_deniedAttendee" DROP CONSTRAINT "_deniedAttendee_A_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_deniedAttendee" DROP CONSTRAINT "_deniedAttendee_B_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_optionalAttendee" DROP CONSTRAINT "_optionalAttendee_A_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_optionalAttendee" DROP CONSTRAINT "_optionalAttendee_B_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_requiredAttendee" DROP CONSTRAINT "_requiredAttendee_A_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_requiredAttendee" DROP CONSTRAINT "_requiredAttendee_B_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_userAttended" DROP CONSTRAINT "_userAttended_A_fkey"; - --- DropForeignKey -ALTER TABLE "public"."_userAttended" DROP CONSTRAINT "_userAttended_B_fkey"; - --- DropIndex -DROP INDEX "public"."Message_Info_designReviewId_idx"; - --- AlterTable -ALTER TABLE "Message_Info" DROP COLUMN "designReviewId", -ADD COLUMN "eventId" TEXT; - --- DropTable -DROP TABLE "public"."Design_Review"; - --- DropTable -DROP TABLE "public"."Meeting"; - --- DropTable -DROP TABLE "public"."_confirmedAttendee"; - --- DropTable -DROP TABLE "public"."_deniedAttendee"; - --- DropTable -DROP TABLE "public"."_optionalAttendee"; - --- DropTable -DROP TABLE "public"."_requiredAttendee"; - --- DropTable -DROP TABLE "public"."_userAttended"; - --- DropEnum -DROP TYPE "public"."Design_Review_Status"; - --- CreateTable -CREATE TABLE "Shop" ( - "shopId" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "description" TEXT NOT NULL, - "organizationId" TEXT NOT NULL, - - CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId") -); - --- CreateTable -CREATE TABLE "Machinery" ( - "machineryId" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "organizationId" TEXT NOT NULL, - - CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId") -); - --- CreateTable -CREATE TABLE "Shop_Machinery" ( - "shopMachineryId" TEXT NOT NULL, - "shopId" TEXT NOT NULL, - "machineryId" TEXT NOT NULL, - "quantity" INTEGER NOT NULL DEFAULT 1, - - CONSTRAINT "Shop_Machinery_pkey" PRIMARY KEY ("shopMachineryId") -); - --- CreateTable -CREATE TABLE "Schedule_Slot" ( - "scheduleSlotId" TEXT NOT NULL, - "days" "DayOfWeek"[], - "startTime" TIMESTAMP(3), - "endTime" TIMESTAMP(3), - "recurrenceNumber" INTEGER NOT NULL, - "initialDateScheduled" DATE NOT NULL, - "endDate" DATE NOT NULL, - "allDay" BOOLEAN NOT NULL DEFAULT false, - - CONSTRAINT "Schedule_Slot_pkey" PRIMARY KEY ("scheduleSlotId") -); - --- CreateTable -CREATE TABLE "Event" ( - "eventId" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "title" TEXT NOT NULL, - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "eventTypeId" TEXT NOT NULL, - "approved" "ConflictStatus", - "approvalRequiredFromUserId" TEXT, - "teamTypeId" TEXT, - "location" TEXT, - "zoomLink" TEXT, - "documentIds" TEXT[], - "status" "Event_Status" NOT NULL, - "questionDocument" TEXT, - "description" TEXT, - - CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId") -); - --- CreateTable -CREATE TABLE "Calendar" ( - "calendarId" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "description" TEXT NOT NULL, - "colorHexCode" TEXT NOT NULL, - "organizationId" TEXT NOT NULL, - - CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId") -); - --- CreateTable -CREATE TABLE "Event_Type" ( - "eventTypeId" TEXT NOT NULL, - "name" TEXT NOT NULL, - "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, - "dateDeleted" TIMESTAMP(3), - "userCreatedId" TEXT NOT NULL, - "userDeletedId" TEXT, - "requiredMembers" BOOLEAN NOT NULL, - "optionalMembers" BOOLEAN NOT NULL, - "teams" BOOLEAN NOT NULL, - "teamType" BOOLEAN NOT NULL, - "location" BOOLEAN NOT NULL, - "zoomLink" BOOLEAN NOT NULL, - "shop" BOOLEAN NOT NULL, - "machinery" BOOLEAN NOT NULL, - "workPackage" BOOLEAN NOT NULL, - "questionDocument" BOOLEAN NOT NULL, - "documents" BOOLEAN NOT NULL, - "description" BOOLEAN NOT NULL, - "onlyHeadsOrAboveForEventCreation" BOOLEAN NOT NULL, - "requiresConfirmation" BOOLEAN NOT NULL, - "sendSlackNotifications" BOOLEAN NOT NULL, - "organizationId" TEXT NOT NULL, - - CONSTRAINT "Event_Type_pkey" PRIMARY KEY ("eventTypeId") -); - --- CreateTable -CREATE TABLE "_EventToSchedule_Slot" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToSchedule_Slot_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_requiredEventAttendee" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_requiredEventAttendee_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_optionalEventAttendee" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_optionalEventAttendee_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_confirmedEventAttendee" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_confirmedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_deniedEventAttendee" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_deniedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_affiliatedTeam" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_affiliatedTeam_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_EventToShop" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToShop_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_EventToMachinery" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToMachinery_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_EventToWork_Package" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToWork_Package_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateTable -CREATE TABLE "_CalendarToEvent_Type" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_CalendarToEvent_Type_AB_pkey" PRIMARY KEY ("A","B") -); - --- CreateIndex -CREATE UNIQUE INDEX "Shop_name_key" ON "Shop"("name"); - --- CreateIndex -CREATE INDEX "Shop_Machinery_machineryId_idx" ON "Shop_Machinery"("machineryId"); - --- CreateIndex -CREATE UNIQUE INDEX "Shop_Machinery_shopId_machineryId_key" ON "Shop_Machinery"("shopId", "machineryId"); - --- CreateIndex -CREATE INDEX "Schedule_Slot_initialDateScheduled_endDate_idx" ON "Schedule_Slot"("initialDateScheduled", "endDate"); - --- CreateIndex -CREATE INDEX "_EventToSchedule_Slot_B_index" ON "_EventToSchedule_Slot"("B"); - --- CreateIndex -CREATE INDEX "_requiredEventAttendee_B_index" ON "_requiredEventAttendee"("B"); - --- CreateIndex -CREATE INDEX "_optionalEventAttendee_B_index" ON "_optionalEventAttendee"("B"); - --- CreateIndex -CREATE INDEX "_confirmedEventAttendee_B_index" ON "_confirmedEventAttendee"("B"); - --- CreateIndex -CREATE INDEX "_deniedEventAttendee_B_index" ON "_deniedEventAttendee"("B"); - --- CreateIndex -CREATE INDEX "_affiliatedTeam_B_index" ON "_affiliatedTeam"("B"); - --- CreateIndex -CREATE INDEX "_EventToShop_B_index" ON "_EventToShop"("B"); - --- CreateIndex -CREATE INDEX "_EventToMachinery_B_index" ON "_EventToMachinery"("B"); - --- CreateIndex -CREATE INDEX "_EventToWork_Package_B_index" ON "_EventToWork_Package"("B"); - --- CreateIndex -CREATE INDEX "_CalendarToEvent_Type_B_index" ON "_CalendarToEvent_Type"("B"); - --- CreateIndex -CREATE INDEX "Message_Info_eventId_idx" ON "Message_Info"("eventId"); - --- AddForeignKey -ALTER TABLE "Message_Info" ADD CONSTRAINT "Message_Info_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("eventId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Shop" ADD CONSTRAINT "Shop_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Shop" ADD CONSTRAINT "Shop_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Machinery" ADD CONSTRAINT "Machinery_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Shop_Machinery" ADD CONSTRAINT "Shop_Machinery_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "Shop"("shopId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Shop_Machinery" ADD CONSTRAINT "Shop_Machinery_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "Machinery"("machineryId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Event" ADD CONSTRAINT "Event_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Event" ADD CONSTRAINT "Event_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "Event_Type"("eventTypeId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Event" ADD CONSTRAINT "Event_approvalRequiredFromUserId_fkey" FOREIGN KEY ("approvalRequiredFromUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Event" ADD CONSTRAINT "Event_teamTypeId_fkey" FOREIGN KEY ("teamTypeId") REFERENCES "Team_Type"("teamTypeId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Event_Type" ADD CONSTRAINT "Event_Type_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Event_Type" ADD CONSTRAINT "Event_Type_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Event_Type" ADD CONSTRAINT "Event_Type_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_B_fkey" FOREIGN KEY ("B") REFERENCES "Schedule_Slot"("scheduleSlotId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_B_fkey" FOREIGN KEY ("B") REFERENCES "Team"("teamId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_EventToShop" ADD CONSTRAINT "_EventToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_EventToShop" ADD CONSTRAINT "_EventToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_B_fkey" FOREIGN KEY ("B") REFERENCES "Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_A_fkey" FOREIGN KEY ("A") REFERENCES "Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_B_fkey" FOREIGN KEY ("B") REFERENCES "Work_Package"("workPackageId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_A_fkey" FOREIGN KEY ("A") REFERENCES "Calendar"("calendarId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_B_fkey" FOREIGN KEY ("B") REFERENCES "Event_Type"("eventTypeId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql b/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql new file mode 100644 index 0000000000..c3062ce452 --- /dev/null +++ b/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql @@ -0,0 +1,706 @@ +-- CreateEnum +CREATE TYPE "public"."DayOfWeek" AS ENUM ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'); + +-- CreateTable +CREATE TABLE "public"."Shop" ( + "shopId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "description" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Shop_pkey" PRIMARY KEY ("shopId") +); + +-- CreateTable +CREATE TABLE "public"."Machinery" ( + "machineryId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Machinery_pkey" PRIMARY KEY ("machineryId") +); + +-- CreateTable +CREATE TABLE "public"."Shop_Machinery" ( + "shopMachineryId" TEXT NOT NULL, + "shopId" TEXT NOT NULL, + "machineryId" TEXT NOT NULL, + "quantity" INTEGER NOT NULL DEFAULT 1, + + CONSTRAINT "Shop_Machinery_pkey" PRIMARY KEY ("shopMachineryId") +); + +-- CreateTable +CREATE TABLE "public"."Schedule_Slot" ( + "scheduleSlotId" TEXT NOT NULL, + "days" "public"."DayOfWeek"[], + "startTime" TIMESTAMP(3), + "endTime" TIMESTAMP(3), + "recurrenceNumber" INTEGER NOT NULL, + "initialDateScheduled" DATE NOT NULL, + "endDate" DATE NOT NULL, + "allDay" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "Schedule_Slot_pkey" PRIMARY KEY ("scheduleSlotId") +); + +-- CreateEnum +CREATE TYPE "ConflictStatus" AS ENUM ('PENDING', 'APPROVED', 'DENIED', 'NO_CONFLICT'); + +-- CreateTable +CREATE TABLE "public"."Event" ( + "eventId" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "title" TEXT NOT NULL, + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "eventTypeId" TEXT NOT NULL, + "approved" "public"."ConflictStatus" NOT NULL, + "approvalRequiredFromUserId" TEXT, + "location" TEXT, + "zoomLink" TEXT, + "documentIds" TEXT[], + "questionDocument" TEXT, + "description" TEXT, + "teamTypeId" TEXT, + + CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId") +); + +-- CreateTable +CREATE TABLE "public"."Calendar" ( + "calendarId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "description" TEXT NOT NULL, + "colorHexCode" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Calendar_pkey" PRIMARY KEY ("calendarId") +); + +-- CreateTable +CREATE TABLE "public"."Event_Type" ( + "eventTypeId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "userCreatedId" TEXT NOT NULL, + "userDeletedId" TEXT, + "optionalMembers" BOOLEAN NOT NULL DEFAULT FALSE, + "requiredMembers" BOOLEAN NOT NULL DEFAULT FALSE, + "teams" BOOLEAN NOT NULL DEFAULT FALSE, + "teamType" BOOLEAN NOT NULL DEFAULT FALSE, + "location" BOOLEAN NOT NULL DEFAULT FALSE, + "zoomLink" BOOLEAN NOT NULL DEFAULT FALSE, + "shop" BOOLEAN NOT NULL DEFAULT FALSE, + "machinery" BOOLEAN NOT NULL DEFAULT FALSE, + "workPackage" BOOLEAN NOT NULL DEFAULT FALSE, + "questionDocument" BOOLEAN NOT NULL DEFAULT FALSE, + "documents" BOOLEAN NOT NULL DEFAULT FALSE, + "description" BOOLEAN NOT NULL DEFAULT FALSE, + "onlyHeadsOrAboveForEventCreation" BOOLEAN NOT NULL DEFAULT FALSE, + "requiresConfirmation" BOOLEAN NOT NULL DEFAULT FALSE, + "sendSlackNotifications" BOOLEAN NOT NULL DEFAULT FALSE, + "organizationId" TEXT NOT NULL, + + CONSTRAINT "Event_Type_pkey" PRIMARY KEY ("eventTypeId") +); + +-- CreateEnum +CREATE TYPE "public"."Event_Status" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'SCHEDULED', 'DONE'); + +-- AlterTable +ALTER TABLE "public"."Event" ADD COLUMN "status" "public"."Event_Status" NOT NULL; + +-- CreateTable +CREATE TABLE "public"."_EventToSchedule_Slot" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToSchedule_Slot_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_affiliatedTeam" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_affiliatedTeam_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_EventToShop" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToShop_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_EventToMachinery" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToMachinery_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_EventToWork_Package" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_EventToWork_Package_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_CalendarToEvent_Type" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_CalendarToEvent_Type_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_requiredEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_requiredEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_optionalEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_optionalEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_confirmedEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_confirmedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "public"."_deniedEventAttendee" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_deniedEventAttendee_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE INDEX "_requiredEventAttendee_B_index" ON "public"."_requiredEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_optionalEventAttendee_B_index" ON "public"."_optionalEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_confirmedEventAttendee_B_index" ON "public"."_confirmedEventAttendee"("B"); + +-- CreateIndex +CREATE INDEX "_deniedEventAttendee_B_index" ON "public"."_deniedEventAttendee"("B"); + +-- AddForeignKey +ALTER TABLE "public"."_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_optionalEventAttendee" ADD CONSTRAINT "_optionalEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_confirmedEventAttendee" ADD CONSTRAINT "_confirmedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_deniedEventAttendee" ADD CONSTRAINT "_deniedEventAttendee_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."User"("userId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- CreateIndex +CREATE INDEX "Shop_Machinery_machineryId_idx" ON "public"."Shop_Machinery"("machineryId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Shop_Machinery_shopId_machineryId_key" ON "public"."Shop_Machinery"("shopId", "machineryId"); + +-- CreateIndex +CREATE INDEX "Schedule_Slot_initialDateScheduled_endDate_idx" ON "public"."Schedule_Slot"("initialDateScheduled", "endDate"); + +-- CreateIndex +CREATE INDEX "_EventToSchedule_Slot_B_index" ON "public"."_EventToSchedule_Slot"("B"); + +-- CreateIndex +CREATE INDEX "_affiliatedTeam_B_index" ON "public"."_affiliatedTeam"("B"); + +-- CreateIndex +CREATE INDEX "_EventToShop_B_index" ON "public"."_EventToShop"("B"); + +-- CreateIndex +CREATE INDEX "_EventToMachinery_B_index" ON "public"."_EventToMachinery"("B"); + +-- CreateIndex +CREATE INDEX "_EventToWork_Package_B_index" ON "public"."_EventToWork_Package"("B"); + +-- CreateIndex +CREATE INDEX "_CalendarToEvent_Type_B_index" ON "public"."_CalendarToEvent_Type"("B"); + +-- AddForeignKey +ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Shop" ADD CONSTRAINT "Shop_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Machinery" ADD CONSTRAINT "Machinery_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Shop_Machinery" ADD CONSTRAINT "Shop_Machinery_shopId_fkey" FOREIGN KEY ("shopId") REFERENCES "public"."Shop"("shopId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Shop_Machinery" ADD CONSTRAINT "Shop_Machinery_machineryId_fkey" FOREIGN KEY ("machineryId") REFERENCES "public"."Machinery"("machineryId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_eventTypeId_fkey" FOREIGN KEY ("eventTypeId") REFERENCES "public"."Event_Type"("eventTypeId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_approvalRequiredFromUserId_fkey" FOREIGN KEY ("approvalRequiredFromUserId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event" ADD CONSTRAINT "Event_teamTypeId_fkey" FOREIGN KEY ("teamTypeId") REFERENCES "public"."Team_Type"("teamTypeId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Calendar" ADD CONSTRAINT "Calendar_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event_Type" ADD CONSTRAINT "Event_Type_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "public"."User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event_Type" ADD CONSTRAINT "Event_Type_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "public"."User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."Event_Type" ADD CONSTRAINT "Event_Type_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Schedule_Slot"("scheduleSlotId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Team"("teamId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToShop" ADD CONSTRAINT "_EventToShop_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToShop" ADD CONSTRAINT "_EventToShop_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Shop"("shopId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToMachinery" ADD CONSTRAINT "_EventToMachinery_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Machinery"("machineryId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_EventToWork_Package" ADD CONSTRAINT "_EventToWork_Package_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Work_Package"("workPackageId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Calendar"("calendarId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "public"."_CalendarToEvent_Type" ADD CONSTRAINT "_CalendarToEvent_Type_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Event_Type"("eventTypeId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- Create Event_Types for Design Review (one per organization) +INSERT INTO "public"."Event_Type" ( + "eventTypeId", + "name", + "dateCreated", + "userCreatedId", + "requiredMembers", + "optionalMembers", + "teams", + "teamType", + "location", + "zoomLink", + "shop", + "machinery", + "workPackage", + "questionDocument", + "documents", + "description", + "onlyHeadsOrAboveForEventCreation", + "requiresConfirmation", + "organizationId" +) +SELECT DISTINCT ON (org."organizationId") + gen_random_uuid(), + 'Design Review', + NOW(), + org."userCreatedId", + true, -- requiredMembers + true, -- optionalMembers + false, -- teams + true, -- team type + true, -- location + true, -- zoomLink + false, -- shop + false, -- machinery + true, -- workPackage (based on wbsElementId) + true, -- questionDocument (docTemplateLink) + true, -- documents + false, -- description + true, -- onlyHeadsOrAboveForEventCreation + true, -- requiresConfirmation + org."organizationId" +FROM "public"."Organization" org +WHERE EXISTS ( + SELECT 1 FROM "public"."Design_Review" dr + JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId" + WHERE w."organizationId" = org."organizationId" + AND dr."dateDeleted" IS NULL +); + +-- Create Event_Types for Meeting (one per organization) +INSERT INTO "public"."Event_Type" ( + "eventTypeId", + "name", + "dateCreated", + "userCreatedId", + "requiredMembers", + "optionalMembers", + "teams", + "teamType", + "location", + "zoomLink", + "shop", + "machinery", + "workPackage", + "questionDocument", + "documents", + "description", + "onlyHeadsOrAboveForEventCreation", + "requiresConfirmation", + "organizationId" +) +SELECT DISTINCT ON (org."organizationId") + gen_random_uuid(), + 'Meeting', + NOW(), + org."userCreatedId", + false, -- requiredMembers + false, -- optionalMembers + true, -- teams + false, -- team type + false, -- location + false, -- zoomLink + false, -- shop + false, -- machinery + false, -- workPackage + false, -- questionDocument + false, -- documents + false, -- description + false, -- onlyHeadsOrAboveForEventCreation + false, -- requiresConfirmation + org."organizationId" +FROM "public"."Organization" org +WHERE EXISTS ( + SELECT 1 FROM "public"."Meeting" m + JOIN "public"."Team" t ON m."teamId" = t."teamId" + WHERE t."organizationId" = org."organizationId" +); + +-- Migrate Design_Review records to Event table +INSERT INTO "public"."Event" ( + "eventId", + "dateCreated", + "dateDeleted", + "title", + "userCreatedId", + "userDeletedId", + "eventTypeId", + "approved", + "approvalRequiredFromUserId", + "location", + "zoomLink", + "documentIds", + "questionDocument", + "description", + "status", + "teamTypeId" +) +SELECT + dr."designReviewId", + dr."dateCreated", + dr."dateDeleted", + 'Design Review - ' || w."name", -- Generate title from WBS element name + dr."userCreatedId", + dr."userDeletedId", + (SELECT et."eventTypeId" + FROM "public"."Event_Type" et + WHERE et."name" = 'Design Review' + AND et."organizationId" = w."organizationId" + LIMIT 1), + CASE WHEN dr."status" IN ('CONFIRMED', 'SCHEDULED', 'DONE') THEN true ELSE false END, + NULL, -- approvalRequiredFromUserId (not in Design_Review) + dr."location", + dr."zoomLink", + CASE WHEN dr."docTemplateLink" IS NOT NULL THEN ARRAY[dr."docTemplateLink"] ELSE ARRAY[]::TEXT[] END, + dr."docTemplateLink", -- questionDocument uses docTemplateLink + NULL, -- description (not in Design_Review) + dr."status"::"text"::"public"."Event_Status", + dr."teamTypeId" +FROM "public"."Design_Review" dr +JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId"; + +-- Create Schedule_Slot records for Design Reviews +-- This creates one slot per time per design review +-- Design Reviews are non-recurring, so endDate = dateScheduled +CREATE TEMP TABLE temp_dr_schedule_slots AS +SELECT + dr."designReviewId" as event_id, + gen_random_uuid() as slot_id, + ARRAY[CASE EXTRACT(DOW FROM dr."dateScheduled") + WHEN 0 THEN 'SUNDAY'::public."DayOfWeek" + WHEN 1 THEN 'MONDAY'::public."DayOfWeek" + WHEN 2 THEN 'TUESDAY'::public."DayOfWeek" + WHEN 3 THEN 'WEDNESDAY'::public."DayOfWeek" + WHEN 4 THEN 'THURSDAY'::public."DayOfWeek" + WHEN 5 THEN 'FRIDAY'::public."DayOfWeek" + WHEN 6 THEN 'SATURDAY'::public."DayOfWeek" + END] as days, + dr."dateScheduled" + ((10 + time_slot) * INTERVAL '1 hour') as start_time, + dr."dateScheduled" + ((11 + time_slot) * INTERVAL '1 hour') as end_time, + 0 as recurrence_number, + dr."initialDateScheduled" as initial_date, + dr."dateScheduled" as end_date, + false as all_day +FROM "public"."Design_Review" dr +CROSS JOIN LATERAL unnest(dr."meetingTimes") AS time_slot; + +-- Insert schedule slots from temp table +INSERT INTO "public"."Schedule_Slot" ( + "scheduleSlotId", + "days", + "startTime", + "endTime", + "recurrenceNumber", + "initialDateScheduled", + "endDate", + "allDay" +) +SELECT + slot_id, + days, + start_time, + end_time, + recurrence_number, + initial_date, + end_date, + all_day +FROM temp_dr_schedule_slots; + +-- Link Schedule_Slots to Events using the temp table +INSERT INTO "public"."_EventToSchedule_Slot" ("A", "B") +SELECT event_id, slot_id +FROM temp_dr_schedule_slots; + +-- Drop temp table +DROP TABLE temp_dr_schedule_slots; + +-- Migrate Design Review member relationships +INSERT INTO "public"."_requiredEventAttendee" ("A", "B") +SELECT dr."designReviewId", ra."B" +FROM "public"."Design_Review" dr +JOIN "public"."_requiredAttendee" ra ON dr."designReviewId" = ra."A"; + +INSERT INTO "public"."_optionalEventAttendee" ("A", "B") +SELECT dr."designReviewId", oa."B" +FROM "public"."Design_Review" dr +JOIN "public"."_optionalAttendee" oa ON dr."designReviewId" = oa."A"; + +INSERT INTO "public"."_confirmedEventAttendee" ("A", "B") +SELECT dr."designReviewId", ca."B" +FROM "public"."Design_Review" dr +JOIN "public"."_confirmedAttendee" ca ON dr."designReviewId" = ca."A"; + +INSERT INTO "public"."_deniedEventAttendee" ("A", "B") +SELECT dr."designReviewId", da."B" +FROM "public"."Design_Review" dr +JOIN "public"."_deniedAttendee" da ON dr."designReviewId" = da."A"; + +-- Link Design Reviews to Work Packages (via wbsElementId) +INSERT INTO "public"."_EventToWork_Package" ("A", "B") +SELECT dr."designReviewId", wp."workPackageId" +FROM "public"."Design_Review" dr +JOIN "public"."Work_Package" wp ON dr."wbsElementId" = wp."wbsElementId"; + +-- Migrate Meeting records to Event table +INSERT INTO "public"."Event" ( + "eventId", + "dateCreated", + "title", + "userCreatedId", + "eventTypeId", + "approved", + "status" +) +SELECT + m."meetingId", + NOW(), + m."title", + t."headId", -- Use the team head as the creator + (SELECT et."eventTypeId" + FROM "public"."Event_Type" et + WHERE et."name" = 'Meeting' + AND et."organizationId" = t."organizationId" + LIMIT 1), + false, -- Meetings aren't pre-approved + 'UNCONFIRMED'::public."Event_Status" +FROM "public"."Meeting" m +JOIN "public"."Team" t ON m."teamId" = t."teamId"; + +-- Create Schedule_Slot records for Meetings +-- This creates one slot per time per meeting +CREATE TEMP TABLE temp_meeting_schedule_slots AS +SELECT + m."meetingId" as event_id, + gen_random_uuid() as slot_id, + ARRAY[CASE EXTRACT(DOW FROM m."dateSet") + WHEN 0 THEN 'SUNDAY'::public."DayOfWeek" + WHEN 1 THEN 'MONDAY'::public."DayOfWeek" + WHEN 2 THEN 'TUESDAY'::public."DayOfWeek" + WHEN 3 THEN 'WEDNESDAY'::public."DayOfWeek" + WHEN 4 THEN 'THURSDAY'::public."DayOfWeek" + WHEN 5 THEN 'FRIDAY'::public."DayOfWeek" + WHEN 6 THEN 'SATURDAY'::public."DayOfWeek" + END] as days, + m."dateSet" + ((10 + time_slot) * INTERVAL '1 hour') as start_time, + m."dateSet" + ((11 + time_slot) * INTERVAL '1 hour') as end_time, + CASE WHEN m."recurringInterval" > 0 THEN m."recurringInterval" ELSE 0 END as recurrence_number, + m."dateSet"::DATE as initial_date, + CASE + WHEN m."recurringInterval" > 0 THEN (m."dateSet" + INTERVAL '1 year')::DATE + ELSE m."dateSet"::DATE + END as end_date, + false as all_day +FROM "public"."Meeting" m +CROSS JOIN LATERAL unnest(m."meetingTimes") AS time_slot; + +-- Insert schedule slots from temp table +INSERT INTO "public"."Schedule_Slot" ( + "scheduleSlotId", + "days", + "startTime", + "endTime", + "recurrenceNumber", + "initialDateScheduled", + "endDate", + "allDay" +) +SELECT + slot_id, + days, + start_time, + end_time, + recurrence_number, + initial_date, + end_date, + all_day +FROM temp_meeting_schedule_slots; + +-- Link Schedule_Slots to Events using the temp table +INSERT INTO "public"."_EventToSchedule_Slot" ("A", "B") +SELECT event_id, slot_id +FROM temp_meeting_schedule_slots; + +-- Drop temp table +DROP TABLE temp_meeting_schedule_slots; + +-- Link Meetings to Teams +INSERT INTO "public"."_affiliatedTeam" ("A", "B") +SELECT m."meetingId", m."teamId" +FROM "public"."Meeting" m; + +ALTER TABLE "Message_Info" ADD COLUMN "eventId" TEXT; + +UPDATE "Message_Info" +SET "eventId" = "designReviewId" +WHERE "designReviewId" IS NOT NULL; + +DROP INDEX IF EXISTS "Message_Info_designReviewId_idx"; + +ALTER TABLE "Message_Info" DROP COLUMN IF EXISTS "designReviewId"; + +CREATE INDEX IF NOT EXISTS "Message_Info_eventId_idx" ON "Message_Info"("eventId"); + +ALTER TABLE "Message_Info" +ADD CONSTRAINT "Message_Info_eventId_fkey" +FOREIGN KEY ("eventId") +REFERENCES "Event"("eventId") +ON DELETE SET NULL +ON UPDATE CASCADE; + +-- Drop old relation tables for Design_Review +DROP TABLE "public"."_requiredAttendee" CASCADE; +DROP TABLE "public"."_optionalAttendee" CASCADE; +DROP TABLE "public"."_confirmedAttendee" CASCADE; +DROP TABLE "public"."_deniedAttendee" CASCADE; +DROP TABLE "public"."_userAttended" CASCADE; + +-- Drop the old Meeting and Design_Review tables +DROP TABLE "public"."Meeting" CASCADE; +DROP TABLE "public"."Design_Review" CASCADE; + +-- DropEnum +DROP TYPE "public"."Design_Review_Status"; \ No newline at end of file diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 2ff8721ec3..2669855240 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1030,9 +1030,10 @@ model Schedule_Slot { } enum ConflictStatus { - UNCONFIRMED - CONFIRMED + PENDING + APPROVED DENIED + NO_CONFLICT } model Event { @@ -1046,7 +1047,7 @@ model Event { userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventDeleter") eventTypeId String eventType Event_Type @relation(fields: [eventTypeId], references: [eventTypeId]) - approved ConflictStatus? + approved ConflictStatus // when approval is false, approved by holds who needs to approve the event // when approval is true, approved by holds who actually approved the event approvalRequiredFromUserId String? diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index f2ea112cf5..dd90f61148 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -460,7 +460,7 @@ export default class CalendarService { })) }, status: foundEventType.requiresConfirmation ? Event_Status.UNCONFIRMED : Event_Status.CONFIRMED, - approved: hasConflict ? ConflictStatus.UNCONFIRMED : null, + approved: hasConflict ? ConflictStatus.PENDING : ConflictStatus.NO_CONFLICT, approvalRequiredFromUserId: hasConflict ? approverUserId : null, location, zoomLink, @@ -885,7 +885,11 @@ export default class CalendarService { // If schedule/location changed and there's a conflict, set approved=false and track who needs to approve // Otherwise keep existing approval state approved: - scheduleChanged || locationChanged ? (hasConflict ? ConflictStatus.UNCONFIRMED : null) : foundEvent.approved, + scheduleChanged || locationChanged + ? hasConflict + ? ConflictStatus.PENDING + : ConflictStatus.NO_CONFLICT + : foundEvent.approved, approvalRequiredFromUserId: scheduleChanged || locationChanged ? hasConflict @@ -947,7 +951,7 @@ export default class CalendarService { const approvedEvent = await prisma.event.update({ where: { eventId }, data: { - approved: ConflictStatus.CONFIRMED, + approved: ConflictStatus.APPROVED, approvalRequiredFromUserId: submitter.userId }, ...getEventQueryArgs(organization.organizationId) @@ -2097,7 +2101,7 @@ export default class CalendarService { eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, teams: teamIds?.length ? { some: { teamId: { in: teamIds } } } : undefined, - OR: approvedEvents ? [{ approved: 'CONFIRMED' }, { approved: null }] : undefined, + OR: approvedEvents ? [{ approved: 'APPROVED' }, { approved: 'NO_CONFLICT' }] : undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...memberOrCreator, ...fromCalendar diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index e865b08e56..b46b861a6b 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -121,7 +121,7 @@ export const eventTransformer = (event: Prisma.EventGetPayload): workPackages: event.workPackages, documentIds: event.documentIds, scheduledTimes: event.scheduledTimes.map(scheduleTimesTransformer), - approved: event.approved ? conflictStatusTransformer(event.approved) : undefined, + approved: conflictStatusTransformer(event.approved), approvalRequiredFrom: event.approvalRequiredBy ?? undefined, location: event.location ?? undefined, zoomLink: event.zoomLink ?? undefined, @@ -160,9 +160,10 @@ export const dayOfWeekTransformer = (day: PrismaDayOfWeek): DayOfWeek => { export const conflictStatusTransformer = (day: PrismaConflictStatus): ConflictStatus => { const mapping: Record = { - CONFIRMED: ConflictStatus.CONFIRMED, - UNCONFIRMED: ConflictStatus.UNCONFIRMED, - DENIED: ConflictStatus.DENIED + APPROVED: ConflictStatus.APPROVED, + PENDING: ConflictStatus.PENDING, + DENIED: ConflictStatus.DENIED, + NO_CONFLICT: ConflictStatus.NO_CONFLICT }; return mapping[day]; }; diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 82a88dc616..c8698bb19d 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,4 +1,4 @@ -import { Calendar, Event_Status, Organization, User } from '@prisma/client'; +import { Calendar, ConflictStatus, Event_Status, Organization, User } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; import { AccessDeniedAdminOnlyException, @@ -913,7 +913,7 @@ describe('Calendar Tests', () => { expect(result.scheduledTimes).toHaveLength(1); expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); expect(result.teamType).toBe(undefined); - expect(result.approved).toBe(undefined); + expect(result.approved).toBe(ConflictStatus.NO_CONFLICT); expect(result.approvalRequiredFrom).toBe(undefined); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); @@ -1025,7 +1025,7 @@ describe('Calendar Tests', () => { expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.teamType).toBe(undefined); - expect(result.approved).toBe(undefined); + expect(result.approved).toBe(ConflictStatus.NO_CONFLICT); expect(result.approvalRequiredFrom).toBeUndefined(); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); @@ -1952,7 +1952,7 @@ describe('Calendar Tests', () => { expect(result.optionalMembers).toHaveLength(1); expect(result.optionalMembers[0].userId).toBe(adminUser.userId); expect(result.documentIds).toEqual(['doc2', 'doc3']); - expect(result.approved).toBe(undefined); + expect(result.approved).toBe(ConflictStatus.NO_CONFLICT); expect(result.approvalRequiredFrom).toBe(undefined); expect(result.questionDocument).toBe('https://updated.com/questions.pdf'); expect(result.location).toBe('Updated Location'); diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 890c2e69a1..3abdf94859 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -190,15 +190,15 @@ const YourEventsPage = () => { - {event.approved - ? event.approved === ConflictStatus.CONFIRMED - ? 'Approved' - : event.approved === ConflictStatus.UNCONFIRMED - ? 'Pending' - : 'Denied' - : 'N/A'} + {event.approved === ConflictStatus.APPROVED + ? 'Approved' + : event.approved === ConflictStatus.PENDING + ? 'Pending' + : event.approved === ConflictStatus.DENIED + ? 'Denied' + : 'N/A'} - {event.approved && event.approved === ConflictStatus.DENIED && ( + {event.approved === ConflictStatus.DENIED && ( Date: Tue, 9 Dec 2025 19:40:19 -0500 Subject: [PATCH 306/477] refactor due to errors --- .../20251210001906_calendar/migration.sql | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql b/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql index c3062ce452..f51c55af15 100644 --- a/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql @@ -52,9 +52,6 @@ CREATE TABLE "public"."Schedule_Slot" ( CONSTRAINT "Schedule_Slot_pkey" PRIMARY KEY ("scheduleSlotId") ); --- CreateEnum -CREATE TYPE "ConflictStatus" AS ENUM ('PENDING', 'APPROVED', 'DENIED', 'NO_CONFLICT'); - -- CreateTable CREATE TABLE "public"."Event" ( "eventId" TEXT NOT NULL, @@ -64,7 +61,7 @@ CREATE TABLE "public"."Event" ( "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, "eventTypeId" TEXT NOT NULL, - "approved" "public"."ConflictStatus" NOT NULL, + "approved" BOOLEAN NOT NULL DEFAULT false, "approvalRequiredFromUserId" TEXT, "location" TEXT, "zoomLink" TEXT, @@ -703,4 +700,11 @@ DROP TABLE "public"."Meeting" CASCADE; DROP TABLE "public"."Design_Review" CASCADE; -- DropEnum -DROP TYPE "public"."Design_Review_Status"; \ No newline at end of file +DROP TYPE "public"."Design_Review_Status"; + +-- CreateEnum +CREATE TYPE "ConflictStatus" AS ENUM ('PENDING', 'APPROVED', 'DENIED', 'NO_CONFLICT'); + +-- AlterTable +ALTER TABLE "Event" DROP COLUMN "approved", +ADD COLUMN "approved" "ConflictStatus" NOT NULL; \ No newline at end of file From aee3f9995965c8b6901f1adaecff46e6855a35bc Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 9 Dec 2025 19:44:36 -0500 Subject: [PATCH 307/477] repeats --- src/frontend/src/apis/calendar.api.ts | 2 +- src/frontend/src/hooks/calendar.hooks.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 4ed30b2f14..d91b678cc0 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,7 +1,6 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; import { filterEventTransformer } from './transformers/calendar.transformer'; -import { Shop, Machinery, AvailabilityCreateArgs, Event, EventStatus, Calendar, FilterArgs } from 'shared'; import { Shop, Machinery, @@ -10,6 +9,7 @@ import { Event, EventStatus, Calendar, + FilterArgs, EventTypeCreateArgs } from 'shared'; import { eventTransformer } from './transformers/calendar.transformer'; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index f093d1bf96..872fac6606 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,14 +1,14 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop, Machinery, Calendar, AvailabilityCreateArgs, Event, EventStatus, FilterArgs } from 'shared'; import { Shop, Machinery, EventType, Calendar, - Event, - EventTypeCreateArgs, AvailabilityCreateArgs, - EventStatus + EventTypeCreateArgs, + Event, + EventStatus, + FilterArgs } from 'shared'; import { getAllShops, From a71a4ffc9f00905eb6e49f122857d0650071a54f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 9 Dec 2025 19:49:24 -0500 Subject: [PATCH 308/477] api/hook update --- src/frontend/src/apis/calendar.api.ts | 4 ++-- src/frontend/src/hooks/calendar.hooks.ts | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index d91b678cc0..2640213cc5 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -48,8 +48,8 @@ export const postCreateShop = (payload: { name: string; description: string }) = }; export const postFilterEvents = (payload: FilterArgs) => { - return axios.post(apiUrls.calendarFilterEvents(), payload, { - transformResponse: (data) => JSON.parse(data).map(filterEventTransformer) + return axios.post(apiUrls.calendarFilterEvents(), payload, { + transformResponse: (data) => JSON.parse(data).map(eventTransformer) }); }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 872fac6606..2db18b65a7 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -319,12 +319,14 @@ export const useSetEventStatus = (id: string) => { }; export const useFilterEvents = (filterArgs: FilterArgs) => { - return useQuery({ - queryKey: [FILTER_EVENTS_KEY, filterArgs], - queryFn: async () => { + return useQuery( + ['filter-events', filterArgs], + async () => { const { data } = await postFilterEvents(filterArgs); return data; }, - staleTime: 1000 * 60 - }); + { + keepPreviousData: true + } + ); }; From 077e00a30ba4da6830c12e9475394533c4579b98 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 9 Dec 2025 20:04:48 -0500 Subject: [PATCH 309/477] minor workaround --- src/frontend/src/apis/calendar.api.ts | 1 - src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 2640213cc5..780183b42d 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -1,6 +1,5 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; -import { filterEventTransformer } from './transformers/calendar.transformer'; import { Shop, Machinery, diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 3abdf94859..9bcf0227c6 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -25,6 +25,7 @@ import { ConflictStatus, ScheduleSlot } from 'shared'; import { Event } from 'shared'; import WarningIcon from '@mui/icons-material/Warning'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; +import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; interface YourEventsHeadCells { id: string; @@ -77,7 +78,7 @@ const YourEventsPage = () => { const user = useCurrentUser(); const { - data: events, + data: untransformedEvents, isLoading: eventsLoading, isFetching: eventsFetching } = useFilterEvents({ @@ -86,6 +87,11 @@ const YourEventsPage = () => { endPeriod: new Date(2099, 11, 31) // Adjust as needed }); + // Convert to include proper dates + // Done this way to allow the old events transformer to function properly + // but provide better utility to this file (without breaking other files that may rely on eventTransformer) + const events = untransformedEvents?.map(filterEventTransformer); + const loading = () => eventsLoading || eventsFetching; const [, setUpdate] = useState(true); // Linting... From 12f04c958bfe6109b1e3200b615936a9c4ac429b Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 9 Dec 2025 21:11:03 -0500 Subject: [PATCH 310/477] #3706 migration change --- .../20251210001906_calendar/migration.sql | 18 +++++++----------- src/backend/src/prisma/schema.prisma | 4 ++-- src/backend/src/services/calendar.services.ts | 12 ++++++------ .../src/transformers/calendar.transformer.ts | 2 +- src/backend/tests/unit/calendar.test.ts | 8 ++++---- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql b/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql index f51c55af15..ecbfddc8b6 100644 --- a/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql @@ -1,6 +1,9 @@ -- CreateEnum CREATE TYPE "public"."DayOfWeek" AS ENUM ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'); +-- CreateEnum +CREATE TYPE "Conflict_Status" AS ENUM ('PENDING', 'APPROVED', 'DENIED', 'NO_CONFLICT'); + -- CreateTable CREATE TABLE "public"."Shop" ( "shopId" TEXT NOT NULL, @@ -61,7 +64,7 @@ CREATE TABLE "public"."Event" ( "userCreatedId" TEXT NOT NULL, "userDeletedId" TEXT, "eventTypeId" TEXT NOT NULL, - "approved" BOOLEAN NOT NULL DEFAULT false, + "approved" "public"."Conflict_Status" NOT NULL, "approvalRequiredFromUserId" TEXT, "location" TEXT, "zoomLink" TEXT, @@ -488,7 +491,7 @@ SELECT WHERE et."name" = 'Design Review' AND et."organizationId" = w."organizationId" LIMIT 1), - CASE WHEN dr."status" IN ('CONFIRMED', 'SCHEDULED', 'DONE') THEN true ELSE false END, + 'NO_CONFLICT'::public."Conflict_Status" , NULL, -- approvalRequiredFromUserId (not in Design_Review) dr."location", dr."zoomLink", @@ -602,7 +605,7 @@ SELECT WHERE et."name" = 'Meeting' AND et."organizationId" = t."organizationId" LIMIT 1), - false, -- Meetings aren't pre-approved + 'NO_CONFLICT'::public."Conflict_Status" , 'UNCONFIRMED'::public."Event_Status" FROM "public"."Meeting" m JOIN "public"."Team" t ON m."teamId" = t."teamId"; @@ -700,11 +703,4 @@ DROP TABLE "public"."Meeting" CASCADE; DROP TABLE "public"."Design_Review" CASCADE; -- DropEnum -DROP TYPE "public"."Design_Review_Status"; - --- CreateEnum -CREATE TYPE "ConflictStatus" AS ENUM ('PENDING', 'APPROVED', 'DENIED', 'NO_CONFLICT'); - --- AlterTable -ALTER TABLE "Event" DROP COLUMN "approved", -ADD COLUMN "approved" "ConflictStatus" NOT NULL; \ No newline at end of file +DROP TYPE "public"."Design_Review_Status"; \ No newline at end of file diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 3a204265bb..9d61e9d3f0 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1030,7 +1030,7 @@ model Schedule_Slot { @@index([initialDateScheduled, endDate]) } -enum ConflictStatus { +enum Conflict_Status { PENDING APPROVED DENIED @@ -1048,7 +1048,7 @@ model Event { userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "eventDeleter") eventTypeId String eventType Event_Type @relation(fields: [eventTypeId], references: [eventTypeId]) - approved ConflictStatus + approved Conflict_Status // when approval is false, approved by holds who needs to approve the event // when approval is true, approved by holds who actually approved the event approvalRequiredFromUserId String? diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 4ef5355f98..9704829ea3 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,6 +1,6 @@ import { calendarTransformer, eventTransformer, machineryTransformer } from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; -import { ConflictStatus, Event_Status, Organization } from '@prisma/client'; +import { Conflict_Status, Event_Status, Organization } from '@prisma/client'; import { isAdmin, isHead, @@ -460,7 +460,7 @@ export default class CalendarService { })) }, status: foundEventType.requiresConfirmation ? Event_Status.UNCONFIRMED : Event_Status.CONFIRMED, - approved: hasConflict ? ConflictStatus.PENDING : ConflictStatus.NO_CONFLICT, + approved: hasConflict ? Conflict_Status.PENDING : Conflict_Status.NO_CONFLICT, approvalRequiredFromUserId: hasConflict ? approverUserId : null, location, zoomLink, @@ -887,8 +887,8 @@ export default class CalendarService { approved: scheduleChanged || locationChanged ? hasConflict - ? ConflictStatus.PENDING - : ConflictStatus.NO_CONFLICT + ? Conflict_Status.PENDING + : Conflict_Status.NO_CONFLICT : foundEvent.approved, approvalRequiredFromUserId: scheduleChanged || locationChanged @@ -951,7 +951,7 @@ export default class CalendarService { const approvedEvent = await prisma.event.update({ where: { eventId }, data: { - approved: ConflictStatus.APPROVED, + approved: Conflict_Status.APPROVED, approvalRequiredFromUserId: submitter.userId }, ...getEventQueryArgs(organization.organizationId) @@ -979,7 +979,7 @@ export default class CalendarService { const deniedEvent = await prisma.event.update({ where: { eventId }, data: { - approved: ConflictStatus.DENIED, + approved: Conflict_Status.DENIED, approvalRequiredFromUserId: submitter.userId }, ...getEventQueryArgs(organization.organizationId) diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 0823c60177..e04b477f06 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -2,7 +2,7 @@ import { Prisma, DayOfWeek as PrismaDayOfWeek, Event_Status as PrismaEventStatus, - ConflictStatus as PrismaConflictStatus + Conflict_Status as PrismaConflictStatus } from '@prisma/client'; import { Machinery, diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index c8698bb19d..49e6ff6e9c 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1,4 +1,4 @@ -import { Calendar, ConflictStatus, Event_Status, Organization, User } from '@prisma/client'; +import { Calendar, Conflict_Status, Event_Status, Organization, User } from '@prisma/client'; import CalendarService from '../../src/services/calendar.services'; import { AccessDeniedAdminOnlyException, @@ -913,7 +913,7 @@ describe('Calendar Tests', () => { expect(result.scheduledTimes).toHaveLength(1); expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); expect(result.teamType).toBe(undefined); - expect(result.approved).toBe(ConflictStatus.NO_CONFLICT); + expect(result.approved).toBe(Conflict_Status.NO_CONFLICT); expect(result.approvalRequiredFrom).toBe(undefined); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); @@ -1025,7 +1025,7 @@ describe('Calendar Tests', () => { expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.teamType).toBe(undefined); - expect(result.approved).toBe(ConflictStatus.NO_CONFLICT); + expect(result.approved).toBe(Conflict_Status.NO_CONFLICT); expect(result.approvalRequiredFrom).toBeUndefined(); expect(result.questionDocument).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); @@ -1952,7 +1952,7 @@ describe('Calendar Tests', () => { expect(result.optionalMembers).toHaveLength(1); expect(result.optionalMembers[0].userId).toBe(adminUser.userId); expect(result.documentIds).toEqual(['doc2', 'doc3']); - expect(result.approved).toBe(ConflictStatus.NO_CONFLICT); + expect(result.approved).toBe(Conflict_Status.NO_CONFLICT); expect(result.approvalRequiredFrom).toBe(undefined); expect(result.questionDocument).toBe('https://updated.com/questions.pdf'); expect(result.location).toBe('Updated Location'); From 846b588d2cf86d620ccf8d52326f5af717d68944 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 9 Dec 2025 23:47:20 -0500 Subject: [PATCH 311/477] loading updates --- .../pages/NewCalendarPage/YourEventsPage.tsx | 290 +++++++++--------- 1 file changed, 140 insertions(+), 150 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 9bcf0227c6..23c44db151 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -26,6 +26,8 @@ import { Event } from 'shared'; import WarningIcon from '@mui/icons-material/Warning'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; +import LoadingIndicator from '../../components/LoadingIndicator'; +import ErrorPage from '../ErrorPage'; interface YourEventsHeadCells { id: string; @@ -80,7 +82,8 @@ const YourEventsPage = () => { const { data: untransformedEvents, isLoading: eventsLoading, - isFetching: eventsFetching + isError: eventsIsError, + error: eventsError } = useFilterEvents({ memberIds: [user.userId], startPeriod: new Date(0), @@ -92,8 +95,6 @@ const YourEventsPage = () => { // but provide better utility to this file (without breaking other files that may rely on eventTransformer) const events = untransformedEvents?.map(filterEventTransformer); - const loading = () => eventsLoading || eventsFetching; - const [, setUpdate] = useState(true); // Linting... useEffect(() => { @@ -103,6 +104,9 @@ const YourEventsPage = () => { return () => clearInterval(timer); }, []); + if (!events || eventsLoading) return ; + if (eventsIsError) return ; + return ( @@ -126,161 +130,147 @@ const YourEventsPage = () => { - {loading() ? ( - - - Loading... - - - ) : events?.length === 0 ? ( - - - No events found. - - - ) : ( - events?.map((event) => { - const earliestSchedule = getEarliestSchedule(event); - const now = new Date(); - const diffMs = earliestSchedule.startTime.getTime() - now.getTime(); + {events?.map((event) => { + const earliestSchedule = getEarliestSchedule(event); + const now = new Date(); + const diffMs = earliestSchedule.startTime.getTime() - now.getTime(); - const seconds = Math.floor(diffMs / 1000); - const minutes = Math.floor(seconds / 60); - const hours = Math.floor(minutes / 60); - const days = Math.floor(hours / 24); + const seconds = Math.floor(diffMs / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); - // Rough month estimate (30 days) - const months = Math.floor(days / 30); + // Rough month estimate (30 days) + const months = Math.floor(days / 30); - const timeAway = { - passed: diffMs <= 0, - months, - days: days % 30, - hours: hours % 24, - minutes: minutes % 60, - seconds: seconds % 60 - }; + const timeAway = { + passed: diffMs <= 0, + months, + days: days % 30, + hours: hours % 24, + minutes: minutes % 60, + seconds: seconds % 60 + }; - return ( - - {event.title} - - {new Date(earliestSchedule.startTime).toLocaleDateString()}{' '} - {!timeAway.passed ? ` - In ${timeAway.months}m : ${timeAway.days}d` : '- Passed'} - - - {new Date(earliestSchedule.startTime).toLocaleTimeString('en-US', { - hour: 'numeric', - minute: '2-digit' - })}{' '} - {!timeAway.passed ? ` - In ${timeAway.hours}h ${timeAway.minutes}m ${timeAway.seconds}s` : '- Passed'} - - - {event.location ? ( - event.location.includes('https://') ? ( - - {event.location} - - ) : ( - event.location - ) + return ( + + {event.title} + + {new Date(earliestSchedule.startTime).toLocaleDateString()}{' '} + {!timeAway.passed ? ` - In ${timeAway.months}m : ${timeAway.days}d` : '- Passed'} + + + {new Date(earliestSchedule.startTime).toLocaleTimeString('en-US', { + hour: 'numeric', + minute: '2-digit' + })}{' '} + {!timeAway.passed ? ` - In ${timeAway.hours}h ${timeAway.minutes}m ${timeAway.seconds}s` : '- Passed'} + + + {event.location ? ( + event.location.includes('https://') ? ( + + {event.location} + ) : ( - 'N/A' - )} - - - {event.approvalRequiredFrom - ? `${event.approvalRequiredFrom.firstName} ${event.approvalRequiredFrom.lastName}` - : 'N/A'} - - - - - {event.approved === ConflictStatus.APPROVED - ? 'Approved' - : event.approved === ConflictStatus.PENDING - ? 'Pending' - : event.approved === ConflictStatus.DENIED - ? 'Denied' - : 'N/A'} - - {event.approved === ConflictStatus.DENIED && ( - + + {event.approvalRequiredFrom + ? `${event.approvalRequiredFrom.firstName} ${event.approvalRequiredFrom.lastName}` + : 'N/A'} + + + + + {event.approved === ConflictStatus.APPROVED + ? 'Approved' + : event.approved === ConflictStatus.PENDING + ? 'Pending' + : event.approved === ConflictStatus.DENIED + ? 'Denied' + : 'N/A'} + + {event.approved === ConflictStatus.DENIED && ( + - - - Your meeting approval has been denied, please reschedule or change your meeting location. - - - + ] + }} + slotProps={{ + tooltip: { + sx: { + bgcolor: '#ef5350', + color: 'white', + padding: 2, + borderRadius: 2, + maxWidth: 600, + fontSize: '14px', + boxShadow: '0 4px 12px rgba(0,0,0,0.3)' + } + }, + arrow: { + sx: { + color: '#ef5350' + } } - > - - - )} - - - - ); - }) - )} + }} + title={ + + + + Your meeting approval has been denied, please reschedule or change your meeting location. + + + + } + > + + + )} + + + + ); + })} Date: Wed, 10 Dec 2025 16:47:50 -0500 Subject: [PATCH 312/477] #3774 Added delete event types --- .ebextensions/02_cloudwatch_agent 2.config | 63 ----------- .github/workflows/deploy-prod 2.yml | 102 ------------------ src/frontend/src/apis/calendar.api.ts | 4 + src/frontend/src/hooks/calendar.hooks.ts | 16 +++ .../AdminToolsScheduleConfig.tsx | 38 +++++-- .../EventType/DeleteEventTypeModal.tsx | 44 ++++++++ .../pages/CalendarPage/EventSummaryModal.tsx | 3 +- .../pages/NewCalendarPage/NewCalendarPage.tsx | 5 +- src/frontend/src/utils/urls.ts | 4 +- 9 files changed, 99 insertions(+), 180 deletions(-) delete mode 100644 .ebextensions/02_cloudwatch_agent 2.config delete mode 100644 .github/workflows/deploy-prod 2.yml create mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx diff --git a/.ebextensions/02_cloudwatch_agent 2.config b/.ebextensions/02_cloudwatch_agent 2.config deleted file mode 100644 index 14bc226e52..0000000000 --- a/.ebextensions/02_cloudwatch_agent 2.config +++ /dev/null @@ -1,63 +0,0 @@ -files: - "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json": - mode: "000644" - owner: root - group: root - content: | - { - "agent": { - "metrics_collection_interval": 60, - "run_as_user": "root" - }, - "metrics": { - "namespace": "CWAgent", - "metrics_collected": { - "mem": { - "measurement": [ - { - "name": "mem_used_percent", - "rename": "MemoryUtilization", - "unit": "Percent" - } - ], - "metrics_collection_interval": 60 - }, - "disk": { - "measurement": [ - { - "name": "used_percent", - "rename": "DiskUtilization", - "unit": "Percent" - } - ], - "metrics_collection_interval": 60, - "resources": [ - "*" - ] - } - }, - "append_dimensions": { - "AutoScalingGroupName": "${aws:AutoScalingGroupName}", - "InstanceId": "${aws:InstanceId}" - } - } - } - -commands: - 01_install_cloudwatch_agent: - command: | - if ! command -v amazon-cloudwatch-agent-ctl &> /dev/null; then - wget -q https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm - rpm -U ./amazon-cloudwatch-agent.rpm - rm -f ./amazon-cloudwatch-agent.rpm - fi - test: "[ ! -f /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl ]" - - 02_stop_cloudwatch_agent: - command: | - /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \ - -a fetch-config \ - -m ec2 \ - -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \ - -s - ignoreErrors: true diff --git a/.github/workflows/deploy-prod 2.yml b/.github/workflows/deploy-prod 2.yml deleted file mode 100644 index ed899ee8be..0000000000 --- a/.github/workflows/deploy-prod 2.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: Deploy to Production - -on: - push: - branches: - - multitenancy - -jobs: - deploy: - runs-on: ubuntu-latest - timeout-minutes: 30 - - steps: - - name: Checkout source code - uses: actions/checkout@v3 - - - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: us-east-1 - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - - - name: Set up Docker Buildx (for multi-platform builds) - uses: docker/setup-buildx-action@v2 - - - name: Build, tag, and push image to Amazon ECR - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: finishline-production - IMAGE_TAG: ${{ github.sha }} - run: | - echo "Building Docker image for AMD64 architecture..." - - # Build for AMD64 architecture (t3.small instances are AMD64) - docker buildx build \ - --platform linux/amd64 \ - --tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \ - --tag $ECR_REGISTRY/$ECR_REPOSITORY:latest \ - --push \ - . - - echo "✅ Image pushed successfully" - echo "Image: $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" - - - name: Update Dockerrun.aws.json - env: - ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: finishline-production - IMAGE_TAG: ${{ github.sha }} - run: | - # Create a deployment-specific Dockerrun.aws.json with the commit SHA - cat > Dockerrun.aws.json < { + return axios.post(apiUrls.calendarDeleteEventType(eventTypeId)); +}; + export const getAllEvents = () => { return axios.get(apiUrls.calendarEvents(), { transformResponse: (data) => JSON.parse(data).map(eventTransformer) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index d86d02dd6c..60410a6bf9 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -26,6 +26,7 @@ import { getAllEventTypes, postCreateEventType, postEditEventType, + postDeleteEventType, markUserConfirmed, getSingleEvent, getAllEvents, @@ -231,6 +232,21 @@ export const useEditEventType = (eventTypeId: string) => { ); }; +export const useDeleteEventType = () => { + const qc = useQueryClient(); + return useMutation( + async (eventTypeId: string) => { + const { data } = await postDeleteEventType(eventTypeId); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries(EVENT_TYPE_KEY); + } + } + ); +}; + export const useMarkUserConfirmed = (id: string) => { const user = useCurrentUser(); const queryClient = useQueryClient(); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 7e717e4015..7a269dccce 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -15,7 +15,8 @@ import { useAllCalendars, useCreateCalendar, useEditCalendar, - useAllEventTypes + useAllEventTypes, + useDeleteEventType } from '../../../hooks/calendar.hooks'; import ShopModal from './Shop/ShopModal'; import CreateCalendarModal from './Calendar/CreateCalendarModal'; @@ -26,6 +27,7 @@ import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; import CreateEventTypeModal from './EventType/CreateEventTypeModal'; import EditEventTypeModal from './EventType/EditEventTypeModal'; +import DeleteEventTypeModal from './EventType/DeleteEventTypeModal'; import { Shop, EventType, Calendar } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import NERDeleteModal from '../../../components/NERDeleteModal'; @@ -59,6 +61,7 @@ const AdminToolsScheduleConfig: React.FC = () => { const { mutateAsync: deleteMachinery } = useDeleteMachinery(); const { mutateAsync: deleteShop } = useDeleteShop(); const { mutateAsync: deleteCalendar } = useDeleteCalendar(); + const { mutateAsync: deleteEventType } = useDeleteEventType(); const toast = useToast(); const handleDeleteMachinery = async () => { @@ -106,6 +109,21 @@ const AdminToolsScheduleConfig: React.FC = () => { } }; + const handleEventTypeDelete = async () => { + if (!eventTypeToDelete) return; + setEventTypeToDelete(undefined); + try { + await deleteEventType(eventTypeToDelete.eventTypeId); + toast.success('Event type deleted successfully'); + } catch (e: unknown) { + if (e instanceof Error) { + toast.error(e.message, 3000); + } else { + toast.error('Failed to delete event type', 3000); + } + } + }; + const [openCreate, setOpenCreate] = useState(false); const [openCreateMachinery, setOpenCreateMachinery] = useState(false); const [editMachinery, setEditMachinery] = useState<{ machineryId: string; shopId: string } | null>(null); @@ -114,6 +132,7 @@ const AdminToolsScheduleConfig: React.FC = () => { const [shopToDelete, setShopToDelete] = useState(undefined); const [openCreateEventType, setOpenCreateEventType] = useState(false); const [editingEventType, setEditingEventType] = useState(null); + const [eventTypeToDelete, setEventTypeToDelete] = useState(undefined); const [calendarToDelete, setCalendarToDelete] = useState(undefined); const [openCreateCalendar, setOpenCreateCalendar] = useState(false); const [openEditCalendar, setOpenEditCalendar] = useState(false); @@ -270,14 +289,9 @@ const AdminToolsScheduleConfig: React.FC = () => { setEventTypeToDelete(eventType)} > @@ -592,6 +606,14 @@ const AdminToolsScheduleConfig: React.FC = () => { {editingEventType && ( setEditingEventType(null)} eventType={editingEventType} /> )} + + {/* Delete Event Type Modal */} + setEventTypeToDelete(undefined)} + eventType={eventTypeToDelete} + onFormSubmit={handleEventTypeDelete} + /> ); }; diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx new file mode 100644 index 0000000000..0e0cf42f46 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { FieldValues, useForm } from 'react-hook-form'; +import { Typography } from '@mui/material'; +import NERFormModal from '../../../../components/NERFormModal'; +import { EventType } from 'shared'; + +interface DeleteEventTypeModalProps { + open: boolean; + onHide: () => void; + eventType: EventType | undefined; + onFormSubmit: () => void; +} + +const DeleteEventTypeModal: React.FC = ({ + open, + onHide, + eventType, + onFormSubmit +}: DeleteEventTypeModalProps) => { + const { handleSubmit, reset } = useForm({ + mode: 'onChange' + }); + + return ( + + + Are you sure you want to delete event type "{eventType?.name || ''}"? + + This action cannot be undone! + + ); +}; + +export default DeleteEventTypeModal; + diff --git a/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx index 53e45168f1..7d70db9f45 100644 --- a/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx +++ b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx @@ -48,8 +48,7 @@ const EventSummaryModal: React.FC = ({ const handleDelete = async () => { try { await deleteEvent(); - setShowDeleteModal(false); - toast.success('Deleted Successfully'); + history.push(routes.CALENDAR); } catch (e: unknown) { if (e instanceof Error) { toast.error(e.message, 3000); diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index f983a56c7b..9a501b6114 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -3,7 +3,7 @@ * See the LICENSE file in the repository root folder for details. */ import { useState } from 'react'; -import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button, IconButton } from '@mui/material'; +import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { Event } from 'shared'; import MonthSelector from '../CalendarPage/CalendarComponents/MonthSelector'; @@ -12,12 +12,10 @@ import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../ import { useAllEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; -import { useToast } from '../../hooks/toasts.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import EventSummaryModal from '../CalendarPage/EventSummaryModal'; import { useAllTeamTypes } from '../../hooks/team-types.hooks'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; -import NERModal from '../../components/NERModal'; const NewCalendarPage = () => { const theme = useTheme(); @@ -32,7 +30,6 @@ const NewCalendarPage = () => { const { isLoading, isError, error, data: allEvents } = useAllEvents(); const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); - const toast = useToast(); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); if (isLoading || !allEvents) return ; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index f761c2f10c..afdef32a60 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -457,9 +457,10 @@ const calendarCalendars = () => `${calendar()}/calendars`; const calendarEventTypes = () => `${calendar()}/event-types`; const calendarCreateEventType = () => `${calendar()}/event-type/create`; const calendarEditEventType = (eventTypeId: string) => `${calendar()}/event-type/${eventTypeId}/edit`; +const calendarDeleteEventType = (eventTypeId: string) => `${calendar()}/event-type/${eventTypeId}/delete`; const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id}/confirm-schedule`; const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; -const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}`; +const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; /**************** Other Endpoints ****************/ @@ -785,6 +786,7 @@ export const apiUrls = { calendarEventTypes, calendarCreateEventType, calendarEditEventType, + calendarDeleteEventType, version }; From b35aa3f06d60ebb88e6c889b3b68660bbf31abee Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 10 Dec 2025 16:56:29 -0500 Subject: [PATCH 313/477] #3774 fixing linting issues --- .../ScheduleConfig/EventType/DeleteEventTypeModal.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx index 0e0cf42f46..dc187bfce1 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { FieldValues, useForm } from 'react-hook-form'; +import { useForm } from 'react-hook-form'; import { Typography } from '@mui/material'; import NERFormModal from '../../../../components/NERFormModal'; import { EventType } from 'shared'; @@ -41,4 +41,3 @@ const DeleteEventTypeModal: React.FC = ({ }; export default DeleteEventTypeModal; - From 654f4cda86594dfbe8cc9e1e09d7dce2363f70b5 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Wed, 10 Dec 2025 18:29:36 -0500 Subject: [PATCH 314/477] #3774 fixed requested changes with delete event type --- src/backend/src/routes/calendar.routes.ts | 2 +- .../AdminToolsScheduleConfig.tsx | 6 +-- .../EventType/DeleteEventTypeModal.tsx | 43 ------------------- 3 files changed, 4 insertions(+), 47 deletions(-) delete mode 100644 src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 9321725fe7..f5ddb6e241 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -151,7 +151,7 @@ calendarRouter.post( CalendarController.setStatus ); -calendarRouter.delete('/event/:eventId', CalendarController.deleteEvent); +calendarRouter.delete('/event/:eventId/delete', CalendarController.deleteEvent); calendarRouter.get('/event/:eventId', CalendarController.getSingleEvent); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx index 7a269dccce..3ce50f5d62 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/AdminToolsScheduleConfig.tsx @@ -27,7 +27,6 @@ import CreateMachineryModal from './Machinery/CreateMachineryModal'; import EditMachineryModal from './Machinery/EditMachineryModal'; import CreateEventTypeModal from './EventType/CreateEventTypeModal'; import EditEventTypeModal from './EventType/EditEventTypeModal'; -import DeleteEventTypeModal from './EventType/DeleteEventTypeModal'; import { Shop, EventType, Calendar } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import NERDeleteModal from '../../../components/NERDeleteModal'; @@ -608,10 +607,11 @@ const AdminToolsScheduleConfig: React.FC = () => { )} {/* Delete Event Type Modal */} - setEventTypeToDelete(undefined)} - eventType={eventTypeToDelete} + formId="delete-event-type-form" + dataType={`event type "${eventTypeToDelete?.name || ''}"`} onFormSubmit={handleEventTypeDelete} /> diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx deleted file mode 100644 index dc187bfce1..0000000000 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/DeleteEventTypeModal.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react'; -import { useForm } from 'react-hook-form'; -import { Typography } from '@mui/material'; -import NERFormModal from '../../../../components/NERFormModal'; -import { EventType } from 'shared'; - -interface DeleteEventTypeModalProps { - open: boolean; - onHide: () => void; - eventType: EventType | undefined; - onFormSubmit: () => void; -} - -const DeleteEventTypeModal: React.FC = ({ - open, - onHide, - eventType, - onFormSubmit -}: DeleteEventTypeModalProps) => { - const { handleSubmit, reset } = useForm({ - mode: 'onChange' - }); - - return ( - - - Are you sure you want to delete event type "{eventType?.name || ''}"? - - This action cannot be undone! - - ); -}; - -export default DeleteEventTypeModal; From e880f53fe6fb6fbe2ae25cc302670376d8fb2285 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Wed, 10 Dec 2025 18:53:41 -0500 Subject: [PATCH 315/477] added modal and logic for uploading and downloading documents --- .../src/controllers/calendar.controllers.ts | 81 +- .../src/prisma-query-args/event.query-args.ts | 3 +- .../20251101233144_calendar/migration.sql | 33 +- src/backend/src/prisma/schema.prisma | 24 +- src/backend/src/prisma/seed.ts | 4 - src/backend/src/routes/calendar.routes.ts | 21 +- src/backend/src/services/calendar.services.ts | 114 ++- .../src/services/notifications.services.ts | 2 +- .../src/transformers/calendar.transformer.ts | 11 +- src/backend/src/utils/calendar.utils.ts | 43 +- src/backend/src/utils/slack.utils.ts | 2 +- src/backend/tests/test-utils.ts | 1 - src/backend/tests/unit/calendar.test.ts | 53 +- src/frontend/src/apis/calendar.api.ts | 39 +- src/frontend/src/hooks/calendar.hooks.ts | 143 ++- .../pages/CalendarPage/EventCreateModal.tsx | 320 ------ .../FinalizeEventDetailsModal.tsx | 4 +- .../EventSummaryModalDetails.tsx | 4 +- .../Components/CreateEventModal.tsx | 16 + .../Components/EditEventModal.tsx | 18 + .../NewCalendarPage/Components/EventModal.tsx | 912 ++++++++++++++++++ .../pages/NewCalendarPage/NewCalendarPage.tsx | 79 +- .../test-data/design-reviews.stub.ts | 8 +- src/frontend/src/utils/urls.ts | 8 + src/shared/src/types/calendar-types.ts | 19 +- 25 files changed, 1523 insertions(+), 439 deletions(-) delete mode 100644 src/frontend/src/pages/CalendarPage/EventCreateModal.tsx create mode 100644 src/frontend/src/pages/NewCalendarPage/Components/CreateEventModal.tsx create mode 100644 src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx create mode 100644 src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 51258df66a..53040d2839 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -1,6 +1,7 @@ import { NextFunction, Request, Response } from 'express'; import CalendarService from '../services/calendar.services'; import { getCurrentUserWithUserSettings } from '../utils/auth.utils'; +import { HttpException } from '../utils/errors.utils'; export default class CalendarController { static async createEventType(req: Request, res: Response, next: NextFunction) { @@ -266,34 +267,41 @@ export default class CalendarController { const { title, eventTypeId, - memberIds, + requiredMemberIds, + optionalMemberIds, teamIds, teamTypeId, shopIds, machineryIds, workPackageIds, - documentIds, scheduleSlot, - questionDocument, + questionDocumentLink, location, zoomLink, description } = req.body; + const parsedScheduleSlot = scheduleSlot.map((slot: any) => ({ + ...slot, + startTime: slot.startTime ? new Date(slot.startTime) : undefined, + endTime: slot.endTime ? new Date(slot.endTime) : undefined, + initialDateScheduled: new Date(slot.initialDateScheduled) + })); + const event = await CalendarService.createEvent( req.currentUser, title, eventTypeId, req.organization, - memberIds, + requiredMemberIds, + optionalMemberIds, shopIds, machineryIds, teamIds, workPackageIds, - documentIds, - scheduleSlot, + parsedScheduleSlot, teamTypeId, - questionDocument, + questionDocumentLink, location, zoomLink, description @@ -318,13 +326,20 @@ export default class CalendarController { shopIds, machineryIds, workPackageIds, - documentIds, + documents, scheduleSlot, - questionDocument, + questionDocumentLink, location, zoomLink } = req.body; + const parsedScheduleSlot = scheduleSlot.map((slot: any) => ({ + ...slot, + startTime: slot.startTime ? new Date(slot.startTime) : undefined, + endTime: slot.endTime ? new Date(slot.endTime) : undefined, + initialDateScheduled: new Date(slot.initialDateScheduled) + })); + const event = await CalendarService.editEvent( req.currentUser, eventId, @@ -338,10 +353,10 @@ export default class CalendarController { machineryIds, teamIds, workPackageIds, - documentIds, - scheduleSlot, + documents, + parsedScheduleSlot, teamTypeId, - questionDocument, + questionDocumentLink, location, zoomLink ); @@ -351,6 +366,39 @@ export default class CalendarController { } } + static async uploadDocument(req: Request, res: Response, next: NextFunction) { + try { + const { file } = req; + const { eventId } = req.params; + if (!file) throw new HttpException(400, 'Invalid or undefined document data'); + const receipt = await CalendarService.uploadDocument(eventId, file, req.currentUser, req.organization); + const isProd = process.env.NODE_ENV === 'production'; + const origin = isProd ? 'https://finishlinebyner.com' : 'http://localhost:3000'; + + res.header('Access-Control-Allow-Origin', origin); + res.status(200).json(receipt); + } catch (error: unknown) { + next(error); + } + } + + static async downloadDocument(req: Request, res: Response, next: NextFunction) { + try { + const { fileId } = req.params; + + const imageData = await CalendarService.downloadDocument(fileId); + + // Set the appropriate headers for the HTTP response + res.setHeader('content-type', String(imageData.type)); + res.setHeader('content-length', imageData.buffer.length); + + // Send the Buffer as the response body + res.status(200).send(imageData.buffer); + } catch (error: unknown) { + next(error); + } + } + static async approveEvent(req: Request, res: Response, next: NextFunction) { try { const { eventId } = req.params; @@ -451,4 +499,13 @@ export default class CalendarController { next(error); } } + + static async getAllEventTypes(req: Request, res: Response, next: NextFunction) { + try { + const events = await CalendarService.getAllEventTypes(req.organization); + res.status(200).json(events); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/prisma-query-args/event.query-args.ts b/src/backend/src/prisma-query-args/event.query-args.ts index c8524dd867..bfaeac073a 100644 --- a/src/backend/src/prisma-query-args/event.query-args.ts +++ b/src/backend/src/prisma-query-args/event.query-args.ts @@ -56,6 +56,7 @@ export const getEventQueryArgs = (organizationId: string) => }, approvalRequiredBy: getUserQueryArgs(organizationId), scheduledTimes: true, - notificationSlackThreads: true + notificationSlackThreads: true, + documents: true } }); diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index a4f2bcf242..e8f58c58f3 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -52,6 +52,20 @@ CREATE TABLE "public"."Schedule_Slot" ( CONSTRAINT "Schedule_Slot_pkey" PRIMARY KEY ("scheduleSlotId") ); +-- CreateTable +CREATE TABLE "Document" ( + "documentId" TEXT NOT NULL, + "googleFileId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "deletedByUserId" TEXT, + "dateDeleted" TIMESTAMP(3), + "createdByUserId" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "documentEventId" TEXT NOT NULL, + + CONSTRAINT "Document_pkey" PRIMARY KEY ("documentId") +); + -- CreateTable CREATE TABLE "public"."Event" ( "eventId" TEXT NOT NULL, @@ -66,7 +80,7 @@ CREATE TABLE "public"."Event" ( "location" TEXT, "zoomLink" TEXT, "documentIds" TEXT[], - "questionDocument" TEXT, + "questionDocumentLink" TEXT, "description" TEXT, "teamTypeId" TEXT, @@ -214,6 +228,21 @@ CREATE INDEX "_confirmedEventAttendee_B_index" ON "public"."_confirmedEventAtten -- CreateIndex CREATE INDEX "_deniedEventAttendee_B_index" ON "public"."_deniedEventAttendee"("B"); +-- CreateIndex +CREATE UNIQUE INDEX "Document_googleFileId_key" ON "Document"("googleFileId"); + +-- CreateIndex +CREATE INDEX "Document_documentEventId_idx" ON "Document"("documentEventId"); + +-- AddForeignKey +ALTER TABLE "Document" ADD CONSTRAINT "Document_deletedByUserId_fkey" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Document" ADD CONSTRAINT "Document_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Document" ADD CONSTRAINT "Document_documentEventId_fkey" FOREIGN KEY ("documentEventId") REFERENCES "Event"("eventId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "public"."_requiredEventAttendee" ADD CONSTRAINT "_requiredEventAttendee_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; @@ -471,7 +500,7 @@ INSERT INTO "public"."Event" ( "location", "zoomLink", "documentIds", - "questionDocument", + "questionDocumentLink", "description", "status", "teamTypeId" diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index a960c28097..617c2a6cb3 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -270,6 +270,8 @@ model User { optionalEvents Event[] @relation(name: "optionalEventAttendee") confirmedEvents Event[] @relation(name: "confirmedEventAttendee") deniedEvents Event[] @relation(name: "deniedEventAttendee") + deletedDocuments Document[] @relation(name: "deletedDocuments") + createdDocuments Document[] @relation(name: "documentsCreatedBy") } model Role { @@ -1030,6 +1032,22 @@ model Schedule_Slot { @@index([initialDateScheduled, endDate]) } +model Document { + documentId String @id @default(uuid()) + googleFileId String @unique + name String + deletedByUserId String? + deletedBy User? @relation(name: "deletedDocuments", fields: [deletedByUserId], references: [userId]) + dateDeleted DateTime? + createdBy User @relation(name: "documentsCreatedBy", fields: [createdByUserId], references: [userId]) + createdByUserId String + dateCreated DateTime @default(now()) + documentEventId String + documentEvent Event @relation(fields: [documentEventId], references: [eventId]) + + @@index([documentEventId]) +} + model Event { eventId String @id @default(uuid()) dateCreated DateTime @default(now()) @@ -1042,8 +1060,6 @@ model Event { eventTypeId String eventType Event_Type @relation(fields: [eventTypeId], references: [eventTypeId]) approved Boolean @default(false) - // when approval is false, approved by holds who needs to approve the event - // when approval is true, approved by holds who actually approved the event approvalRequiredFromUserId String? approvalRequiredBy User? @relation(fields: [approvalRequiredFromUserId], references: [userId], name: "eventApprovalRequiredBy") scheduledTimes Schedule_Slot[] @@ -1059,9 +1075,9 @@ model Event { shops Shop[] machinery Machinery[] workPackages Work_Package[] - documentIds String[] + documents Document[] status Event_Status - questionDocument String? + questionDocumentLink String? description String? notificationSlackThreads Message_Info[] } diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 4f89b4a76f..ec9b1e092d 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3272,7 +3272,6 @@ const performSeed: () => Promise = async () => { [], [], [], - [], [ { days: [DayOfWeek.MONDAY], @@ -3301,7 +3300,6 @@ const performSeed: () => Promise = async () => { [], [], [workPackage1.id], - ['doc1', 'doc2'], [ { days: [DayOfWeek.TUESDAY], @@ -3330,7 +3328,6 @@ const performSeed: () => Promise = async () => { [electronicsLab.shopId], [printer.machineryId], [workPackage3.id], - [], [ { days: [DayOfWeek.WEDNESDAY], @@ -3359,7 +3356,6 @@ const performSeed: () => Promise = async () => { [], [ironMachine.machineryId], [], - [], [ { days: [DayOfWeek.THURSDAY], diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 0dd576674f..fb89555c77 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -2,9 +2,13 @@ import express from 'express'; import { body, param } from 'express-validator'; import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek, isEventStatus } from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; +import multer, { memoryStorage } from 'multer'; +import { MAX_FILE_SIZE } from 'shared'; const calendarRouter = express.Router(); +const upload = multer({ limits: { fileSize: MAX_FILE_SIZE }, storage: memoryStorage() }); + calendarRouter.post( '/create', nonEmptyString(body('name')), @@ -81,9 +85,7 @@ calendarRouter.post( body('machineryIds.*').isString(), body('workPackageIds').isArray(), body('workPackageIds.*').isString(), - body('documentIds').isArray(), - body('documentIds.*').isString(), - body('questionDocument').optional().isString(), + body('questionDocumentLink').optional().isString(), body('description').optional().isString(), body('scheduleSlot').isArray(), body('scheduleSlot.*.days').isArray(), @@ -116,9 +118,10 @@ calendarRouter.post( body('machineryIds.*').isString(), body('workPackageIds').isArray(), body('workPackageIds.*').isString(), - body('documentIds').isArray(), - body('documentIds.*').isString(), - body('questionDocument').optional().isString(), + body('documents').isArray(), + nonEmptyString(body('documents.*.name')), + nonEmptyString(body('documents.*.googleFileId')), + body('questionDocumentLink').optional().isString(), body('description').optional().isString(), body('scheduleSlot').isArray(), body('scheduleSlot.*.days').isArray(), @@ -132,6 +135,10 @@ calendarRouter.post( CalendarController.editEvent ); +calendarRouter.get('/document/:fileId', CalendarController.downloadDocument); + +calendarRouter.post('/event/:eventId/upload-document', upload.single('pdf'), CalendarController.uploadDocument); + calendarRouter.post('/event/:eventId/approve', CalendarController.approveEvent); calendarRouter.post( @@ -157,6 +164,8 @@ calendarRouter.get('/event/:eventId', CalendarController.getSingleEvent); calendarRouter.get('/events', CalendarController.getAllEvents); +calendarRouter.get('/event-types', CalendarController.getAllEventTypes); + calendarRouter.post('/machinery/create', nonEmptyString(body('name')), validateInputs, CalendarController.createMachinery); calendarRouter.post( diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 4c25c80d7d..2887a1ce4a 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -13,12 +13,15 @@ import { FilterArgs, Machinery, AvailabilityCreateArgs, - EventStatus + EventStatus, + EventDocumentCreateArgs, + isGuest } from 'shared'; import prisma from '../prisma/prisma'; import { AccessDeniedAdminOnlyException, AccessDeniedException, + AccessDeniedGuestException, DeletedException, HttpException, InvalidOrganizationException, @@ -41,6 +44,7 @@ import { buildScheduledTimesOverlap, checkEventConflicts, isUserOnEvent, + removeDeletedEventDocuments, validateEventTypeConfiguration } from '../utils/calendar.utils'; import { UserWithSettings } from '../utils/auth.utils'; @@ -53,6 +57,7 @@ import { sendSlackEventConfirmNotification } from '../utils/slack.utils'; import { sendEventPopUp } from '../utils/pop-up.utils'; +import { downloadFile, uploadFile } from '../utils/google-integration.utils'; export default class CalendarService { /** @@ -227,9 +232,8 @@ export default class CalendarService { * @param shopIds An array of shops associated with the event. * @param machineryIds An array of machinery associated with the event. * @param workPackageIds An array of work packages associated with the event. - * @param documentIds An array of documents associated with the event. * @param scheduleSlots An array of schedule slots associated with the event. - * @param questionDocument The link to the question document. + * @param questionDocumentLink The link to the question document. * @param location Location of the event. * @param zoomLink Zoom Link if the event is online. * @param description Describes the event. @@ -250,10 +254,9 @@ export default class CalendarService { shopIds: string[], machineryIds: string[], workPackageIds: string[], - documentIds: string[], scheduleSlot: ScheduleSlotCreateArgs[], teamTypeId?: string, - questionDocument?: string, + questionDocumentLink?: string, location?: string, zoomLink?: string, description?: string @@ -284,12 +287,12 @@ export default class CalendarService { shopIds, machineryIds, workPackageIds, - documentIds, + documents: [], scheduleSlot, teamTypeId, location, zoomLink, - questionDocument, + questionDocumentLink, description }); @@ -447,7 +450,6 @@ export default class CalendarService { workPackages: { connect: workPackageIds.map((workPackageId) => ({ workPackageId })) }, - documentIds, scheduledTimes: { create: scheduleSlot.map((s) => ({ days: s.days, @@ -464,7 +466,7 @@ export default class CalendarService { approvalRequiredFromUserId: hasConflict ? approverUserId : null, location, zoomLink, - questionDocument, + questionDocumentLink, description }, ...getEventQueryArgs(organization.organizationId) @@ -555,9 +557,9 @@ export default class CalendarService { * @param shopIds An array of shops associated with the event. * @param machineryIds An array of machinery associated with the event. * @param workPackageIds An array of work packages associated with the event. - * @param documentIds An array of documents associated with the event. + * @param documents An array of documents associated with the event. * @param scheduleSlots An array of schedule slots associated with the event. - * @param questionDocument The link to the question document. + * @param questionDocumentLink The link to the question document. * @param location Location of the event. * @param zoomLink Zoom Link if the event is online. * @param description Describes the event. @@ -579,10 +581,10 @@ export default class CalendarService { shopIds: string[], machineryIds: string[], workPackageIds: string[], - documentIds: string[], + documents: EventDocumentCreateArgs[], scheduleSlot: ScheduleSlotCreateArgs[], teamTypeId?: string, - questionDocument?: string, + questionDocumentLink?: string, location?: string, zoomLink?: string, description?: string @@ -612,19 +614,19 @@ export default class CalendarService { shopIds, machineryIds, workPackageIds, - documentIds, + documents, scheduleSlot, teamTypeId, location, zoomLink, - questionDocument, + questionDocumentLink, description }); // question document is required if the status is scheduled or done if (foundEventType.requiresConfirmation) { if (foundEvent.status === Event_Status.SCHEDULED || foundEvent.status === Event_Status.DONE) { - if (questionDocument == null) { + if (questionDocumentLink == null) { throw new HttpException(400, 'doc template link is required for scheduled and done design reviews'); } } @@ -891,16 +893,18 @@ export default class CalendarService { ? approverUserId : null : foundEvent.approvalRequiredFromUserId, - documentIds, location, zoomLink, - questionDocument, + questionDocumentLink, description }, ...getEventQueryArgs(organization.organizationId) }); }); + //set any deleted documents with a dateDeleted + await removeDeletedEventDocuments(documents, foundEvent.documents || [], submitter); + const edittedEvent = eventTransformer(updatedEvent); if (status === Event_Status.SCHEDULED && foundEventType.sendSlackNotifications) { @@ -914,6 +918,72 @@ export default class CalendarService { return edittedEvent; } + /** + * Service function to upload a picture to the event documents folder in the NER google drive + * @param eventId id for the event we're tying the document to + * @param file The file data for the image + * @param submitter user who is uploading the document + * @param organizationId the organization the user is currently in + * @returns the google drive id for the file + */ + static async uploadDocument(eventId: string, file: Express.Multer.File, submitter: User, organization: Organization) { + if (await userHasPermission(submitter.userId, organization.organizationId, isGuest)) + throw new AccessDeniedGuestException('Guests cannot upload documents'); + + const event = await prisma.event.findUnique({ + where: { eventId } + }); + + const numDocuments = await prisma.document.count({ + where: { + documentEvent: { + eventType: { + organizationId: organization.organizationId + } + } + } + }); + + if (!event) throw new NotFoundException('Event', eventId); + if (event.dateDeleted) { + throw new DeletedException('Event', eventId); + } + if (event.userCreatedId !== submitter.userId && !isHead) { + throw new AccessDeniedException('You do not have access to upload a document for this event'); + } + + file.filename = 'document' + numDocuments; + const documentData = await uploadFile(file); + + if (!documentData?.name) { + throw new HttpException(500, 'Document Name not found'); + } + + const document = await prisma.document.create({ + data: { + googleFileId: documentData.id, + name: documentData.name, + documentEventId: eventId, + createdByUserId: submitter.userId + } + }); + + return document; + } + + /** + * Downloads the document file with the given google file id + * + * @param fileId the google file id of the document + * @returns a buffer of the image data and the image type + */ + static async downloadDocument(fileId: string) { + const fileData = await downloadFile(fileId); + + if (!fileData) throw new NotFoundException('Image File', fileId); + return fileData; + } + /** * Approve event in the database * @param submitter The user submitting the request who must be a head or above. @@ -2198,4 +2268,12 @@ export default class CalendarService { }); return events.map(eventTransformer); } + + static async getAllEventTypes(organization: Organization): Promise { + const eventTypes = await prisma.event_Type.findMany({ + where: { dateDeleted: null }, + ...getEventTypeQueryArgs(organization.organizationId) + }); + return eventTypes.map(eventTypeTransformer); + } } diff --git a/src/backend/src/services/notifications.services.ts b/src/backend/src/services/notifications.services.ts index 7f8e2414af..fad9f663b0 100644 --- a/src/backend/src/services/notifications.services.ts +++ b/src/backend/src/services/notifications.services.ts @@ -194,7 +194,7 @@ export default class NotificationsService { const messageBlock = events .map((event) => { const zoomLink = event.zoomLink ? `<${event.zoomLink}|Zoom Link>\n` : ''; - const questionDocLink = event.questionDocument ? `<${event.questionDocument}|Question Doc Link>\n` : ''; + const questionDocLink = event.questionDocumentLink ? `<${event.questionDocumentLink}|Question Doc Link>\n` : ''; // Get work package names for this event const workPackageNames = event.workPackages.map((wp) => wp.wbsElement.name).join(', '); diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 1c93277bf1..ce9f412905 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -9,7 +9,8 @@ import { ScheduleSlot, EventStatus, EventPreview, - DayOfWeek + DayOfWeek, + Document } from 'shared'; import { MachineryQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { userTransformer, userWithScheduleSettingsTransformer } from './user.transformer'; @@ -18,6 +19,10 @@ import { CalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; import { EventQueryArgs } from '../prisma-query-args/event.query-args'; import { ShopQueryArgs } from '../prisma-query-args/shop.query-args'; +export const documentTransformer = (document: Prisma.DocumentGetPayload): Document => { + return { documentId: document.documentId, googleFileId: document.googleFileId, name: document.name }; +}; + export const shopTransformer = (shop: Prisma.ShopGetPayload): Shop => { return { shopId: shop.shopId, @@ -113,13 +118,13 @@ export const eventTransformer = (event: Prisma.EventGetPayload): shops: event.shops, machinery: event.machinery, workPackages: event.workPackages, - documentIds: event.documentIds, + documents: event.documents.filter((document) => !document.dateDeleted).map(documentTransformer), scheduledTimes: event.scheduledTimes.map(scheduleTimesTransformer), approved: event.approved, approvalRequiredFrom: event.approvalRequiredBy ?? undefined, location: event.location ?? undefined, zoomLink: event.zoomLink ?? undefined, - questionDocument: event.questionDocument ?? undefined, + questionDocumentLink: event.questionDocumentLink ?? undefined, description: event.description ?? undefined, status: eventStatusTransformer(event.status) }; diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index 2b03e39837..29f7187fbc 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -1,5 +1,5 @@ import { Prisma, Event_Type, Organization } from '@prisma/client'; -import { User, ScheduleSlotCreateArgs, Event } from 'shared'; +import { User, ScheduleSlotCreateArgs, Event, EventDocumentCreateArgs, Document } from 'shared'; import { InvalidEventTypeConfigurationException } from './errors.utils'; import prisma from '../prisma/prisma'; @@ -36,15 +36,19 @@ export function validateEventTypeConfiguration( shopIds: string[]; machineryIds: string[]; workPackageIds: string[]; - documentIds: string[]; + documents: EventDocumentCreateArgs[]; scheduleSlot: ScheduleSlotCreateArgs[]; teamTypeId?: string; location?: string; zoomLink?: string; - questionDocument?: string; + questionDocumentLink?: string; description?: string; } ): void { + const requiresLocationOrZoom = eventType.location || eventType.zoomLink; + + const missingBoth = !eventData.location && !eventData.zoomLink; + // Check required fields if (eventType.requiredMembers && eventData.requiredMemberIds.length === 0) { throw new InvalidEventTypeConfigurationException('at least one required member'); @@ -52,13 +56,13 @@ export function validateEventTypeConfiguration( if (eventType.teamType && !eventData.teamTypeId) { throw new InvalidEventTypeConfigurationException('a team type'); } - if ((eventType.location && !eventData.location) || (eventType.zoomLink && !eventData.zoomLink)) { + if (requiresLocationOrZoom && missingBoth) { throw new InvalidEventTypeConfigurationException('a location or zoom link'); } if (eventType.workPackage && eventData.workPackageIds.length === 0) { throw new InvalidEventTypeConfigurationException('at least one work package'); } - if (eventType.questionDocument && !eventData.questionDocument) { + if (eventType.questionDocument && !eventData.questionDocumentLink) { throw new InvalidEventTypeConfigurationException('a question document'); } if (eventData.scheduleSlot.length === 0) { @@ -87,10 +91,10 @@ export function validateEventTypeConfiguration( if (!eventType.workPackage && eventData.workPackageIds.length > 0) { throw new InvalidEventTypeConfigurationException('Event type does not allow work packages'); } - if (!eventType.questionDocument && eventData.questionDocument) { + if (!eventType.questionDocument && eventData.questionDocumentLink) { throw new InvalidEventTypeConfigurationException('Event type does not allow a question document'); } - if (!eventType.documents && eventData.documentIds.length > 0) { + if (!eventType.documents && eventData.documents.length > 0) { throw new InvalidEventTypeConfigurationException('Event type does not allow documents'); } if (!eventType.description && eventData.description) { @@ -190,3 +194,28 @@ export async function checkEventConflicts( return { hasConflict: false }; } + +/** + * This function removes any deleted documents and adds any new documents + * @param documents the new list of documents to compare against the old ones + * @param currentDocuments the current list of documents on the event that's being edited + */ +export const removeDeletedEventDocuments = async ( + newDocuments: EventDocumentCreateArgs[], + currentDocuments: Document[], + submitter: User +) => { + if (currentDocuments.length === 0) return; + const deletedDocuments = currentDocuments.filter( + (currentDocument) => !newDocuments.find((document) => document.googleFileId === currentDocument.googleFileId) + ); + + //mark any deleted documents as deleted in the database + await prisma.document.updateMany({ + where: { documentId: { in: deletedDocuments.map((document) => document.documentId) } }, + data: { + dateDeleted: new Date(), + deletedByUserId: submitter.userId + } + }); +}; diff --git a/src/backend/src/utils/slack.utils.ts b/src/backend/src/utils/slack.utils.ts index 82b550e8c7..b09da38489 100644 --- a/src/backend/src/utils/slack.utils.ts +++ b/src/backend/src/utils/slack.utils.ts @@ -444,7 +444,7 @@ export const sendEventScheduledSlackNotif = async (threads: SlackMessageThread[] const location = zoomLink && inPersonLocation ? `${inPersonLocation} and ${zoomLink}` : inPersonLocation || zoomLink || ''; const msg = `:spiral_calendar_pad: Design Review for *${drName}* has been scheduled for *${drTime}* ${location} by ${drSubmitter}`; - const docLink = event.questionDocument ? `<${event.questionDocument}|Doc Link>` : ''; + const docLink = event.questionDocumentLink ? `<${event.questionDocumentLink}|Doc Link>` : ''; const threadMsg = `The Design Review has been Scheduled! \n` + docLink; try { diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index 5f6483e0f1..5fcb302d02 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -613,7 +613,6 @@ export const createTestDesignReviewEvent = async () => { [], // shopIds [], // machineryIds [testWorkPackage.workPackageId], // workPackageIds - [], // documentIds [ { days: [DayOfWeek.TUESDAY], diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index 2e5531cb39..cadcadb415 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -831,7 +831,6 @@ describe('Calendar Tests', () => { let otherOrgUser: User; let otherOrgShop: Shop; let otherOrgMachinery: Machinery; - let document: string; beforeEach(async () => { member = await createTestUser(supermanAdmin, orgId); @@ -862,8 +861,6 @@ describe('Calendar Tests', () => { 1, otherOrg ); - - document = 'Test Document'; }); it('succeeds for admin with valid inputs', async () => { @@ -889,7 +886,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -909,13 +905,12 @@ describe('Calendar Tests', () => { expect(result.machinery).toHaveLength(1); expect(result.machinery[0].machineryId).toBe(machinery.machineryId); expect(result.workPackages).toHaveLength(0); - expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); expect(result.teamType).toBe(undefined); expect(result.approved).toBe(true); expect(result.approvalRequiredFrom).toBe(undefined); - expect(result.questionDocument).toBe('https://example.com/questions.pdf'); + expect(result.questionDocumentLink).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); expect(result.zoomLink).toBe('https://zoom.us/j/123456789'); expect(result.description).toBe('Weekly team synchronization meeting'); @@ -945,7 +940,6 @@ describe('Calendar Tests', () => { [], [], [], - [], scheduleSlots ) ).rejects.toThrow(new NotFoundException('Event Type', 'non-existent-event-type-id')); @@ -975,7 +969,6 @@ describe('Calendar Tests', () => { [shop.shopId], [], [], - [], scheduleSlots ) ).rejects.toThrow(new InvalidOrganizationException('Event Type')); @@ -1004,7 +997,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1022,12 +1014,11 @@ describe('Calendar Tests', () => { expect(result.shops).toHaveLength(1); expect(result.machinery).toHaveLength(1); expect(result.workPackages).toHaveLength(0); - expect(result.documentIds).toHaveLength(1); expect(result.scheduledTimes).toHaveLength(1); expect(result.teamType).toBe(undefined); expect(result.approved).toBe(true); expect(result.approvalRequiredFrom).toBeUndefined(); - expect(result.questionDocument).toBe('https://example.com/questions.pdf'); + expect(result.questionDocumentLink).toBe('https://example.com/questions.pdf'); expect(result.location).toBe('Conference Room A'); expect(result.zoomLink).toBe('https://zoom.us/j/123456789'); expect(result.description).toBe('Weekly team synchronization meeting'); @@ -1057,7 +1048,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1092,7 +1082,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1127,7 +1116,6 @@ describe('Calendar Tests', () => { ['non-existent-shop-id'], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1162,7 +1150,6 @@ describe('Calendar Tests', () => { [otherOrgShop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1197,7 +1184,6 @@ describe('Calendar Tests', () => { [shop.shopId], [otherOrgMachinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1238,7 +1224,6 @@ describe('Calendar Tests', () => { [deletedShop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1286,7 +1271,6 @@ describe('Calendar Tests', () => { [shop.shopId], [deletedMachinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1302,8 +1286,6 @@ describe('Calendar Tests', () => { it('Succeeds and gets all events', async () => { const member = await createTestUser(supermanAdmin, orgId); - const document = 'Test Document'; - const scheduleSlots = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -1326,7 +1308,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1346,7 +1327,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1365,8 +1345,6 @@ describe('Calendar Tests', () => { it('Succeeds and gets all events within a timeframe', async () => { const member = await createTestUser(supermanAdmin, orgId); - const document = 'Test Document'; - const scheduleSlots = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -1389,7 +1367,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1409,7 +1386,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1441,7 +1417,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots2, undefined, 'https://example.com/questions.pdf', @@ -1461,8 +1436,6 @@ describe('Calendar Tests', () => { const member = await createTestUser(supermanAdmin, orgId); const member2 = await createTestUser(wonderwomanGuest, orgId); - const document = 'Test Document'; - const scheduleSlots = [ { days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], @@ -1485,7 +1458,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1505,7 +1477,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1537,7 +1508,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - [document], scheduleSlots2, undefined, 'https://example.com/questions.pdf', @@ -1720,7 +1690,6 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - ['document'], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1789,7 +1758,7 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - ['document'], + [], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1814,7 +1783,7 @@ describe('Calendar Tests', () => { ['non-existent-shop-id'], [machinery.machineryId], [], - ['document'], + [], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1845,7 +1814,7 @@ describe('Calendar Tests', () => { [deletedShop.shopId], [machinery.machineryId], [], - ['document'], + [], scheduleSlots, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1869,7 +1838,7 @@ describe('Calendar Tests', () => { [shop.shopId], ['non-existent-machinery-id'], [], - ['document'], + [], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1900,7 +1869,7 @@ describe('Calendar Tests', () => { [shop.shopId], [deletedMachinery.machineryId], [], - ['document'], + [], scheduleSlots, undefined, 'https://example.com/questions.pdf', @@ -1936,7 +1905,7 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - ['doc2', 'doc3'], + [], newScheduleSlots, undefined, 'https://updated.com/questions.pdf', @@ -1951,10 +1920,9 @@ describe('Calendar Tests', () => { expect(result.requiredMembers[0].userId).toBe(newMember.userId); expect(result.optionalMembers).toHaveLength(1); expect(result.optionalMembers[0].userId).toBe(adminUser.userId); - expect(result.documentIds).toEqual(['doc2', 'doc3']); expect(result.approved).toBe(true); expect(result.approvalRequiredFrom).toBe(undefined); - expect(result.questionDocument).toBe('https://updated.com/questions.pdf'); + expect(result.questionDocumentLink).toBe('https://updated.com/questions.pdf'); expect(result.location).toBe('Updated Location'); expect(result.zoomLink).toBe('https://zoom.us/updated'); expect(result.description).toBe('Updated description'); @@ -1989,12 +1957,11 @@ describe('Calendar Tests', () => { [shop.shopId], [machinery.machineryId], [], - ['doc2', 'doc3'], scheduleSlots, undefined, 'https://updated.com/questions.pdf', 'Updated Location', - 'https://zoom.us/updated', + undefined, 'Updated description' ); }); diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 7078ec43b2..d2eb487443 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -2,6 +2,7 @@ import axios from '../utils/axios'; import { apiUrls } from '../utils/urls'; import { Shop, Machinery, AvailabilityCreateArgs, Event, EventStatus, Calendar } from 'shared'; import { eventTransformer } from './transformers/calendar.transformer'; +import { EventCreateArgs } from '../hooks/calendar.hooks'; export const getAllCalendars = () => { return axios.get(apiUrls.calendarCalendars(), { @@ -115,8 +116,14 @@ export const getAllEvents = () => { }); }; +export const getAllEventTypes = () => { + return axios.get(apiUrls.calendarEventTypes(), { + transformResponse: (data) => JSON.parse(data).map(eventTransformer) + }); +}; + export const deleteEvent = async (id: string) => { - return axios.delete(apiUrls.calendarDeleteEvent(id)); + return axios.post(apiUrls.calendarDeleteEvent(id)); }; export const setEventStatus = async (id: string, payload: { status: EventStatus }) => { @@ -128,3 +135,33 @@ export const setEventStatus = async (id: string, payload: { status: EventStatus export const postDeleteCalendar = async (id: string) => { return axios.post(apiUrls.calendarDeleteCalendar(id)); }; + +export const postCreateEvent = async (payload: EventCreateArgs) => { + return axios.post(apiUrls.calendarCreateEvent(), payload, { + transformResponse: (data) => eventTransformer(JSON.parse(data)) + }); +}; + +/** + * Upload a document + * + * @param payload Payload containing the document data + */ +export const uploadSingleDocument = (file: File, id: string) => { + const formData = new FormData(); + formData.append('pdf', file); + return axios.post(apiUrls.calendarUploadDocument(id), formData); +}; + +/** + * Downloads a PDF file from google drive + * + * @param fileId the google id of the file to download + * @returns the downloaded file as a Blob + */ +export const downloadDocumentPdf = async (fileId: string): Promise => { + const response = await axios.get(apiUrls.calendarPDFById(fileId), { + responseType: 'blob' // Simply use 'blob' for PDF downloads + }); + return response.data; // response.data is already a Blob +}; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 1d157f0b7a..c73c92d5c2 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -1,5 +1,14 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Shop, Machinery, Calendar, AvailabilityCreateArgs, Event, EventStatus } from 'shared'; +import { + Shop, + Machinery, + Calendar, + AvailabilityCreateArgs, + Event, + EventStatus, + ScheduleSlotCreateArgs, + EventType +} from 'shared'; import { getAllShops, postCreateShop, @@ -18,14 +27,45 @@ import { getSingleEvent, getAllEvents, deleteEvent, - setEventStatus + setEventStatus, + postCreateEvent, + getAllEventTypes, + uploadSingleDocument, + downloadDocumentPdf } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; +import { PDFDocument } from 'pdf-lib'; +import saveAs from 'file-saver'; export const MACHINERY_KEY = ['machinery'] as const; const SHOP_KEY = ['shops'] as const; const CALENDAR_KEY = ['calendars'] as const; +export interface EventCreateArgs { + title: string; + eventTypeId: string; + requiredMemberIds: string[]; + optionalMemberIds: string[]; + teamIds: string[]; + teamTypeId?: string; + location?: string; + zoomLink?: string; + shopIds: string[]; + machineryIds: string[]; + workPackageIds: string[]; + documentIds: string[]; + questionDocument?: string; + description?: string; + scheduleSlot: ScheduleSlotCreateArgs[]; +} + +export interface DownloadDocumentsFormInput { + fileIds: string[]; + startDate: Date; + endDate: Date; + event: Event; +} + export const useAllCalendars = () => useQuery(['calendars'], async () => { const res = await getAllCalendars(); @@ -232,6 +272,13 @@ export const useAllEvents = () => { }); }; +export const useAllEventTypes = () => { + return useQuery(['eventTypes'], async () => { + const { data } = await getAllEventTypes(); + return data; + }); +}; + export const useDeleteEvent = (id: string) => { const queryClient = useQueryClient(); return useMutation( @@ -263,3 +310,95 @@ export const useSetEventStatus = (id: string) => { } ); }; + +export const useCreateEvent = () => { + const qc = useQueryClient(); + return useMutation( + async (payload) => { + const { data } = await postCreateEvent(payload); + return data; + }, + { + onSuccess: () => { + qc.invalidateQueries('events'); + } + } + ); +}; + +/** + * Custom React Hook to upload a new document. + */ +export const useUploadSingleDocument = () => { + return useMutation<{ googleFileId: string; name: string }, Error, { file: File; id: string }>( + ['events', 'upload', 'single'], + async (formData: { file: File; id: string }) => { + const { data } = await uploadSingleDocument(formData.file, formData.id); + return data; + } + ); +}; + +/** + * Custom hook that uploads many documents to a given event + * + * @returns The created document information + */ +export const useUploadManyDocuments = () => { + return useMutation<{ googleFileId: string; name: string }[], Error, { files: File[]; id: string }>( + ['events', 'upload', 'many'], + async (formData: { files: File[]; id: string }) => { + const results = []; + for (const file of formData.files) { + results.push(await uploadSingleDocument(file, formData.id)); + } + return results.map((result) => result.data); + } + ); +}; + +/** + * Custom react hook to download PDFs from google drive and combine them into a single PDF + * + * @param fileIds The google file ids to fetch the PDFs for + */ +export const useDownloadPDFOfDocuments = () => { + return useMutation(['events'], async (formData: DownloadDocumentsFormInput) => { + const promises = formData.fileIds.map((fileId) => { + return downloadDocumentPdf(fileId); + }); + + const blobs = await Promise.all(promises); + const pdfName = `${formData.startDate.toLocaleDateString()}-${formData.endDate.toLocaleDateString()}.pdf`; + + const pdfFileName = `documents-${formData.event.title}-${pdfName}`; + + await combinePdfsAndDownload(blobs, pdfFileName); + }); +}; + +/** + * Combines multiple PDF blobs into a single PDF and downloads it + * + * @param blobData an array of PDF blob data + * @param filename the name of the created PDF + */ +export const combinePdfsAndDownload = async (blobData: Blob[], filename: string) => { + const pdfDoc = await PDFDocument.create(); + + // Load and copy pages from each PDF + for (const blob of blobData) { + const arrayBuffer = await blob.arrayBuffer(); + const pdf = await PDFDocument.load(arrayBuffer); + const pages = await pdfDoc.copyPages(pdf, pdf.getPageIndices()); + + pages.forEach((page) => { + pdfDoc.addPage(page); + }); + } + + // Save and download + const pdfBytes = await pdfDoc.save(); + const pdfBlob = new Blob([new Uint8Array(pdfBytes)], { type: 'application/pdf' }); + saveAs(pdfBlob, filename); +}; diff --git a/src/frontend/src/pages/CalendarPage/EventCreateModal.tsx b/src/frontend/src/pages/CalendarPage/EventCreateModal.tsx deleted file mode 100644 index 119cf95309..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventCreateModal.tsx +++ /dev/null @@ -1,320 +0,0 @@ -/* -import NERFormModal from '../../components/NERFormModal'; -import * as yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { Controller, useForm } from 'react-hook-form'; -import { - Autocomplete, - Box, - FormControl, - FormHelperText, - FormLabel, - MenuItem, - Select, - SelectChangeEvent, - TextField, - Typography -} from '@mui/material'; -import { DatePicker } from '@mui/x-date-pickers'; -import { useToast } from '../../hooks/toasts.hooks'; -import { useEffect, useMemo, useState } from 'react'; -import { - TeamType, - WbsElementStatus, - WbsNumber, - WorkPackage, - validateWBS, - wbsNamePipe, - wbsNumComparator, - wbsPipe -} from 'shared'; -import { useCreateDesignReviews } from '../../hooks/design-reviews.hooks'; -import { useAllUsers } from '../../hooks/users.hooks'; -import ErrorPage from '../ErrorPage'; -import LoadingIndicator from '../../components/LoadingIndicator'; -import { userToAutocompleteOption } from '../../utils/teams.utils'; -import { useQuery } from '../../hooks/utils.hooks'; -import NERAutocomplete from '../../components/NERAutocomplete'; -import { useAllWorkPackages } from '../../hooks/work-packages.hooks'; - -const schema = yup.object().shape({ - date: yup.date().required('Date is required'), - startTime: yup.number().required('Start time is required'), - teamTypeId: yup.string().required('Team Type is required'), - endTime: yup - .number() - .moreThan(yup.ref('startTime'), `End time must be after the start time`) - .required('End time is required'), - wbsNum: yup.string().required('Work Package is required'), - optionalMemberIds: yup.array().of(yup.string().required()).required(), - requiredMemberIds: yup.array().of(yup.string().required()).required() -}); - -interface CreateDesignReviewFormInput { - date: Date; - startTime: number; - endTime: number; - teamTypeId: string; - requiredMemberIds: string[]; - optionalMemberIds: string[]; - wbsNum: string; -} - -interface DesignReviewCreateModalProps { - showModal: boolean; - handleClose: () => void; - teamTypes: TeamType[]; - defaultDate: Date; - defaultWbsNum?: WbsNumber; -} - -export const DesignReviewCreateModal: React.FC = ({ - showModal, - handleClose, - teamTypes, - defaultDate, - defaultWbsNum -}) => { - const query = useQuery(); - - const toast = useToast(); - const [datePickerOpen, setDatePickerOpen] = useState(false); - const [requiredMembers, setRequiredMembers] = useState([].map(userToAutocompleteOption)); - const [optionalMembers, setOptionalMembers] = useState([].map(userToAutocompleteOption)); - const { isLoading: allUsersIsLoading, isError: allUsersIsError, error: allUsersError, data: users } = useAllUsers(); - - const { - isLoading: allWorkPackagesIsLoading, - isError: allWorkPackagesIsError, - error: allWorkPackagesError, - data: allWorkPackages - } = useAllWorkPackages(); - - const { mutateAsync, isLoading } = useCreateDesignReviews(); - - const defaultFormData = useMemo(() => { - return { - date: defaultDate, - startTime: 0, - endTime: 1, - teamTypeId: '', - wbsNum: defaultWbsNum ? wbsPipe(defaultWbsNum) : query.get('wbsNum') || '', - requiredMemberIds: [], - optionalMemberIds: [] - }; - }, [defaultDate, defaultWbsNum, query]); - - const onSubmit = async (data: CreateDesignReviewFormInput) => { - try { - await mutateAsync({ - dateScheduled: data.date, - teamTypeId: data.teamTypeId, - requiredMemberIds: requiredMembers.map((member) => member.id), - optionalMemberIds: optionalMembers.map((member) => member.id), - wbsNum: validateWBS(data.wbsNum), - meetingTimes: [0] - }); - } catch (error: unknown) { - if (error instanceof Error) { - toast.error(error.message); - } - } - handleClose(); - }; - - const { - handleSubmit, - control, - reset, - setValue, - formState: { errors } - } = useForm({ - resolver: yupResolver(schema), - defaultValues: defaultFormData - }); - - useEffect(() => { - reset(defaultFormData); - }, [defaultDate, reset, defaultFormData]); - - if (allUsersIsError) return ; - if (allWorkPackagesIsError) return ; - if (allUsersIsLoading || allWorkPackagesIsLoading || !allWorkPackages || !users || isLoading) return ; - - const memberOptions = users.map(userToAutocompleteOption); - - const wbsDropdownOptions: { label: string; id: string }[] = []; - - allWorkPackages.forEach((workPackage: WorkPackage) => { - if (workPackage.status === WbsElementStatus.Active) { - wbsDropdownOptions.push({ - label: `${wbsNamePipe(workPackage)}`, - id: wbsPipe(workPackage.wbsNum) - }); - } - }); - - wbsDropdownOptions.sort((wp1, wp2) => wbsNumComparator(wp2.id, wp1.id)); - - return ( - reset({ date: defaultDate })} - handleUseFormSubmit={handleSubmit} - onFormSubmit={onSubmit} - formId="create-design-review-form" - showCloseButton - > - - Work Package - { - const onClear = () => { - setValue('wbsNum', ''); - onChange(''); - setValue('teamTypeId', ''); - }; - - const handleWorkPackageSelect = async (selectedValue: string) => { - onChange(selectedValue); - setValue('wbsNum', selectedValue); - - const workPackage = allWorkPackages.find((wp) => wbsPipe(wp.wbsNum) === selectedValue); - - if (workPackage) { - const { teamTypes } = workPackage; - - if (teamTypes.length > 0) { - const [teamType] = teamTypes; - setValue('teamTypeId', teamType ? teamType.teamTypeId : ''); - } else { - setValue('teamTypeId', ''); - } - } - }; - - return ( - { - newValue ? handleWorkPackageSelect(newValue.id) : onClear(); - }} - options={wbsDropdownOptions} - size="medium" - placeholder="Select a work package" - value={wbsDropdownOptions.find((element) => element.id === value) || null} - /> - ); - }} - /> - {errors.wbsNum?.message} - - - - Design Review Date - ( - setDatePickerOpen(false)} - onOpen={() => setDatePickerOpen(true)} - onChange={(newValue) => { - onChange(newValue ?? defaultDate); - }} - slotProps={{ - textField: { - error: !!errors.date, - helperText: errors.date?.message, - onClick: () => setDatePickerOpen(true), - inputProps: { readOnly: true }, - fullWidth: true - } - }} - /> - )} - /> - {errors.date?.message} - - - Team - ( - - )} - /> - {errors.teamTypeId?.message} - - - - Required Members - option.id === value.id} - filterSelectedOptions - multiple - id="tags-standard" - options={memberOptions} - value={requiredMembers} - onChange={(_event, newValue) => setRequiredMembers(newValue)} - getOptionLabel={(option) => option.label} - renderInput={(params) => } - /> - - - Optional Members - option.id === value.id} - filterSelectedOptions - multiple - id="tags-standard" - options={memberOptions} - value={optionalMembers} - onChange={(_event, newValue) => setOptionalMembers(newValue)} - getOptionLabel={(option) => option.label} - renderInput={(params) => } - /> - - - ); -}; -*/ diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx index 588868a2bb..454f067898 100644 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx @@ -63,7 +63,7 @@ const FinalizeEventDetailsModal = ({ ); const defaultValues = { - docTemplateLink: event.questionDocument ?? '', + docTemplateLink: event.questionDocumentLink ?? '', zoomLink: event.zoomLink ?? userScheduleSettings?.personalZoomLink ?? '', location: event.location ?? undefined }; @@ -92,7 +92,7 @@ const FinalizeEventDetailsModal = ({ useEffect(() => { if (userScheduleSettings && !event.zoomLink) { reset({ - docTemplateLink: event.questionDocument ?? '', + docTemplateLink: event.questionDocumentLink ?? '', zoomLink: userScheduleSettings.personalZoomLink ?? '', location: event.location ?? undefined }); diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx index 89d0af311b..151b7f8c28 100644 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx +++ b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx @@ -100,9 +100,9 @@ const EventSummaryModalDetails: React.FC = ({ - + - {event.questionDocument ? 'Question Document' : 'No Question Document'} + {event.questionDocumentLink ? 'Question Document' : 'No Question Document'} diff --git a/src/frontend/src/pages/NewCalendarPage/Components/CreateEventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/CreateEventModal.tsx new file mode 100644 index 0000000000..ad6a607eeb --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/Components/CreateEventModal.tsx @@ -0,0 +1,16 @@ +import EventModal, { EventRoutePayload } from './EventModal'; +import type { EventType } from 'shared'; + +interface CreateEventModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: EventRoutePayload) => void; + eventTypes: EventType[]; + defaultDate?: Date; +} + +const CreateEventModal: React.FC = (props) => { + return ; +}; + +export default CreateEventModal; diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx new file mode 100644 index 0000000000..878d1c903a --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx @@ -0,0 +1,18 @@ +import EventModal, { EventFormValues, EventRoutePayload } from './EventModal'; +import type { EventType } from 'shared'; + +export interface EditEventModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: EventRoutePayload) => void; + initialValues: Partial; + eventTypes: EventType[]; +} + +const EditEventModal: React.FC = ({ open, onClose, onSubmit, initialValues, eventTypes }) => { + return ( + + ); +}; + +export default EditEventModal; diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx new file mode 100644 index 0000000000..7bc16eecc7 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx @@ -0,0 +1,912 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { + Box, + FormControl, + FormHelperText, + MenuItem, + Select, + TextField, + Typography, + Autocomplete, + Chip, + IconButton, + Button, + Stack, + Checkbox, + FormControlLabel +} from '@mui/material'; +import { DatePicker, TimePicker } from '@mui/x-date-pickers'; +import { Controller, useForm } from 'react-hook-form'; +import * as yup from 'yup'; +import { yupResolver } from '@hookform/resolvers/yup'; +import { + DayOfWeek, + EventDocumentUploadArgs, + WbsElementStatus, + wbsNamePipe, + wbsNumComparator, + wbsPipe, + EventType +} from 'shared'; +import { useToast } from '../../../hooks/toasts.hooks'; +import { useAllUsers } from '../../../hooks/users.hooks'; +import { useAllWorkPackages } from '../../../hooks/work-packages.hooks'; +import { useAllTeams } from '../../../hooks/teams.hooks'; +import { userToAutocompleteOption } from '../../../utils/teams.utils'; +import ErrorPage from '../../ErrorPage'; +import LoadingIndicator from '../../../components/LoadingIndicator'; +import NERFormModal from '../../../components/NERFormModal'; +import CalendarTodayIcon from '@mui/icons-material/CalendarToday'; +import PeopleIcon from '@mui/icons-material/People'; +import LocationOnIcon from '@mui/icons-material/LocationOn'; +import VideocamIcon from '@mui/icons-material/Videocam'; +import WorkIcon from '@mui/icons-material/Work'; +import DescriptionIcon from '@mui/icons-material/Description'; +import BusinessIcon from '@mui/icons-material/Business'; +import { useAllTeamTypes } from '../../../hooks/team-types.hooks'; +import { ClearIcon } from '@mui/x-date-pickers'; + +export interface EventFormValues { + title: string; + eventTypeId: string; + requiredMemberIds: string[]; + optionalMemberIds: string[]; + teamIds: string[]; + teamTypeId?: string; + location?: string; + zoomLink?: string; + shopIds: string[]; + machineryIds: string[]; + workPackageIds: string[]; + documentFiles: EventDocumentUploadArgs[]; + questionDocumentLink?: string; + description?: string; + scheduleDate: Date; + startTime?: Date; + endTime?: Date; + allDay: boolean; + recurrenceNumber: number; + days: DayOfWeek[]; +} + +export interface EventRoutePayload { + title: string; + eventTypeId: string; + requiredMemberIds: string[]; + optionalMemberIds: string[]; + teamIds: string[]; + teamTypeId?: string; + location?: string; + zoomLink?: string; + shopIds: string[]; + machineryIds: string[]; + workPackageIds: string[]; + documentFiles: EventDocumentUploadArgs[]; + questionDocumentLink?: string; + description?: string; + scheduleSlot: Array<{ + days: DayOfWeek[]; + startTime?: Date; + endTime?: Date; + recurrenceNumber: number; + initialDateScheduled: Date; + allDay: boolean; + }>; +} + +const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB + +const schema = yup.object().shape({ + title: yup.string().required('Title is required'), + eventTypeId: yup.string().required('Event Type is required'), + requiredMemberIds: yup.array().of(yup.string().required()).default([]), + optionalMemberIds: yup.array().of(yup.string().required()).default([]), + teamIds: yup.array().of(yup.string().required()).default([]), + teamTypeId: yup.string().optional(), + location: yup.string().optional(), + zoomLink: yup.string().url('Must be a valid URL').optional(), + shopIds: yup.array().of(yup.string().required()).default([]), + machineryIds: yup.array().of(yup.string().required()).default([]), + workPackageIds: yup.array().of(yup.string().required()).default([]), + documentFiles: yup.array().of(yup.mixed().required()).default([]), + questionDocumentLink: yup.string().optional(), + description: yup.string().optional(), + scheduleDate: yup.date().required('Date is required'), + startTime: yup.date().when('allDay', { + is: false, + then: (schema) => schema.required('Start time is required'), + otherwise: (schema) => schema.optional() + }), + endTime: yup.date().when('allDay', { + is: false, + then: (schema) => schema.required('End time is required').min(yup.ref('startTime'), 'End time must be after start time'), + otherwise: (schema) => schema.optional() + }), + allDay: yup.boolean().required(), + recurrenceNumber: yup.number().min(1, 'Must be at least 1').required('Recurrence is required'), + days: yup.array().of(yup.mixed().required()).default([]) +}); + +export interface BaseEventModalProps { + open: boolean; + onClose: () => void; + onSubmit: (data: EventRoutePayload) => Promise | unknown; + initialValues?: Partial; + eventTypes: EventType[]; + defaultDate?: Date; +} + +const EventModal: React.FC = ({ + open, + onClose, + onSubmit, + initialValues, + eventTypes, + defaultDate = new Date() +}) => { + const toast = useToast(); + const [datePickerOpen, setDatePickerOpen] = useState(false); + const [startTimePickerOpen, setStartTimePickerOpen] = useState(false); + const [endTimePickerOpen, setEndTimePickerOpen] = useState(false); + const [showRecurringOptions, setShowRecurringOptions] = useState(false); + const [requiredMembers, setRequiredMembers] = useState>([]); + const [optionalMembers, setOptionalMembers] = useState>([]); + const [selectedTeams, setSelectedTeams] = useState>([]); + + const { isLoading: usersLoading, isError: usersError, error: usersErrorMsg, data: users } = useAllUsers(); + const { + isLoading: workPackagesLoading, + isError: workPackagesError, + error: workPackagesErrorMsg, + data: allWorkPackages + } = useAllWorkPackages(); + const { isLoading: teamsLoading, isError: teamsError, error: teamsErrorMsg, data: teams } = useAllTeams(); + const { + isLoading: teamTypesLoading, + isError: teamTypesError, + error: teamTypesErrorMsg, + data: teamTypes + } = useAllTeamTypes(); + + const defaultFormData = useMemo( + () => ({ + title: initialValues?.title ?? '', + eventTypeId: initialValues?.eventTypeId ?? '', + requiredMemberIds: initialValues?.requiredMemberIds ?? [], + optionalMemberIds: initialValues?.optionalMemberIds ?? [], + teamIds: initialValues?.teamIds ?? [], + teamTypeId: initialValues?.teamTypeId, + location: initialValues?.location, + zoomLink: initialValues?.zoomLink, + shopIds: initialValues?.shopIds ?? [], + machineryIds: initialValues?.machineryIds ?? [], + workPackageIds: initialValues?.workPackageIds ?? [], + documentFiles: initialValues?.documentFiles ?? [], + questionDocumentLink: initialValues?.questionDocumentLink, + description: initialValues?.description, + scheduleDate: initialValues?.scheduleDate ?? defaultDate, + startTime: initialValues?.startTime, + endTime: initialValues?.endTime, + allDay: initialValues?.allDay ?? false, + recurrenceNumber: initialValues?.recurrenceNumber ?? 1, + days: initialValues?.days ?? [] + }), + [initialValues, defaultDate] + ); + + const { + handleSubmit, + control, + reset, + watch, + setValue, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: defaultFormData + }); + + const frozenValuesRef = React.useRef>(defaultFormData); + + useEffect(() => { + if (open) { + frozenValuesRef.current = defaultFormData; + reset(defaultFormData); + + if (initialValues?.requiredMemberIds && users) { + const reqMembers = users + .filter((u) => initialValues.requiredMemberIds?.includes(u.userId)) + .map(userToAutocompleteOption); + setRequiredMembers(reqMembers); + } + + if (initialValues?.optionalMemberIds && users) { + const optMembers = users + .filter((u) => initialValues.optionalMemberIds?.includes(u.userId)) + .map(userToAutocompleteOption); + setOptionalMembers(optMembers); + } + + if (initialValues?.teamIds && teams) { + const teamOptions = teams + .filter((t) => initialValues.teamIds?.includes(t.teamId)) + .map((t) => ({ id: t.teamId, label: t.teamName })); + setSelectedTeams(teamOptions); + } + } else { + reset(defaultFormData); + setRequiredMembers([]); + setOptionalMembers([]); + setSelectedTeams([]); + } + }, [open, defaultFormData, reset, initialValues, users, teams]); + + const selectedEventTypeId = watch('eventTypeId'); + const selectedEventType = useMemo( + () => eventTypes.find((et) => et.eventTypeId === selectedEventTypeId), + [eventTypes, selectedEventTypeId] + ); + + const documentFiles = watch('documentFiles'); + + const isEditMode = !!frozenValuesRef.current.eventTypeId; + const computedTitle = isEditMode ? 'Edit Event' : 'Add Event'; + + const handleDocumentRemove = (index: number) => { + const currentFiles = watch('documentFiles'); + setValue( + 'documentFiles', + currentFiles.filter((_, i) => i !== index) + ); + }; + + const handleDocumentUpload = (e: React.ChangeEvent) => { + if (e.target.files) { + const currentFiles = watch('documentFiles'); + [...e.target.files].forEach((file) => { + if (file.size >= MAX_FILE_SIZE) { + toast.error(`Error uploading ${file.name}; file must be less than ${MAX_FILE_SIZE / 1024 / 1024} MB`, 5000); + } else { + setValue('documentFiles', [ + ...currentFiles, + { + file, + name: file.name, + googleFileId: '' + } + ]); + } + }); + // Clear input so same file can be uploaded again if needed + e.target.value = ''; + } + }; + + const onFormSubmit = async (data: EventFormValues) => { + try { + const submitData: EventRoutePayload = { + title: data.title, + eventTypeId: data.eventTypeId, + requiredMemberIds: requiredMembers.map((m) => m.id), + optionalMemberIds: optionalMembers.map((m) => m.id), + teamIds: selectedTeams.map((t) => t.id), + teamTypeId: data.teamTypeId, + location: data.location, + zoomLink: data.zoomLink, + shopIds: data.shopIds, + machineryIds: data.machineryIds, + workPackageIds: data.workPackageIds, + documentFiles: data.documentFiles, + questionDocumentLink: data.questionDocumentLink, + description: data.description, + scheduleSlot: [ + { + days: data.days, + startTime: data.startTime, + endTime: data.endTime, + recurrenceNumber: data.recurrenceNumber, + initialDateScheduled: data.scheduleDate, + allDay: data.allDay + } + ] + }; + + await onSubmit(submitData); + onClose(); + reset(defaultFormData); + setRequiredMembers([]); + setOptionalMembers([]); + setSelectedTeams([]); + } catch (e: unknown) { + if (e instanceof Error) toast.error(e.message); + } + }; + + if (usersError) return ; + if (workPackagesError) return ; + if (teamsError) return ; + if (teamTypesError) return ; + if ( + usersLoading || + workPackagesLoading || + teamsLoading || + teamTypesLoading || + !users || + !allWorkPackages || + !teams || + !teamTypes + ) { + return ; + } + + const memberOptions = users.map(userToAutocompleteOption); + const teamOptions = teams.map((t) => ({ id: t.teamId, label: t.teamName })); + + const workPackageOptions = allWorkPackages + .filter((wp) => wp.status === WbsElementStatus.Active) + .map((wp) => ({ + label: wbsNamePipe(wp), + id: wbsPipe(wp.wbsNum) + })) + .sort((a, b) => wbsNumComparator(b.id, a.id)); + + return ( + { + onClose(); + reset(defaultFormData); + }} + title={computedTitle} + reset={() => reset(defaultFormData)} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="event-form" + showCloseButton + > + + {/* Title Input with red placeholder styling */} + ( + + )} + /> + + {/* Event Type Tabs */} + + {eventTypes.map((et) => ( + ( + + )} + /> + ))} + + + {/* Date and Time Section */} + + + + ( + setDatePickerOpen(false)} + onOpen={() => setDatePickerOpen(true)} + onChange={(newValue) => onChange(newValue ?? defaultDate)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.scheduleDate, + onClick: () => setDatePickerOpen(true), + sx: { minWidth: 150 } + } + }} + /> + )} + /> + + {!watch('allDay') && ( + <> + ( + setStartTimePickerOpen(false)} + onOpen={() => setStartTimePickerOpen(true)} + onChange={(newValue) => onChange(newValue)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.startTime, + onClick: () => setStartTimePickerOpen(true), + sx: { width: 100 } + } + }} + /> + )} + /> + - + ( + setEndTimePickerOpen(false)} + onOpen={() => setEndTimePickerOpen(true)} + onChange={(newValue) => onChange(newValue)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.endTime, + onClick: () => setEndTimePickerOpen(true), + sx: { width: 100 } + } + }} + /> + )} + /> + + )} + + ( + onChange(e.target.checked)} />} + label="All Day" + /> + )} + /> + + + + + {/* Recurring Options */} + {showRecurringOptions && ( + + + + Repeat every + + ( + + )} + /> + + week(s) + + + + + Repeat on: + + { + const weekDays: DayOfWeek[] = [ + DayOfWeek.SUNDAY, + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SATURDAY + ]; + const dayLabels = ['S', 'M', 'T', 'W', 'TH', 'F', 'S']; + + const toggleDay = (day: DayOfWeek) => { + const currentDays = value || []; + if (currentDays.includes(day)) { + onChange(currentDays.filter((d) => d !== day)); + } else { + onChange([...currentDays, day]); + } + }; + + return ( + + {weekDays.map((day, index) => { + const isSelected = (value || []).includes(day); + return ( + + ); + })} + + ); + }} + /> + + {errors.days && ( + + {errors.days.message} + + )} + + + + Note: This event will repeat {watch('recurrenceNumber')} time(s){' '} + {watch('days').length > 0 && `on ${watch('days').join(', ')}`} + + + + )} + + + {/* Required/Optional Members Section */} + {(selectedEventType?.requiredMembers || selectedEventType?.optionalMembers) && ( + + + + {requiredMembers.map((member) => ( + setRequiredMembers((prev) => prev.filter((m) => m.id !== member.id))} + sx={{ bgcolor: 'grey.300' }} + /> + ))} + {optionalMembers.map((member) => ( + setOptionalMembers((prev) => prev.filter((m) => m.id !== member.id))} + sx={{ bgcolor: 'grey.200', opacity: 0.7 }} + /> + ))} + + {selectedEventType?.requiredMembers && ( + !requiredMembers.find((rm) => rm.id === m.id))} + onChange={(_, newValue) => { + if (newValue) setRequiredMembers((prev) => [...prev, newValue]); + }} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + sx={{ display: 'inline-flex', minWidth: 120 }} + /> + )} + + {selectedEventType?.teams && ( + !selectedTeams.find((st) => st.id === t.id))} + onChange={(_, newValue) => { + if (newValue) setSelectedTeams((prev) => [...prev, newValue]); + }} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + sx={{ display: 'inline-flex', minWidth: 120 }} + /> + )} + + + )} + + {/* Location */} + {selectedEventType?.location && ( + + + ( + + )} + /> + + )} + + {/* Zoom Link */} + {selectedEventType?.zoomLink && ( + + + ( + + )} + /> + + )} + + {/* Work Packages */} + {selectedEventType?.workPackage && ( + + + ( + value?.includes(wp.id))} + onChange={(_, newValue) => onChange(newValue.map((v) => v.id))} + getOptionLabel={(option) => option.label} + renderInput={(params) => } + sx={{ flex: 1 }} + /> + )} + /> + + )} + + {/* Team Type */} + {selectedEventType?.teamType && ( + + + ( + + )} + /> + + )} + + {/* Question Document Link */} + {selectedEventType?.questionDocument && ( + + + ( + + )} + /> + + )} + + {/* Documents */} + {selectedEventType?.documents && ( + + + + + Documents + + +
    + {documentFiles.map((docFile, index) => ( +
  • + + + {docFile.name} + + handleDocumentRemove(index)} + sx={{ + padding: '0px', + marginLeft: '2px' + }} + > + + + +
  • + ))} +
+ + {errors.documentFiles?.message} +
+
+
+ )} + {/* Description */} + {selectedEventType?.description && ( + + + ( + + )} + /> + + )} +
+
+ ); +}; +export default EventModal; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 9a501b6114..c0364cf656 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -9,15 +9,19 @@ import { Event } from 'shared'; import MonthSelector from '../CalendarPage/CalendarComponents/MonthSelector'; import CalendarDayCard from '../CalendarPage/CalendarComponents/CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; -import { useAllEvents } from '../../hooks/calendar.hooks'; +import { useAllEvents, useAllEventTypes, useCreateEvent, useUploadManyDocuments } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; import EventSummaryModal from '../CalendarPage/EventSummaryModal'; import { useAllTeamTypes } from '../../hooks/team-types.hooks'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; +import CreateEventModal from './Components/CreateEventModal'; +import { EventRoutePayload } from './Components/EventModal'; +import { useToast } from '../../hooks/toasts.hooks'; const NewCalendarPage = () => { + const toast = useToast(); const theme = useTheme(); const { data: allTeamTypes, @@ -26,14 +30,28 @@ const NewCalendarPage = () => { error: allTeamTypesError } = useAllTeamTypes(); + const { + data: eventTypes, + isLoading: eventTypesLoading, + isError: eventTypesIsError, + error: eventTypesError + } = useAllEventTypes(); + + const { mutateAsync: createEvent } = useCreateEvent(); + const { isLoading: documentsIsLoading, mutateAsync: uploadDocuments } = useUploadManyDocuments(); + const [displayMonthYear, setDisplayMonthYear] = useState(new Date()); const { isLoading, isError, error, data: allEvents } = useAllEvents(); const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); + const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); if (isLoading || !allEvents) return ; if (isError) return ; + if (eventTypesLoading || !eventTypes) return ; + if (eventTypesIsError) return ; + if (documentsIsLoading) return ; // Sort events by their first occurrence's start time const sortedEvents = [...allEvents].sort((event1, event2) => { @@ -86,6 +104,53 @@ const NewCalendarPage = () => { if (!allTeamTypes || allTeamTypesLoading) return ; if (allTeamTypesIsError) return ; + if (documentsIsLoading) return ; + + const handleCreateEvent = async (data: EventRoutePayload) => { + try { + const { scheduleSlot, documentFiles, ...eventData } = data; + + const [slot] = scheduleSlot; + + if (!slot) throw new Error('Missing scheduleSlot'); + + const { days, startTime, endTime, recurrenceNumber, initialDateScheduled, allDay } = slot; + + // Create the event first WITHOUT documents + const createArgs = { + ...eventData, + documentIds: [], // Empty array initially + scheduleSlot: [ + { + days, + startTime, + endTime, + recurrenceNumber, + initialDateScheduled, + allDay + } + ] + }; + + const createdEvent = await createEvent(createArgs); + + const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); + + if (filesToUpload.length > 0) { + await uploadDocuments({ + id: createdEvent.eventId, + files: filesToUpload + }); + } + + toast.success('Event created successfully!'); + setIsCreateModalOpen(false); + } catch (err) { + if (err instanceof Error) { + toast.error(err.message); + } + } + }; return ( <> @@ -99,15 +164,23 @@ const NewCalendarPage = () => { teamTypes={allTeamTypes} /> )} + {isCreateModalOpen && ( + setIsCreateModalOpen(false)} + onSubmit={handleCreateEvent} + eventTypes={eventTypes} + defaultDate={displayMonthYear} + /> + )} - {/* New Event Button (does not do anything yet) */} +
+ + ); +}; + +export interface EventClickPopupProps { + clickedEvent: Event | null; + anchorPosition: { top: number; left: number } | null; + onClose: () => void; + eventTypes: EventType[]; + calendars: Calendar[]; + dayOfWeek: DayOfWeek; +} + +export const EventClickPopup: React.FC = ({ + clickedEvent, + anchorPosition, + onClose, + eventTypes, + calendars, + dayOfWeek +}) => { + return ( + + {clickedEvent && ( + + )} + + ); +}; diff --git a/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx b/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx index 78bbceba56..fa23504474 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx @@ -3,7 +3,7 @@ import LocationOnIcon from '@mui/icons-material/LocationOn'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; import GroupIcon from '@mui/icons-material/Group'; import { Stack } from '@mui/system'; -import { getTeamTypeIcon } from './CalendarDayCard'; +import { getTeamTypeIcon } from './EventClickPopup'; import { Typography } from '@mui/material'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; From 5edec8e627af7ebaf95b5cb0d79e7e770b4601c7 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Thu, 11 Dec 2025 11:38:24 -0500 Subject: [PATCH 322/477] #3798 Error Fix --- .../pages/NewCalendarPage/CalendarDayCard.tsx | 16 +++++++++++++++- .../pages/NewCalendarPage/EventClickPopup.tsx | 15 ++------------- .../NewCalendarPage/EventPartialInfoView.tsx | 2 +- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index a0f651231f..5cefa957a6 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -12,10 +12,24 @@ import StorefrontIcon from '@mui/icons-material/Storefront'; import BusinessCenterIcon from '@mui/icons-material/BusinessCenter'; import DescriptionIcon from '@mui/icons-material/Description'; import ArticleIcon from '@mui/icons-material/Article'; +import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; +import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices'; +import TerminalIcon from '@mui/icons-material/Terminal'; import EventPartialInfoView from './EventPartialInfoView'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; -import { EventClickPopup, getTeamTypeIcon, getStatusIcon } from './EventClickPopup'; +import { EventClickPopup, getStatusIcon } from './EventClickPopup'; + +export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { + const teamIcons: Map = new Map([ + ['Software', ], + ['Business', ], + ['Electrical', ], + ['Mechanical', ] + ]); + + return teamIcons.get(teamTypeName); +}; interface CalendarDayCardProps { cardDate: Date; diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 43dba35f2f..e786bcd981 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -1,11 +1,9 @@ import React from 'react'; import { Box, Button, IconButton, Popover, Stack, Typography, useTheme } from '@mui/material'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; - +import { getTeamTypeIcon } from './CalendarDayCard'; import ConstructionIcon from '@mui/icons-material/Construction'; -import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; -import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices'; -import TerminalIcon from '@mui/icons-material/Terminal'; + import AccessTimeIcon from '@mui/icons-material/AccessTime'; import LocationOnIcon from '@mui/icons-material/LocationOn'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; @@ -17,16 +15,7 @@ import PeopleIcon from '@mui/icons-material/People'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; -export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { - const teamIcons: Map = new Map([ - ['Software', ], - ['Business', ], - ['Electrical', ], - ['Mechanical', ] - ]); - return teamIcons.get(teamTypeName); -}; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ diff --git a/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx b/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx index fa23504474..78bbceba56 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx @@ -3,7 +3,7 @@ import LocationOnIcon from '@mui/icons-material/LocationOn'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; import GroupIcon from '@mui/icons-material/Group'; import { Stack } from '@mui/system'; -import { getTeamTypeIcon } from './EventClickPopup'; +import { getTeamTypeIcon } from './CalendarDayCard'; import { Typography } from '@mui/material'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; From d9075a43097887abcaf843a791eae8d2e0cdfb31 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Thu, 11 Dec 2025 17:03:30 -0500 Subject: [PATCH 323/477] #3816 everthing but warnings --- .../src/controllers/calendar.controllers.ts | 9 +- src/frontend/src/apis/calendar.api.ts | 8 +- src/frontend/src/hooks/calendar.hooks.ts | 46 ++- .../EventType/EventTypeFormModal.tsx | 2 +- .../pages/NewCalendarPage/CalendarDayCard.tsx | 2 +- .../NewCalendarPage/Components/EventModal.tsx | 277 ++++++++++-------- .../pages/NewCalendarPage/NewCalendarPage.tsx | 4 +- src/frontend/src/utils/urls.ts | 2 + 8 files changed, 215 insertions(+), 135 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 86849f5235..226f23ad99 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -295,9 +295,9 @@ export default class CalendarController { req.organization, requiredMemberIds, optionalMemberIds, + teamIds, shopIds, machineryIds, - teamIds, workPackageIds, parsedScheduleSlot, teamTypeId, @@ -330,7 +330,8 @@ export default class CalendarController { scheduleSlot, questionDocumentLink, location, - zoomLink + zoomLink, + description } = req.body; const parsedScheduleSlot = scheduleSlot.map((slot: any) => ({ @@ -351,14 +352,14 @@ export default class CalendarController { teamIds, shopIds, machineryIds, - teamIds, workPackageIds, documents, parsedScheduleSlot, teamTypeId, questionDocumentLink, location, - zoomLink + zoomLink, + description ); res.status(200).json(event); } catch (error: unknown) { diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index f3181d7c32..57ba25cd8d 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -12,7 +12,7 @@ import { FilterArgs } from 'shared'; import { eventTransformer } from './transformers/calendar.transformer'; -import { EventCreateArgs } from '../hooks/calendar.hooks'; +import { EditEventArgs, EventCreateArgs } from '../hooks/calendar.hooks'; export const getAllCalendars = () => { return axios.get(apiUrls.calendarCalendars(), { @@ -174,6 +174,12 @@ export const postCreateEvent = async (payload: EventCreateArgs) => { }); }; +export const postEditEvent = async (eventId: string, payload: EditEventArgs) => { + return axios.post(apiUrls.calendarEditEvent(eventId), payload, { + transformResponse: (data) => eventTransformer(JSON.parse(data)) + }); +}; + /** * Upload a document * diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index a95bcfaa0f..e7239a2347 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -37,7 +37,8 @@ import { postFilterEvents, postCreateEvent, uploadSingleDocument, - downloadDocumentPdf + downloadDocumentPdf, + postEditEvent } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; import { PDFDocument } from 'pdf-lib'; @@ -47,6 +48,7 @@ export const MACHINERY_KEY = ['machinery'] as const; const SHOP_KEY = ['shops'] as const; const CALENDAR_KEY = ['calendars'] as const; export const EVENT_TYPE_KEY = ['event-types'] as const; +export const EVENT_KEY = ['events'] as const; export interface EventCreateArgs { title: string; @@ -66,6 +68,24 @@ export interface EventCreateArgs { scheduleSlot: ScheduleSlotCreateArgs[]; } +export interface EditEventArgs { + title: string; + requiredMemberIds: string[]; + optionalMemberIds: string[]; + teamIds: string[]; + teamTypeId?: string; + status: EventStatus; + location?: string; + zoomLink?: string; + shopIds: string[]; + machineryIds: string[]; + workPackageIds: string[]; + documents: Array<{ name: string; googleFileId: string }>; + questionDocumentLink?: string; + description?: string; + scheduleSlot: ScheduleSlotCreateArgs[]; +} + export interface DownloadDocumentsFormInput { fileIds: string[]; startDate: Date; @@ -284,7 +304,7 @@ export const useMarkUserConfirmed = (id: string) => { }, { onSuccess: () => { - queryClient.invalidateQueries(['events']); + queryClient.invalidateQueries(EVENT_KEY); queryClient.invalidateQueries(['users', user.userId, 'schedule-settings']); } } @@ -318,7 +338,7 @@ export const useSingleEvent = (id?: string) => { }; export const useAllEvents = () => { - return useQuery(['events'], async () => { + return useQuery(EVENT_KEY, async () => { const { data } = await getAllEvents(); return data; }); @@ -354,7 +374,7 @@ export const useDeleteEvent = (id: string) => { }, { onSuccess: () => { - queryClient.invalidateQueries(['events']); + queryClient.invalidateQueries(EVENT_KEY); } } ); @@ -385,7 +405,23 @@ export const useCreateEvent = () => { }, { onSuccess: () => { - qc.invalidateQueries('events'); + qc.invalidateQueries(EVENT_KEY); + } + } + ); +}; + +export const useEditEvent = (eventId: string) => { + const queryClient = useQueryClient(); + return useMutation( + ['events', 'edit', eventId], + async (payload) => { + const { data } = await postEditEvent(eventId, payload); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(EVENT_KEY); } } ); diff --git a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx index a2a14fd753..6f952c6985 100644 --- a/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/ScheduleConfig/EventType/EventTypeFormModal.tsx @@ -784,7 +784,7 @@ export const EventTypeFormModal: React.FC = ({ open, on color: 'rgba(255, 255, 255, 0.7)' }} > - Add a description or attachment + Add a description diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index 2d10460468..3ff7c1c6b0 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -300,7 +300,7 @@ const CalendarDayCard: React.FC = ({ const EventCard = ({ event }: { event: Event }) => { const [isSummaryModalOpen, setIsSummaryModalOpen] = useState(false); const [markedStatus, setMarkedStatus] = useState(event.status); - const name = event.workPackages[0]?.wbsElement?.name || event.title; + const name = event.title || event.workPackages[0]?.wbsElement?.name; const specificEventType = eventTypes?.find((eventType) => eventType.eventTypeId === event.eventTypeId); const specificCalendar = calendars?.find((calendar) => calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx index 3ca470a441..1971785da8 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx @@ -26,10 +26,11 @@ import { wbsNamePipe, wbsNumComparator, wbsPipe, - EventType + EventType, + isHead } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; -import { useAllUsers } from '../../../hooks/users.hooks'; +import { useAllUsers, useCurrentUser } from '../../../hooks/users.hooks'; import { useAllWorkPackages } from '../../../hooks/work-packages.hooks'; import { useAllTeams } from '../../../hooks/teams.hooks'; import { userToAutocompleteOption } from '../../../utils/teams.utils'; @@ -148,6 +149,7 @@ const EventModal: React.FC = ({ defaultDate = new Date() }) => { const toast = useToast(); + const user = useCurrentUser(); const [datePickerOpen, setDatePickerOpen] = useState(false); const [startTimePickerOpen, setStartTimePickerOpen] = useState(false); const [endTimePickerOpen, setEndTimePickerOpen] = useState(false); @@ -204,6 +206,13 @@ const EventModal: React.FC = ({ [initialValues, defaultDate] ); + const allowedEventTypes = useMemo(() => { + return eventTypes.filter((et) => { + if (!et.onlyHeadsOrAboveForEventCreation) return true; + return isHead(user.role); + }); + }, [eventTypes, user]); + const { handleSubmit, control, @@ -218,6 +227,30 @@ const EventModal: React.FC = ({ const frozenValuesRef = React.useRef>(defaultFormData); + const shopIds = watch('shopIds'); + const selectedEventTypeId = watch('eventTypeId'); + const documentFiles = watch('documentFiles'); + + // Filter machinery based on selected shops + const filteredMachineryOptions = useMemo(() => { + if (!machinery || !shops) { + return []; + } + + const allMachineryOptions = machinery.map((m) => ({ id: m.machineryId, label: m.name })); + + if (shops.length == 0) { + return allMachineryOptions; + } + + return allMachineryOptions.filter((machineOption) => { + const machine = machinery.find((m) => m.machineryId === machineOption.id); + if (!machine) return false; + + return machine.shops.some((shopMachinery) => shopIds.includes(shopMachinery.shop.shopId)); + }); + }, [machinery, shops, shopIds]); + useEffect(() => { if (open) { frozenValuesRef.current = defaultFormData; @@ -251,14 +284,11 @@ const EventModal: React.FC = ({ } }, [open, defaultFormData, reset, initialValues, users, teams]); - const selectedEventTypeId = watch('eventTypeId'); const selectedEventType = useMemo( - () => eventTypes.find((et) => et.eventTypeId === selectedEventTypeId), - [eventTypes, selectedEventTypeId] + () => allowedEventTypes.find((et) => et.eventTypeId === selectedEventTypeId), + [allowedEventTypes, selectedEventTypeId] ); - const documentFiles = watch('documentFiles'); - const isEditMode = !!frozenValuesRef.current.eventTypeId; const computedTitle = isEditMode ? 'Edit Event' : 'Add Event'; @@ -359,13 +389,12 @@ const EventModal: React.FC = ({ const memberOptions = users.map(userToAutocompleteOption); const teamOptions = teams.map((t) => ({ id: t.teamId, label: t.teamName })); const shopOptions = shops.map((s) => ({ id: s.shopId, label: s.name })); - const machineryOptions = machinery.map((m) => ({ id: m.machineryId, label: m.name })); const workPackageOptions = allWorkPackages .filter((wp) => wp.status === WbsElementStatus.Active) .map((wp) => ({ label: wbsNamePipe(wp), - id: wbsPipe(wp.wbsNum) + id: wp.id })) .sort((a, b) => wbsNumComparator(b.id, a.id)); @@ -410,10 +439,9 @@ const EventModal: React.FC = ({ /> )} /> - {/* Event Type Tabs */} - {eventTypes.map((et) => ( + {allowedEventTypes.map((et) => ( = ({ /> ))} - {/* Date and Time Section */} @@ -576,7 +603,7 @@ const EventModal: React.FC = ({ )} /> - time(s) + more time(s) @@ -654,106 +681,99 @@ const EventModal: React.FC = ({ )} - {/* Required Members Section */} {selectedEventType?.requiredMembers && ( - - - Required Members - - - {requiredMembers.map((member) => ( - setRequiredMembers((prev) => prev.filter((m) => m.id !== member.id))} - sx={{ bgcolor: 'grey.300' }} + + + + {requiredMembers.map((member) => ( + setRequiredMembers((prev) => prev.filter((m) => m.id !== member.id))} + sx={{ bgcolor: 'grey.700' }} + /> + ))} + !requiredMembers.find((rm) => rm.id === m.id))} + onChange={(_, newValue) => { + if (newValue) setRequiredMembers((prev) => [...prev, newValue]); + }} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + sx={{ flex: 1, minWidth: 150 }} /> - ))} - !requiredMembers.find((rm) => rm.id === m.id))} - onChange={(_, newValue) => { - if (newValue) setRequiredMembers((prev) => [...prev, newValue]); - }} - getOptionLabel={(option) => option.label} - renderInput={(params) => ( - - )} - sx={{ display: 'inline-flex', minWidth: 150 }} - /> + )} - {/* Optional Members Section */} {selectedEventType?.optionalMembers && ( - - - Optional Members - - - {optionalMembers.map((member) => ( - setOptionalMembers((prev) => prev.filter((m) => m.id !== member.id))} - sx={{ bgcolor: 'grey.200', opacity: 0.7 }} + + + + {optionalMembers.map((member) => ( + setOptionalMembers((prev) => prev.filter((m) => m.id !== member.id))} + sx={{ bgcolor: 'grey.700', opacity: 0.7 }} + /> + ))} + !optionalMembers.find((om) => om.id === m.id))} + onChange={(_, newValue) => { + if (newValue) setOptionalMembers((prev) => [...prev, newValue]); + }} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + sx={{ flex: 1, minWidth: 150 }} /> - ))} - !optionalMembers.find((om) => om.id === m.id))} - onChange={(_, newValue) => { - if (newValue) setOptionalMembers((prev) => [...prev, newValue]); - }} - getOptionLabel={(option) => option.label} - renderInput={(params) => ( - - )} - sx={{ display: 'inline-flex', minWidth: 150 }} - /> + )} - {/* Teams Section */} {selectedEventType?.teams && ( - - - Teams - - - {selectedTeams.map((team) => ( - setSelectedTeams((prev) => prev.filter((t) => t.id !== team.id))} - sx={{ bgcolor: 'primary.light', color: 'white' }} + + + + {selectedTeams.map((team) => ( + setSelectedTeams((prev) => prev.filter((t) => t.id !== team.id))} + sx={{ bgcolor: 'grey.700', opacity: 0.7 }} + /> + ))} + !selectedTeams.find((st) => st.id === t.id))} + onChange={(_, newValue) => { + if (newValue) setSelectedTeams((prev) => [...prev, newValue]); + }} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + sx={{ flex: 1, minWidth: 150 }} /> - ))} - !selectedTeams.find((st) => st.id === t.id))} - onChange={(_, newValue) => { - if (newValue) setSelectedTeams((prev) => [...prev, newValue]); - }} - getOptionLabel={(option) => option.label} - renderInput={(params) => ( - - )} - sx={{ display: 'inline-flex', minWidth: 120 }} - /> + )} - {/* Team Type */} {selectedEventType?.teamType && ( @@ -782,7 +802,6 @@ const EventModal: React.FC = ({ /> )} - {/* Location */} {selectedEventType?.location && ( @@ -803,7 +822,6 @@ const EventModal: React.FC = ({ /> )} - {/* Zoom Link */} {selectedEventType?.zoomLink && ( @@ -826,30 +844,53 @@ const EventModal: React.FC = ({ /> )} - - {/* Shops */} {selectedEventType?.shop && ( - - - ( - value?.includes(s.id))} - onChange={(_, newValue) => onChange(newValue.map((v) => v.id))} - getOptionLabel={(option) => option.label} - renderInput={(params) => } - sx={{ flex: 1 }} - /> - )} - /> + + + + ( + value?.[0] === s.id) || null} + onChange={(_, newValue) => onChange(newValue ? [newValue.id] : [])} + getOptionLabel={(option) => option.label} + renderInput={(params) => } + sx={{ flex: 1 }} + /> + )} + /> + + {shopIds.length > 0 && ( + + {(() => { + const shop = shops.find((s) => s.shopId === shopIds[0]); + if (!shop || !shop.description) return null; + return ( + + + Reserve on Robin: + + + {shop.description} + + + ); + })()} + + )} )} - - {/* Machinery */} {selectedEventType?.machinery && ( @@ -858,10 +899,9 @@ const EventModal: React.FC = ({ control={control} render={({ field: { onChange, value } }) => ( value?.includes(m.id))} - onChange={(_, newValue) => onChange(newValue.map((v) => v.id))} + options={filteredMachineryOptions} + value={filteredMachineryOptions.find((m) => value?.[0] === m.id) || null} + onChange={(_, newValue) => onChange(newValue ? [newValue.id] : [])} getOptionLabel={(option) => option.label} renderInput={(params) => } sx={{ flex: 1 }} @@ -870,8 +910,6 @@ const EventModal: React.FC = ({ /> )} - - {/* Work Packages */} {selectedEventType?.workPackage && ( @@ -880,10 +918,9 @@ const EventModal: React.FC = ({ control={control} render={({ field: { onChange, value } }) => ( value?.includes(wp.id))} - onChange={(_, newValue) => onChange(newValue.map((v) => v.id))} + value={workPackageOptions.find((wp) => value?.[0] === wp.id) || null} + onChange={(_, newValue) => onChange(newValue ? [newValue.id] : [])} getOptionLabel={(option) => option.label} renderInput={(params) => } sx={{ flex: 1 }} @@ -892,7 +929,6 @@ const EventModal: React.FC = ({ /> )} - {/* Question Document Link */} {selectedEventType?.questionDocument && ( @@ -915,7 +951,6 @@ const EventModal: React.FC = ({ /> )} - {/* Documents */} {selectedEventType?.documents && ( @@ -1003,7 +1038,7 @@ const EventModal: React.FC = ({ { const { days, startTime, endTime, recurrenceNumber, initialDateScheduled, allDay } = slot; - // Create the event first WITHOUT documents + // Create the event first without documents const createArgs = { ...eventData, - documentIds: [], // Empty array initially + documentIds: [], scheduleSlot: [ { days, diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 3feb7db3f1..c59d9e7734 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -463,6 +463,7 @@ const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; const calendarCreateEvent = () => `${calendar()}/event/create`; +const calendarEditEvent = (eventId: string) => `${calendar()}/event/${eventId}/edit`; const calendarUploadDocument = (eventId: string) => `${calendar()}/event/${eventId}/upload-document`; const calendarPDFById = (fileId: string) => `${calendar()}/document/${fileId}`; const calendarFilterEvents = () => `${calendar()}/events/filter`; @@ -795,6 +796,7 @@ export const apiUrls = { calendarUploadDocument, calendarPDFById, calendarDeleteEventType, + calendarEditEvent, version }; From 05b534558aaec775d46cec35a1e42777b8567dad Mon Sep 17 00:00:00 2001 From: wavehassman Date: Thu, 11 Dec 2025 17:13:48 -0500 Subject: [PATCH 324/477] #3816 linting --- .../src/pages/NewCalendarPage/Components/EventModal.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx index 1971785da8..1cef4dabe6 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx @@ -25,7 +25,6 @@ import { WbsElementStatus, wbsNamePipe, wbsNumComparator, - wbsPipe, EventType, isHead } from 'shared'; @@ -239,7 +238,7 @@ const EventModal: React.FC = ({ const allMachineryOptions = machinery.map((m) => ({ id: m.machineryId, label: m.name })); - if (shops.length == 0) { + if (shops.length === 0) { return allMachineryOptions; } From 7b8294ad775b869bc830e5ba8ae3d815b3b7b4da Mon Sep 17 00:00:00 2001 From: wavehassman Date: Thu, 11 Dec 2025 19:08:29 -0500 Subject: [PATCH 325/477] #3816 fix query keys --- src/frontend/src/hooks/calendar.hooks.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index e7239a2347..4c6b0303e6 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -375,6 +375,7 @@ export const useDeleteEvent = (id: string) => { { onSuccess: () => { queryClient.invalidateQueries(EVENT_KEY); + queryClient.invalidateQueries(['filter-events']); } } ); @@ -405,6 +406,7 @@ export const useCreateEvent = () => { }, { onSuccess: () => { + qc.invalidateQueries(['filter-events']); qc.invalidateQueries(EVENT_KEY); } } @@ -421,6 +423,7 @@ export const useEditEvent = (eventId: string) => { }, { onSuccess: () => { + queryClient.invalidateQueries(['filter-events']); queryClient.invalidateQueries(EVENT_KEY); } } From 145151622b63403c67ff9b94c43bc4202a9b6ee2 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Thu, 11 Dec 2025 19:18:02 -0500 Subject: [PATCH 326/477] #3816 fix migration --- .../prisma/migrations/20251101233144_calendar/migration.sql | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index e8f58c58f3..8287b89241 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -79,7 +79,6 @@ CREATE TABLE "public"."Event" ( "approvalRequiredFromUserId" TEXT, "location" TEXT, "zoomLink" TEXT, - "documentIds" TEXT[], "questionDocumentLink" TEXT, "description" TEXT, "teamTypeId" TEXT, @@ -499,7 +498,6 @@ INSERT INTO "public"."Event" ( "approvalRequiredFromUserId", "location", "zoomLink", - "documentIds", "questionDocumentLink", "description", "status", @@ -521,7 +519,6 @@ SELECT NULL, -- approvalRequiredFromUserId (not in Design_Review) dr."location", dr."zoomLink", - CASE WHEN dr."docTemplateLink" IS NOT NULL THEN ARRAY[dr."docTemplateLink"] ELSE ARRAY[]::TEXT[] END, dr."docTemplateLink", -- questionDocument uses docTemplateLink NULL, -- description (not in Design_Review) dr."status"::"text"::"public"."Event_Status", From dd43af29c4f9cda52fd326dc004f609422670425 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Fri, 12 Dec 2025 18:48:39 -0500 Subject: [PATCH 327/477] #3814 fixed google calendar integration --- .../20251101233144_calendar/migration.sql | 7 +- src/backend/src/prisma/schema.prisma | 1 + src/backend/src/services/calendar.services.ts | 67 +++++- .../src/utils/google-integration.utils.ts | 225 ++++++++++++------ 4 files changed, 226 insertions(+), 74 deletions(-) diff --git a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql index a4f2bcf242..8d4a57d306 100644 --- a/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20251101233144_calendar/migration.sql @@ -69,6 +69,7 @@ CREATE TABLE "public"."Event" ( "questionDocument" TEXT, "description" TEXT, "teamTypeId" TEXT, + "calendarEventIds" TEXT[], CONSTRAINT "Event_pkey" PRIMARY KEY ("eventId") ); @@ -474,7 +475,8 @@ INSERT INTO "public"."Event" ( "questionDocument", "description", "status", - "teamTypeId" + "teamTypeId", + "calendarEventIds" ) SELECT dr."designReviewId", @@ -496,7 +498,8 @@ SELECT dr."docTemplateLink", -- questionDocument uses docTemplateLink NULL, -- description (not in Design_Review) dr."status"::"text"::"public"."Event_Status", - dr."teamTypeId" + dr."teamTypeId", + CASE WHEN dr."calendarEventId" IS NOT NULL THEN ARRAY[dr."calendarEventId"] ELSE ARRAY[]::TEXT[] END FROM "public"."Design_Review" dr JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId"; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index a960c28097..3f77c2e4fe 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1064,6 +1064,7 @@ model Event { questionDocument String? description String? notificationSlackThreads Message_Info[] + calendarEventIds String[] } model Calendar { diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 0ab3645817..39c06ee829 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -53,6 +53,7 @@ import { sendSlackEventConfirmNotification } from '../utils/slack.utils'; import { sendEventPopUp } from '../utils/pop-up.utils'; +import { createCalendarEvent, deleteCalendarEvents, updateCalendarEvent } from '../utils/google-integration.utils'; export default class CalendarService { /** @@ -470,6 +471,32 @@ export default class CalendarService { ...getEventQueryArgs(organization.organizationId) }); + let calendarEventIds: string[] = []; + if (process.env.NODE_ENV === 'production') { + try { + const allMemberIds = [...requiredMemberIds, ...optionalMemberIds]; + const isInPerson = !!location; + + calendarEventIds = await createCalendarEvent( + process.env.GOOGLE_CALENDAR_ID!, + allMemberIds, + newEvent.scheduledTimes, + isInPerson, + zoomLink ?? null, + location ?? null, + title + ); + + // Update event with calendar IDs + await prisma.event.update({ + where: { eventId: newEvent.eventId }, + data: { calendarEventIds } + }); + } catch (error) { + console.error('Failed to create Google Calendar events:', error); + } + } + if (foundEventType.sendSlackNotifications) { const members = await prisma.user.findMany({ where: { userId: { in: optionalMemberIds.concat(requiredMemberIds) } } @@ -836,6 +863,34 @@ export default class CalendarService { ); } + let calendarEventIds = foundEvent.calendarEventIds || []; + + // If schedule changed, update Google Calendar events + if (scheduleChanged && process.env.NODE_ENV === 'production') { + try { + const allMemberIds = [...requiredMemberIds, ...optionalMemberIds]; + const isInPerson = !!location; + + // Get the newly created schedule slots + const updatedSlots = await tx.schedule_Slot.findMany({ + where: { ScheduledEvents: { some: { eventId } } } + }); + + calendarEventIds = await updateCalendarEvent( + process.env.GOOGLE_CALENDAR_ID!, + foundEvent.calendarEventIds || [], + allMemberIds, + updatedSlots, + isInPerson, + zoomLink ?? null, + location ?? null, + title + ); + } catch (error) { + console.error('Failed to update Google Calendar events:', error); + } + } + // throw if a user isn't found, then build prisma queries for connecting userIds const updatedRequiredMembers = getPrismaQueryUserIds(await getUsers(requiredMemberIds)); const updatedOptionalMembers = getPrismaQueryUserIds(await getUsers(optionalMemberIds)); @@ -895,7 +950,8 @@ export default class CalendarService { location, zoomLink, questionDocument, - description + description, + calendarEventIds }, ...getEventQueryArgs(organization.organizationId) }); @@ -1119,6 +1175,15 @@ export default class CalendarService { throw new AccessDeniedException('Only admins can delete events!'); } + // Delete from Google Calendar + if (event.calendarEventIds && event.calendarEventIds.length > 0 && process.env.NODE_ENV === 'production') { + try { + await deleteCalendarEvents(process.env.GOOGLE_CALENDAR_ID!, event.calendarEventIds); + } catch (error) { + console.error('Failed to delete Google Calendar events:', error); + } + } + const deletedEvent = await prisma.event.update({ where: { eventId }, data: { dateDeleted: new Date(), userDeletedId: submitter.userId }, diff --git a/src/backend/src/utils/google-integration.utils.ts b/src/backend/src/utils/google-integration.utils.ts index d96e7adb63..1a09231203 100644 --- a/src/backend/src/utils/google-integration.utils.ts +++ b/src/backend/src/utils/google-integration.utils.ts @@ -190,7 +190,7 @@ export const createCalendar = async (name: string) => { }; /** - * Creates A Google Calendar Event on the NER Google Calendar + * Creates Google Calendar Events on the NER Google Calendar for all schedule slot occurrences * @param calendarId the id of the calendar to add the event * @param memberIds required and optional members * @param scheduledSlots the scheduled time slots for the event @@ -198,7 +198,7 @@ export const createCalendar = async (name: string) => { * @param zoomLink zoom link if online * @param location physical location if in person * @param eventTitle the title of the event - * @returns the id of the calendar event + * @returns an array of calendar event ids */ export const createCalendarEvent = async ( calendarId: string, @@ -209,11 +209,10 @@ export const createCalendarEvent = async ( location: string | null, eventTitle: string ) => { - if (process.env.NODE_ENV !== 'production') return; + if (process.env.NODE_ENV !== 'production') return []; - const [firstSlot] = scheduledSlots; - if (!firstSlot?.startTime || !firstSlot?.endTime) { - throw new Error('Event must have a valid start and end time'); + if (scheduledSlots.length === 0) { + throw new Error('Event must have at least one schedule slot'); } try { @@ -222,58 +221,73 @@ export const createCalendarEvent = async ( }); const calendar = google.calendar({ version: 'v3', auth: oauth2Client }); - const startDateTime = new Date(firstSlot.startTime); - const endDateTime = new Date(firstSlot.endTime); - - const eventInput = { - location: isInPerson ? location : zoomLink, - summary: eventTitle, - start: { - dateTime: startDateTime.toISOString(), - timeZone: 'America/New_York' - }, - end: { - dateTime: endDateTime.toISOString(), - timeZone: 'America/New_York' - }, - attendees: (await getUsers(memberIds)).map((user) => { - return { email: user.email }; - }), - reminders: { - useDefault: false, - overrides: [ - { method: 'email', minutes: 24 * 60 }, - { method: 'popup', minutes: 10 } - ] + const attendees = (await getUsers(memberIds)).map((user) => ({ + email: user.email + })); + + const calendarEventIds: string[] = []; + + for (const slot of scheduledSlots) { + const occurrences = generateOccurrences(slot); + + for (const occurrence of occurrences) { + const eventInput = { + location: isInPerson ? location : zoomLink, + summary: eventTitle, + start: slot.allDay + ? { date: occurrence.date } + : { + dateTime: occurrence.startDateTime.toISOString(), + timeZone: 'America/New_York' + }, + end: slot.allDay + ? { date: occurrence.date } + : { + dateTime: occurrence.endDateTime.toISOString(), + timeZone: 'America/New_York' + }, + attendees, + reminders: { + useDefault: false, + overrides: [ + { method: 'email', minutes: 24 * 60 }, + { method: 'popup', minutes: 10 } + ] + } + }; + + const calendarEvent = await calendar.events.insert({ + calendarId, + requestBody: eventInput + }); + + if (calendarEvent.data.id) { + calendarEventIds.push(calendarEvent.data.id); + } } - }; - - const calendarEvent = await calendar.events.insert({ - calendarId, - requestBody: eventInput - }); + } - return calendarEvent.data.id; + return calendarEventIds; } catch (error: unknown) { throw error; } }; /** - * Updates a Google Calendar Event + * Updates Google Calendar Events by deleting old ones and creating new ones * @param calendarId Id of the calendar the event is on - * @param eventId Id of the calendar event + * @param oldEventIds Array of old calendar event ids to delete * @param memberIds required and optional members * @param scheduledSlots the scheduled time slots for the event * @param isInPerson whether the event is in person * @param zoomLink zoom link if online * @param location physical location if in person * @param eventTitle the title of the event - * @returns the id of the updated calendar event + * @returns an array of new calendar event ids */ export const updateCalendarEvent = async ( calendarId: string, - eventId: string, + oldEventIds: string[], memberIds: string[], scheduledSlots: Schedule_Slot[], isInPerson: boolean, @@ -281,9 +295,8 @@ export const updateCalendarEvent = async ( location: string | null, eventTitle: string ) => { - const [firstSlot] = scheduledSlots; - if (!firstSlot?.startTime || !firstSlot?.endTime) { - throw new Error('Event must have a valid start and end time'); + if (scheduledSlots.length === 0) { + throw new Error('Event must have at least one schedule slot'); } try { @@ -292,39 +305,109 @@ export const updateCalendarEvent = async ( }); const calendar = google.calendar({ version: 'v3', auth: oauth2Client }); - const startDateTime = new Date(firstSlot.startTime); - const endDateTime = new Date(firstSlot.endTime); + // Delete old calendar events + for (const eventId of oldEventIds) { + try { + await calendar.events.delete({ + calendarId, + eventId + }); + } catch (error) { + console.error(`Failed to delete calendar event ${eventId}:`, error); + } + } - const eventInput = { - location: isInPerson ? location : zoomLink, - summary: eventTitle, - start: { - dateTime: startDateTime.toISOString(), - timeZone: 'America/New_York' - }, - end: { - dateTime: endDateTime.toISOString(), - timeZone: 'America/New_York' - }, - attendees: (await getUsers(memberIds)).map((user) => { - return { email: user.email }; - }), - reminders: { - useDefault: false, - overrides: [ - { method: 'email', minutes: 24 * 60 }, - { method: 'popup', minutes: 10 } - ] + // Create new calendar events + return await createCalendarEvent(calendarId, memberIds, scheduledSlots, isInPerson, zoomLink, location, eventTitle); + } catch (error: unknown) { + throw error; + } +}; + +/** + * Helper function to generate all occurrences for a schedule slot + */ +const generateOccurrences = (slot: Schedule_Slot) => { + const occurrences: Array<{ + date: string; + startDateTime: Date; + endDateTime: Date; + }> = []; + + const startDate = new Date(slot.initialDateScheduled); + const endDate = new Date(slot.endDate); + const currentDate = new Date(startDate); + + const dayOfWeekMap: Record = { + SUNDAY: 0, + MONDAY: 1, + TUESDAY: 2, + WEDNESDAY: 3, + THURSDAY: 4, + FRIDAY: 5, + SATURDAY: 6 + }; + + const targetDays = slot.days.map((day) => dayOfWeekMap[day]); + + while (currentDate <= endDate) { + const currentDayOfWeek = currentDate.getDay(); + + if (targetDays.includes(currentDayOfWeek)) { + const [dateStr] = currentDate.toISOString().split('T'); + + if (slot.startTime && slot.endTime) { + const startTime = new Date(slot.startTime); + const endTime = new Date(slot.endTime); + + const startDateTime = new Date(currentDate); + startDateTime.setHours(startTime.getHours(), startTime.getMinutes(), 0, 0); + + const endDateTime = new Date(currentDate); + endDateTime.setHours(endTime.getHours(), endTime.getMinutes(), 0, 0); + + occurrences.push({ date: dateStr, startDateTime, endDateTime }); + } else { + occurrences.push({ + date: dateStr, + startDateTime: currentDate, + endDateTime: currentDate + }); } - }; + } - const calendarEvent = await calendar.events.update({ - calendarId, - eventId, - requestBody: eventInput + currentDate.setDate(currentDate.getDate() + 1); + } + + return occurrences; +}; + +/** + * Deletes multiple Google Calendar Events + * @param calendarId Id of the calendar the events are on + * @param eventIds Array of calendar event IDs to delete + */ +export const deleteCalendarEvents = async (calendarId: string, eventIds: string[]) => { + if (process.env.NODE_ENV !== 'production') return; + + try { + oauth2Client.setCredentials({ + refresh_token: CALENDAR_REFRESH_TOKEN }); + const calendar = google.calendar({ version: 'v3', auth: oauth2Client }); - return calendarEvent.data.id; + await Promise.all( + eventIds.map(async (eventId) => { + try { + await calendar.events.delete({ + calendarId, + eventId + }); + } catch (error) { + console.error(`Failed to delete calendar event ${eventId}:`, error); + } + }) + ); } catch (error: unknown) { throw error; } From 49b114edb46d1343410ea051e06cbc7ec08b1758 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 12 Dec 2025 21:51:36 -0500 Subject: [PATCH 328/477] #minorupdate --- src/frontend/src/utils/urls.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index a7f2d5f26d..df5afd78da 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -463,7 +463,6 @@ const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; -const calendarFilterEvents = () => `${calendar()}/events/filter`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; From b7da61cab798d0d4ab3e657aa3eb8f9d08287d20 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 12 Dec 2025 22:02:45 -0500 Subject: [PATCH 329/477] update --- src/backend/src/prisma/seed.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 87d6afd27b..46f2ff315a 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3443,35 +3443,6 @@ const performSeed: () => Promise = async () => { "This one is optional, up to you if you want to show up, we won't judge" ); - await CalendarService.createEvent( - thomasEmrax, - 'Weekly Team Sync 2', - meetingEventType.eventTypeId, - ner, - [], - [], - [justiceLeague.teamId], - [], - [], - [], - [], - [ - { - days: [DayOfWeek.MONDAY], - startTime: new Date('2025-10-21T10:00:00.000Z'), - endTime: new Date('2025-10-21T11:00:00.000Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), - allDay: false - } - ], - mechanical.teamTypeId, - undefined, - 'Conference Room A', - 'https://zoom.us/j/123456789', - undefined - ); - await CalendarService.createEvent( thomasEmrax, 'Impact Attenuator Design Review', From 0a066c1f364ba55c259d9a9b10bd2eafa3111ef3 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 12 Dec 2025 22:07:10 -0500 Subject: [PATCH 330/477] refactoring --- src/backend/src/services/calendar.services.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 63765f87e0..6705b58aad 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2169,8 +2169,10 @@ export default class CalendarService { dateDeleted: null, eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, - ...(memberOrTeamFilter ? { OR: memberOrTeamFilter } : undefined), - OR: approvedEvents ? [{ approved: 'APPROVED' }, { approved: 'NO_CONFLICT' }] : undefined, + AND: [ + memberOrTeamFilter.length ? { OR: memberOrTeamFilter } : {}, + approvedEvents ? { OR: [{ approved: 'APPROVED' }, { approved: 'NO_CONFLICT' }] } : {} + ], scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...fromCalendar }, From b26d96ca6d51e4c3b62aa13e199fc87ccb0cd174 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 12 Dec 2025 22:22:07 -0500 Subject: [PATCH 331/477] minor change to calendar day card so I don't forget --- .../pages/NewCalendarPage/CalendarDayCard.tsx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index f81bb1acac..cc0bb2c24d 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -17,6 +17,7 @@ import BusinessCenterIcon from '@mui/icons-material/BusinessCenter'; import DescriptionIcon from '@mui/icons-material/Description'; import ArticleIcon from '@mui/icons-material/Article'; import HelpIcon from '@mui/icons-material/Help'; +import GroupsIcon from '@mui/icons-material/Groups'; import EventPartialInfoView from './EventPartialInfoView'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; @@ -183,6 +184,26 @@ const CalendarDayCard: React.FC = ({ )} + {event.teams.length > 0 && ( + + + + Teams : + + + {event.teams.length > 0 && event.teams.map((team) => `${team.teamName}`).join(', ')} + {event.teams.length === 0 && 'N/A'} + + + )} {event.machinery.length > 0 && ( From faff8cd32b052389e0d9ae0a37488d0ccafbdb03 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 12 Dec 2025 22:25:37 -0500 Subject: [PATCH 332/477] naming update --- src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index cc0bb2c24d..80f851130d 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -78,7 +78,7 @@ const CalendarDayCard: React.FC = ({ ); const EventPopupInfo = ({ event, color }: { event: Event; color: string }) => { - const name = event.workPackages[0]?.wbsElement?.name || event.title; + const name = event.title; const convertedStartTime = getConvertedStart(event, dayOfWeek); const convertedEndTime = getConvertedEnd(event, dayOfWeek); @@ -316,7 +316,7 @@ const CalendarDayCard: React.FC = ({ const EventCard = ({ event }: { event: Event }) => { const [isSummaryModalOpen, setIsSummaryModalOpen] = useState(false); const [markedStatus, setMarkedStatus] = useState(event.status); - const name = event.workPackages[0]?.wbsElement?.name || event.title; + const name = event.title; const specificEventType = eventTypes?.find((eventType) => eventType.eventTypeId === event.eventTypeId); const specificCalendar = calendars?.find((calendar) => calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) From 48b4dc683e0234236e5ad56d52494d23cd942c1b Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 12 Dec 2025 22:32:34 -0500 Subject: [PATCH 333/477] Update .editorconfig --- .editorconfig | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.editorconfig b/.editorconfig index 1ed453a371..e69de29bb2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,10 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true - -[*.{js,json,yml}] -charset = utf-8 -indent_style = space -indent_size = 2 From b2eeb8d1b9579949387ba483d80b629f22776f95 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Fri, 12 Dec 2025 22:43:02 -0500 Subject: [PATCH 334/477] delete file --- .editorconfig | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index e69de29bb2..0000000000 From 532144f91c0e781cadb81f51080a9d56d88e8861 Mon Sep 17 00:00:00 2001 From: sam gunss Date: Thu, 11 Dec 2025 18:34:14 -0500 Subject: [PATCH 335/477] Ticket #3702: all calendar view --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 65 ++++++++++++++++++- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 55bd25492a..8de6714473 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -3,7 +3,7 @@ * See the LICENSE file in the repository root folder for details. */ import { useState } from 'react'; -import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; +import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button, Checkbox, FormControlLabel, FormGroup, Divider, ButtonBase } from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { DayOfWeek, Event } from 'shared'; import CalendarDayCard from './CalendarDayCard'; @@ -20,6 +20,15 @@ import { DateCalendar } from '@mui/x-date-pickers'; import { useCurrentUser } from '../../hooks/users.hooks'; import { useGetUsersTeams } from '../../hooks/teams.hooks'; import { convertDayToInt } from '../../utils/calendar.utils'; +import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; +import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; + +type CalendarWithColor = Calendar & { + id?: string; + calendarId?: string; + color?: string; + colorHexCode?: string; +}; const NewCalendarPage = () => { const theme = useTheme(); @@ -72,6 +81,8 @@ const NewCalendarPage = () => { } = useAllCalendars(); const [selectedEvent, setSelectedEvent] = useState(); + const [selectedCalendarIds, setSelectedCalendarIds] = useState([]); + const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); @@ -98,11 +109,54 @@ const NewCalendarPage = () => { if (isLoading || !allEvents) return ; + const { + data: allCalendars = [], + isLoading: calendarsLoading, + isError: calendarsIsError, + error: calendarsError + } = useAllCalendars(); + + const calendars = (allCalendars ?? []) as CalendarWithColor[]; + + const toggleCalendar = (calendarId: string) => { + setSelectedCalendarIds((prev) => + prev.includes(calendarId) + ? prev.filter((id) => id !== calendarId) + : [...prev, calendarId] + ); + }; + + const monthStart = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 1); + const nextMonthStart = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 1); + if (isLoading || !allEvents) return ; if (isError) return ; + const getEventCalendarId = (event: any): string | undefined => + event.calendarId ?? + event.calendar?.id ?? + event.calendar?.calendarId; + + const baseEvents = allEvents.filter((event) => { + const inRange = event.scheduledTimes.some((slot) => { + if (!slot.startTime) return false; + const t = new Date(slot.startTime).getTime(); + return t >= monthStart.getTime() && t < nextMonthStart.getTime(); + }); + + if (!inRange) return false; + + if (selectedCalendarIds.length === 0) return true; + + const calId = getEventCalendarId(event); + + if (!calId) return true; + + return selectedCalendarIds.includes(calId); + }); + // Sort events by their first occurrence's start time - const sortedEvents = [...allEvents].sort((event1, event2) => { + const sortedEvents = [...baseEvents].sort((event1, event2) => { const time1 = event1.scheduledTimes[0]?.startTime ? new Date(event1.scheduledTimes[0].startTime).getTime() : 0; const time2 = event2.scheduledTimes[0]?.startTime ? new Date(event2.scheduledTimes[0].startTime).getTime() : 0; return time1 - time2; @@ -284,9 +338,14 @@ const NewCalendarPage = () => { + + {/* Calendars Selector */} Date: Fri, 12 Dec 2025 02:18:21 -0500 Subject: [PATCH 336/477] Ticket #3702: merge conflicts --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 120 +++++++++++------- 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 8de6714473..ab1e459fe0 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -3,9 +3,9 @@ * See the LICENSE file in the repository root folder for details. */ import { useState } from 'react'; -import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button, Checkbox, FormControlLabel, FormGroup, Divider, ButtonBase } from '@mui/material'; +import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button, Checkbox, FormControlLabel, FormGroup } from '@mui/material'; import PageLayout from '../../components/PageLayout'; -import { DayOfWeek, Event } from 'shared'; +import { Calendar, DayOfWeek, Event } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; @@ -23,7 +23,7 @@ import { convertDayToInt } from '../../utils/calendar.utils'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; -type CalendarWithColor = Calendar & { +type CalendarWithColor = Calendar & { id?: string; calendarId?: string; color?: string; @@ -80,13 +80,20 @@ const NewCalendarPage = () => { error: allCalendarsError } = useAllCalendars(); - const [selectedEvent, setSelectedEvent] = useState(); - const [selectedCalendarIds, setSelectedCalendarIds] = useState([]); + const calendars = (allCalendars ?? []) as CalendarWithColor[]; + const [selectedCalendarIds, setSelectedCalendarIds] = useState([]); + const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); + const toggleCalendar = (calendarId: string) => { + setSelectedCalendarIds((prev) => + prev.includes(calendarId) ? prev.filter((id) => id !== calendarId) : [...prev, calendarId] + ); + }; + const updateAdditionalTeamIds = (changed: boolean) => { setShowTeamEvents(changed); @@ -107,50 +114,21 @@ const NewCalendarPage = () => { } }; - if (isLoading || !allEvents) return ; - - const { - data: allCalendars = [], - isLoading: calendarsLoading, - isError: calendarsIsError, - error: calendarsError - } = useAllCalendars(); - - const calendars = (allCalendars ?? []) as CalendarWithColor[]; - - const toggleCalendar = (calendarId: string) => { - setSelectedCalendarIds((prev) => - prev.includes(calendarId) - ? prev.filter((id) => id !== calendarId) - : [...prev, calendarId] - ); - }; - - const monthStart = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 1); - const nextMonthStart = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 1); - if (isLoading || !allEvents) return ; if (isError) return ; const getEventCalendarId = (event: any): string | undefined => - event.calendarId ?? - event.calendar?.id ?? - event.calendar?.calendarId; - - const baseEvents = allEvents.filter((event) => { - const inRange = event.scheduledTimes.some((slot) => { - if (!slot.startTime) return false; - const t = new Date(slot.startTime).getTime(); - return t >= monthStart.getTime() && t < nextMonthStart.getTime(); - }); - - if (!inRange) return false; + event.calendarId ?? event.calendar?.id ?? event.calendar?.calendarId; - if (selectedCalendarIds.length === 0) return true; + const baseEvents = allEvents.filter((event) => { + if (selectedCalendarIds.length === 0) { + return true; + } const calId = getEventCalendarId(event); - - if (!calId) return true; + if (!calId) { + return false; + } return selectedCalendarIds.includes(calId); }); @@ -338,8 +316,6 @@ const NewCalendarPage = () => { - - {/* Calendars Selector */} { > More Filters + + {/* Calendar Selector */} + + + Calendars: + + + {allCalendarsLoading && Loading...} + + {allCalendarsIsError && ( + + {allCalendarsError?.message || 'Failed to load calendars'} + + )} + + {!allCalendarsLoading && !allCalendarsIsError && calendars.length > 0 && ( + + {calendars.map((cal) => { + const calendarId = cal.calendarId ?? cal.id!; + const checked = selectedCalendarIds.includes(calendarId); + const color = cal.color ?? cal.colorHexCode ?? '#999'; + return ( + toggleCalendar(calendarId)} + icon={} + checkedIcon={} + sx={{ + p: 0.5, + color, + '&.Mui-checked': { color } + }} + /> + } + label={ + t.typography.h6.fontFamily, + fontSize: 16, + color, + fontWeight: 500 + }} + > + {cal.name} + + } + /> + ); + })} + + )} + From f4e3ef3a878963e751a4b7c13c78d4b29c656c67 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 13 Dec 2025 00:01:23 -0500 Subject: [PATCH 337/477] docs --- src/backend/src/services/calendar.services.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 6705b58aad..dbad8f6df8 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -979,7 +979,7 @@ export default class CalendarService { * Approve event in the database * @param submitter The user submitting the request who must be a head or above. * @param eventId The id of the given event. - * @param organization The organization for which the event is being deleted. + * @param organization The organization for which the event is being approved. * * @returns The approved event. * @@ -1016,6 +1016,19 @@ export default class CalendarService { return eventTransformer(approvedEvent); } + /** + * Denies an event in the database + * @param submitter The user submitting the request who must be a head or above. + * @param eventId The id of the given event. + * @param organization The organization for which the event is being denied. + * + * @returns The denied event. + * + * @throws NotFoundException If the given eventId is not found. + * @throws InvalidOrganizationException If the given eventId is not part of the same organization. + * @throws DeletedException If the event has already been deleted. + * @throws AccessDeniedAdminOnlyException If the submitter is not an admin or head. + */ static async denyEvent(submitter: User, eventId: string, organization: Organization): Promise { const event = await prisma.event.findUnique({ where: { eventId } From c7973adcc70d8c91730b898713a442ddaa23f35f Mon Sep 17 00:00:00 2001 From: sam gunss Date: Fri, 12 Dec 2025 15:37:38 -0500 Subject: [PATCH 338/477] #3702: all-calendar-view pre-lint --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 169 +++++++++++------- 1 file changed, 102 insertions(+), 67 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index ab1e459fe0..cfe05f87cf 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -346,77 +346,112 @@ const NewCalendarPage = () => { } }} /> - + {/* Calendar Selector */} + + + t.typography.h4.fontFamily, + fontWeight: 400, + fontSize: 22 + }} + > + Calendars: + - {/* Calendar Selector */} - - - Calendars: - - - {allCalendarsLoading && Loading...} - - {allCalendarsIsError && ( - - {allCalendarsError?.message || 'Failed to load calendars'} - - )} - - {!allCalendarsLoading && !allCalendarsIsError && calendars.length > 0 && ( - - {calendars.map((cal) => { - const calendarId = cal.calendarId ?? cal.id!; - const checked = selectedCalendarIds.includes(calendarId); - const color = cal.color ?? cal.colorHexCode ?? '#999'; - return ( - toggleCalendar(calendarId)} - icon={} - checkedIcon={} - sx={{ - p: 0.5, - color, - '&.Mui-checked': { color } - }} - /> - } - label={ - t.typography.h6.fontFamily, - fontSize: 16, - color, - fontWeight: 500 - }} - > - {cal.name} - - } - /> - ); - })} - - )} + + + + {allCalendarsLoading && Loading...} + + {allCalendarsIsError && ( + + {(allCalendarsError as Error | undefined)?.message ?? 'Failed to load calendars'} + + )} + + {!allCalendarsLoading && !allCalendarsIsError && calendars.length > 0 && ( + + {calendars.map((cal) => { + const calendarId = cal.calendarId ?? cal.id!; + const checked = selectedCalendarIds.includes(calendarId); + const color = cal.color ?? cal.colorHexCode ?? '#999'; + return ( + toggleCalendar(calendarId)} + icon={} + checkedIcon={} + sx={{ + p: 0.5, + color, + '&.Mui-checked': { color } + }} + /> + } + label={ + t.typography.h6.fontFamily, + fontSize: 16, + color, + fontWeight: 500 + }} + > + {cal.name} + + } + /> + ); + })} + + )} + From ad5d707dcfa391bc30ed6c732c833bc18b917c58 Mon Sep 17 00:00:00 2001 From: sam gunss Date: Fri, 12 Dec 2025 16:24:16 -0500 Subject: [PATCH 339/477] prettier check --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index cfe05f87cf..00e81bdda2 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -3,7 +3,18 @@ * See the LICENSE file in the repository root folder for details. */ import { useState } from 'react'; -import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button, Checkbox, FormControlLabel, FormGroup } from '@mui/material'; +import { + Box, + Grid, + Stack, + Typography, + useMediaQuery, + useTheme, + Button, + Checkbox, + FormControlLabel, + FormGroup +} from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { Calendar, DayOfWeek, Event } from 'shared'; import CalendarDayCard from './CalendarDayCard'; @@ -346,7 +357,7 @@ const NewCalendarPage = () => { } }} /> - + { }} > {/* Calendar Selector */} - - - t.typography.h4.fontFamily, - fontWeight: 400, - fontSize: 22 - }} + + + t.typography.h4.fontFamily, + fontWeight: 400, + fontSize: 22 + }} > Calendars: @@ -398,9 +403,9 @@ const NewCalendarPage = () => { More Filters - + {allCalendarsLoading && Loading...} - + {allCalendarsIsError && ( {(allCalendarsError as Error | undefined)?.message ?? 'Failed to load calendars'} From c2f1393f857a578b8fadf6c05465706644027f8f Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sat, 13 Dec 2025 12:59:26 -0500 Subject: [PATCH 340/477] Adding the availability button --- .../pages/NewCalendarPage/EventClickPopup.tsx | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index e786bcd981..58b44cdb0a 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -3,7 +3,6 @@ import { Box, Button, IconButton, Popover, Stack, Typography, useTheme } from '@ import { Calendar, DayOfWeek, Event, EventType } from 'shared'; import { getTeamTypeIcon } from './CalendarDayCard'; import ConstructionIcon from '@mui/icons-material/Construction'; - import AccessTimeIcon from '@mui/icons-material/AccessTime'; import LocationOnIcon from '@mui/icons-material/LocationOn'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; @@ -15,8 +14,6 @@ import PeopleIcon from '@mui/icons-material/People'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; - - export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ ['UNCONFIRMED', ], @@ -47,6 +44,8 @@ const EventClickContent: React.FC = ({ event, eventTypes ); const calendarColor = specificCalendar?.color ?? 'gray'; + const showAvailabilityButton = Boolean(specificEventType?.requiresConfirmation); + const allPeople = [...event.requiredMembers, ...event.optionalMembers, ...event.confirmedMembers]; const seenIds = new Set(); const peopleNames: string[] = []; @@ -83,7 +82,6 @@ const EventClickContent: React.FC = ({ event, eventTypes maxWidth: 520 }} > - {/* Header row with edit icon */} = ({ event, eventTypes {event.location || 'N/A'} - - {/* Body sections */} - {/* People */} + {/* Members */} @@ -135,6 +131,35 @@ const EventClickContent: React.FC = ({ event, eventTypes + {/* View availability */} + {showAvailabilityButton && ( + + + + )} + {/* Machinery */} {hasMachinery && ( @@ -145,7 +170,7 @@ const EventClickContent: React.FC = ({ event, eventTypes )} - {/* Work package */} + {/* Work packages */} {hasWorkPackages && ( @@ -163,8 +188,6 @@ const EventClickContent: React.FC = ({ event, eventTypes - - {/* reminder button */} - + + )} + + {/* Teams */} + {hasValue(teamsText) && ( + + + + Teams: {teamsText} + + )} {/* Machinery */} - {hasMachinery && ( + {hasValue(machineryText) && ( - {machineryText} + Machinery: {machineryText} + + + )} + + {/* Shops */} + {hasValue(shopsText) && ( + + + + Shops: {shopsText} )} {/* Work packages */} - {hasWorkPackages && ( + {hasValue(workPackagesText) && ( - {workPackageText} + Work packages: {workPackagesText} + + + )} + + {/* Zoom link */} + {hasValue(event.zoomLink) && ( + + + + Zoom:{' '} + e.stopPropagation()}> + Zoom Link + + + + )} + + {/* Question document */} + {hasValue(event.questionDocument) && ( + + + + Question doc:{' '} + e.stopPropagation()}> + Question Document Link + )} {/* Description */} - - - - {descriptionText} - - + {hasValue(descriptionText) && ( + + + + Description: {descriptionText} + + + )} + + {/* Status */} + {hasValue(event.status) && ( + + {getStatusIcon(event.status!, false) ?? } + + Status: {event.status} + + + )} + + + } + > + +
+ ); +}; + +export default WarningTooltip; diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 23c44db151..ea6b414216 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -2,65 +2,19 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { - Box, - Button, - Link, - Stack, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, - Tooltip, - Typography -} from '@mui/material'; +import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; -import { useFilterEvents } from '../../hooks/calendar.hooks'; -import { useCurrentUser } from '../../hooks/users.hooks'; import React, { useEffect, useState } from 'react'; import { ConflictStatus, ScheduleSlot } from 'shared'; import { Event } from 'shared'; -import WarningIcon from '@mui/icons-material/Warning'; -import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; -import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; -import LoadingIndicator from '../../components/LoadingIndicator'; -import ErrorPage from '../ErrorPage'; +import WarningTooltip from './YourEventsComponents/WarningTooltip'; interface YourEventsHeadCells { id: string; label: string; } -const headCells: readonly YourEventsHeadCells[] = [ - { - id: 'eventsName', - label: 'Events Name' - }, - { - id: 'date', - label: 'Date' - }, - { - id: 'time', - label: 'Time' - }, - { - id: 'location', - label: 'Location' - }, - { - id: 'approvalBy', - label: 'Approval By' - }, - { - id: 'approvalStatus', - label: 'Approval Status' - } -]; - const earliestSchedules = new Map(); const getEarliestSchedule = (event: Event) => { @@ -76,24 +30,77 @@ const getEarliestSchedule = (event: Event) => { return result; }; -const YourEventsPage = () => { - const user = useCurrentUser(); - - const { - data: untransformedEvents, - isLoading: eventsLoading, - isError: eventsIsError, - error: eventsError - } = useFilterEvents({ - memberIds: [user.userId], - startPeriod: new Date(0), - endPeriod: new Date(2099, 11, 31) // Adjust as needed - }); +export interface EventTableArgs { + yourEvents: Event[]; + reviewEvents: Event[]; + tab: number; +} +const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvents }) => { // Convert to include proper dates // Done this way to allow the old events transformer to function properly // but provide better utility to this file (without breaking other files that may rely on eventTransformer) - const events = untransformedEvents?.map(filterEventTransformer); + + const headCells: readonly YourEventsHeadCells[] = [ + { + id: 'eventsName', + label: 'Events Name' + }, + { + id: 'date', + label: 'Date' + }, + { + id: 'time', + label: 'Time' + }, + { + id: 'location', + label: 'Location' + }, + ...(tab === 2 + ? [ + { + id: 'attendees', + label: 'Attendees' + } + ] + : []), + ...(tab === 1 + ? [ + { + id: 'approvalBy', + label: 'Approval By' + } + ] + : []), + ...(tab === 2 + ? [ + { + id: 'seekingApproval', + label: 'Seeking Approval' + } + ] + : []), + ...(tab === 1 + ? [ + { + id: 'approvalStatus', + label: 'Approval Status' + } + ] + : []), + ...(tab === 2 + ? [ + { + id: 'approveEvent', + label: 'Approve?' + } + ] + : []) + ]; + + const events = tab === 1 ? yourEvents : reviewEvents; const [, setUpdate] = useState(true); // Linting... @@ -104,9 +111,6 @@ const YourEventsPage = () => { return () => clearInterval(timer); }, []); - if (!events || eventsLoading) return ; - if (eventsIsError) return ; - return ( @@ -152,6 +156,9 @@ const YourEventsPage = () => { seconds: seconds % 60 }; + const attendeeNumber = + event.requiredMembers.length + event.optionalMembers.length - event.deniedMembers.length + 1; + return ( {event.title} @@ -179,95 +186,55 @@ const YourEventsPage = () => { 'N/A' )} - - {event.approvalRequiredFrom - ? `${event.approvalRequiredFrom.firstName} ${event.approvalRequiredFrom.lastName}` - : 'N/A'} - - - - - {event.approved === ConflictStatus.APPROVED - ? 'Approved' - : event.approved === ConflictStatus.PENDING - ? 'Pending' - : event.approved === ConflictStatus.DENIED - ? 'Denied' - : 'N/A'} - - {event.approved === ConflictStatus.DENIED && ( - - - - Your meeting approval has been denied, please reschedule or change your meeting location. - - - - } - > - {attendeeNumber}} + {tab === 1 && ( + + {event.approvalRequiredFrom + ? `${event.approvalRequiredFrom.firstName} ${event.approvalRequiredFrom.lastName}` + : 'N/A'} + + )} + {tab === 2 && ( + {`${event.userCreated.firstName} ${event.userCreated.lastName}`} + )} + {tab === 1 && ( + + + + {event.approved === ConflictStatus.APPROVED + ? 'Approved' + : event.approved === ConflictStatus.PENDING + ? 'Pending' + : event.approved === ConflictStatus.DENIED + ? 'Denied' + : 'N/A'} + + {event.approved === ConflictStatus.DENIED && ( + {}} /> -
+ )} + + + )} + {tab === 2 && ( + + {event.approved === ConflictStatus.PENDING + ? '...' + : event.approved === ConflictStatus.APPROVED + ? 'Yes' + : 'No'} + {event.approved === ConflictStatus.PENDING && ( + {}} + /> )} - - + + )} ); })} diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 638ce9e863..05f9fd5313 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -91,6 +91,8 @@ export interface FilterArgs { eventTypeIds?: string[]; eventIds?: string[]; approvedEvents?: boolean; + getPending?: boolean; + approvalIds?: string[]; startPeriod: Date; endPeriod: Date; } From 351e83fc8643971fc312235a501e54df565596bf Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 13 Dec 2025 20:41:18 -0500 Subject: [PATCH 355/477] comment not needed --- .../NewCalendarPage/YourEventsComponents/WarningTooltip.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx index e86de642c4..bec872b126 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx @@ -61,7 +61,6 @@ const WarningTooltip: React.FC = ({ warning, buttonText, on } }} onClick={(e) => { - // add in functionality soon e.stopPropagation(); onClick(); }} From de6a22756c1e2b8a94b2df7ceab7cae674ccde6d Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 14 Dec 2025 02:20:49 -0500 Subject: [PATCH 356/477] lint --- src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index e15e17e1c8..de4dbc8359 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -6,8 +6,7 @@ import { Box } from '@mui/material'; import FullPageTabs from '../../components/FullPageTabs'; import { useState } from 'react'; import { useCurrentUser } from '../../hooks/users.hooks'; -import { isAdmin, isHead, isLead } from 'shared'; -import SettingsPage from '../SettingsPage/SettingsPage'; +import { isHead, isLead } from 'shared'; import { useFilterEvents } from '../../hooks/calendar.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; From 87aa6144df600547d37eed92636d18cebe454628 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 14 Dec 2025 14:54:10 -0500 Subject: [PATCH 357/477] #3816 requested changes --- src/backend/tests/unit/calendar.test.ts | 2 +- .../NewCalendarPage/Components/EventModal.tsx | 161 ++++++++++++++++-- .../pages/NewCalendarPage/NewCalendarPage.tsx | 26 ++- 3 files changed, 161 insertions(+), 28 deletions(-) diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index f8674f2d45..f0b218de17 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -1928,7 +1928,7 @@ describe('Calendar Tests', () => { expect(result.requiredMembers[0].userId).toBe(newMember.userId); expect(result.optionalMembers).toHaveLength(1); expect(result.optionalMembers[0].userId).toBe(adminUser.userId); - expect(result.documentIds).toEqual(['doc2', 'doc3']); + expect(result.documents).toEqual([]); expect(result.approved).toBe(Conflict_Status.NO_CONFLICT); expect(result.approvalRequiredFrom).toBe(undefined); expect(result.questionDocumentLink).toBe('https://updated.com/questions.pdf'); diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx index 1cef4dabe6..be68f13398 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx @@ -323,6 +323,89 @@ const EventModal: React.FC = ({ const onFormSubmit = async (data: EventFormValues) => { try { + const scheduleSlots: Array<{ + days: DayOfWeek[]; + startTime?: Date; + endTime?: Date; + recurrenceNumber: number; + initialDateScheduled: Date; + allDay: boolean; + }> = []; + + // If recurrence is 0, automatically determine the day from the initial date + if (data.recurrenceNumber === 0) { + const dayOfWeek = data.scheduleDate.getDay(); // 0 = Sunday, 1 = Monday, etc. + const dayOfWeekEnum = [ + DayOfWeek.SUNDAY, + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SATURDAY + ][dayOfWeek]; + + // Create a schedule slot with just the initial date's day + scheduleSlots.push({ + days: [dayOfWeekEnum], + startTime: data.startTime, + endTime: data.endTime, + recurrenceNumber: 0, + initialDateScheduled: data.scheduleDate, + allDay: data.allDay + }); + } else { + // If there are recurring days selected + const dayOfWeek = data.scheduleDate.getDay(); + const dayOfWeekEnum = [ + DayOfWeek.SUNDAY, + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SATURDAY + ][dayOfWeek]; + + const selectedDays = data.days.length > 0 ? data.days : []; + const initialDayMatchesSelected = selectedDays.includes(dayOfWeekEnum); + + // If the initial date's day is NOT in the selected recurring days, + // create a separate slot for just the initial occurrence + if (!initialDayMatchesSelected && selectedDays.length > 0) { + scheduleSlots.push({ + days: [dayOfWeekEnum], + startTime: data.startTime, + endTime: data.endTime, + recurrenceNumber: 0, + initialDateScheduled: data.scheduleDate, + allDay: data.allDay + }); + } + + // Create the recurring schedule slot + if (selectedDays.length > 0) { + scheduleSlots.push({ + days: selectedDays, + startTime: data.startTime, + endTime: data.endTime, + recurrenceNumber: data.recurrenceNumber, + initialDateScheduled: data.scheduleDate, + allDay: data.allDay + }); + } else { + // If no days selected, use the initial date's day for recurring + scheduleSlots.push({ + days: [dayOfWeekEnum], + startTime: data.startTime, + endTime: data.endTime, + recurrenceNumber: data.recurrenceNumber, + initialDateScheduled: data.scheduleDate, + allDay: data.allDay + }); + } + } + const submitData: EventRoutePayload = { title: data.title, eventTypeId: data.eventTypeId, @@ -338,16 +421,7 @@ const EventModal: React.FC = ({ documentFiles: data.documentFiles, questionDocumentLink: data.questionDocumentLink, description: data.description, - scheduleSlot: [ - { - days: data.days, - startTime: data.startTime, - endTime: data.endTime, - recurrenceNumber: data.recurrenceNumber, - initialDateScheduled: data.scheduleDate, - allDay: data.allDay - } - ] + scheduleSlot: scheduleSlots }; await onSubmit(submitData); @@ -486,6 +560,19 @@ const EventModal: React.FC = ({ error: !!errors.scheduleDate, onClick: () => setDatePickerOpen(true), sx: { minWidth: 150 } + }, + day: { + sx: { + '&.Mui-selected': { + backgroundColor: '#EF4345 !important', + '&:hover': { + backgroundColor: '#d32f2f !important' + }, + '&:focus': { + backgroundColor: '#EF4345 !important' + } + } + } } }} /> @@ -510,6 +597,31 @@ const EventModal: React.FC = ({ error: !!errors.startTime, onClick: () => setStartTimePickerOpen(true), sx: { width: 100 } + }, + layout: { + sx: { + '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { + backgroundColor: '#EF4345', + borderColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { + backgroundColor: '#EF4345 !important' + }, + '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + }, + '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + } + } } }} /> @@ -532,6 +644,31 @@ const EventModal: React.FC = ({ error: !!errors.endTime, onClick: () => setEndTimePickerOpen(true), sx: { width: 100 } + }, + layout: { + sx: { + '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { + backgroundColor: '#EF4345', + borderColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { + backgroundColor: '#EF4345 !important' + }, + '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + }, + '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + } + } } }} /> @@ -648,11 +785,11 @@ const EventModal: React.FC = ({ height: 40, borderRadius: '50%', p: 0, - bgcolor: isSelected ? 'primary.main' : 'transparent', + bgcolor: isSelected ? '#EF4345' : 'transparent', color: isSelected ? 'white' : '#000', borderColor: '#9e9e9e', '&:hover': { - bgcolor: isSelected ? 'primary.dark' : '#e0e0e0' + bgcolor: isSelected ? '#d32f2f' : '#e0e0e0' } }} > diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 5736fd7420..3eedfd69e0 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -208,26 +208,22 @@ const NewCalendarPage = () => { try { const { scheduleSlot, documentFiles, ...eventData } = data; - const [slot] = scheduleSlot; - - if (!slot) throw new Error('Missing scheduleSlot'); - - const { days, startTime, endTime, recurrenceNumber, initialDateScheduled, allDay } = slot; + if (!scheduleSlot || scheduleSlot.length === 0) { + throw new Error('Missing scheduleSlot'); + } // Create the event first without documents const createArgs = { ...eventData, documentIds: [], - scheduleSlot: [ - { - days, - startTime, - endTime, - recurrenceNumber, - initialDateScheduled, - allDay - } - ] + scheduleSlot: scheduleSlot.map((slot) => ({ + days: slot.days, + startTime: slot.startTime, + endTime: slot.endTime, + recurrenceNumber: slot.recurrenceNumber, + initialDateScheduled: slot.initialDateScheduled, + allDay: slot.allDay + })) }; const createdEvent = await createEvent(createArgs); From 215910f02141390c521fa7bed9eebe5da2606df8 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 14 Dec 2025 15:26:43 -0500 Subject: [PATCH 358/477] alteration to calendar population (unrelated to this ticket but it needs to be done) --- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 55bd25492a..83ce63101f 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -54,7 +54,8 @@ const NewCalendarPage = () => { startPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, 15), endPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15), memberIds: memberIds.concat(additionalMemberIds), - teamIds: teamIds.concat(additionalTeamIds) + teamIds: teamIds.concat(additionalTeamIds), + approvedEvents: true }); const { From ddcdaf142a37b492f52fb51b9f2622cdb3f1abea Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sun, 14 Dec 2025 17:07:33 -0500 Subject: [PATCH 359/477] #3798 removed set reminder button changed route for availability button --- .../pages/NewCalendarPage/EventClickPopup.tsx | 26 +++---------------- .../UserScheduleSettingsView.tsx | 15 +++++++++-- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 4ab8dfcb00..aeff0fdbee 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -69,7 +69,8 @@ const EventClickContent: React.FC = ({ event, eventTypes const showAvailabilityButton = Boolean(specificEventType?.requiresConfirmation); - const availabilityUrl = `${routes.SETTINGS_PREFERENCES}?eventId=${event.eventId}`; + const editUrl = `${routes.SETTINGS_PREFERENCES}?eventId=${event.eventId}`; + const availabilityUrl = `${routes.SETTINGS_PREFERENCES}?openAvailability=true`; const requiredText = event.requiredMembers.length > 0 ? joinPeople(event.requiredMembers) : ''; const optionalText = event.optionalMembers.length > 0 ? joinPeople(event.optionalMembers) : ''; @@ -101,7 +102,7 @@ const EventClickContent: React.FC = ({ event, eventTypes = ({ event, eventTypes {hasValue(event.zoomLink) && ( - e.stopPropagation()}> Zoom Link @@ -300,26 +300,6 @@ const EventClickContent: React.FC = ({ event, eventTypes )} - - - - ); }; diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx index ba070b9e4e..55cc618eb9 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx @@ -12,6 +12,7 @@ import SingleAvailabilityModal from './Availability/SingleAvailabilityModal'; import AvailabilityEditModal from './Availability/AvailabilityEditModal'; import { useMarkUserConfirmed } from '../../../hooks/calendar.hooks'; import { useToast } from '../../../hooks/toasts.hooks'; +import { useHistory, useLocation } from 'react-router-dom'; const UserScheduleSettingsView = ({ scheduleSettings, @@ -27,12 +28,13 @@ const UserScheduleSettingsView = ({ const [confirmedAvailabilities, setConfirmedAvailabilities] = useState(new Map()); const { mutateAsync } = useMarkUserConfirmed(event?.eventId || ''); - // Get the first scheduled date from the event + const history = useHistory(); + const location = useLocation(); + const firstScheduledDate = event?.scheduledTimes?.[0]?.initialDateScheduled ? new Date(event.scheduledTimes[0].initialDateScheduled as any) : undefined; - // Get work package names for the event title const workPackageNames = event?.workPackages.map((wp) => wp.wbsElement.name).join(', ') || 'Event'; const confirmModalTitle = @@ -66,6 +68,15 @@ const UserScheduleSettingsView = ({ } }, [confirmedAvailabilities.size, scheduleSettings.availabilities, firstDate]); + useEffect(() => { + const params = new URLSearchParams(location.search); + if (params.get('openAvailability') === 'true') { + setAvailabilityOpen(true); + params.delete('openAvailability'); + history.replace({ ...location, search: params.toString() ? `?${params.toString()}` : '' }); + } + }, [location, history]); + return ( Date: Sun, 14 Dec 2025 17:29:55 -0500 Subject: [PATCH 360/477] #3798 route change again --- .../src/pages/NewCalendarPage/EventClickPopup.tsx | 5 +++-- .../UserScheduleSettingsView.tsx | 15 ++------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index aeff0fdbee..9431248131 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -67,10 +67,11 @@ const EventClickContent: React.FC = ({ event, eventTypes ); const calendarColor = specificCalendar?.color ?? 'gray'; - const showAvailabilityButton = Boolean(specificEventType?.requiresConfirmation); + const showAvailabilityButton = true; const editUrl = `${routes.SETTINGS_PREFERENCES}?eventId=${event.eventId}`; - const availabilityUrl = `${routes.SETTINGS_PREFERENCES}?openAvailability=true`; + const availabilityUrl = `${routes.CALENDAR}/${event.eventId}`; + const requiredText = event.requiredMembers.length > 0 ? joinPeople(event.requiredMembers) : ''; const optionalText = event.optionalMembers.length > 0 ? joinPeople(event.optionalMembers) : ''; diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx index 55cc618eb9..ba070b9e4e 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx @@ -12,7 +12,6 @@ import SingleAvailabilityModal from './Availability/SingleAvailabilityModal'; import AvailabilityEditModal from './Availability/AvailabilityEditModal'; import { useMarkUserConfirmed } from '../../../hooks/calendar.hooks'; import { useToast } from '../../../hooks/toasts.hooks'; -import { useHistory, useLocation } from 'react-router-dom'; const UserScheduleSettingsView = ({ scheduleSettings, @@ -28,13 +27,12 @@ const UserScheduleSettingsView = ({ const [confirmedAvailabilities, setConfirmedAvailabilities] = useState(new Map()); const { mutateAsync } = useMarkUserConfirmed(event?.eventId || ''); - const history = useHistory(); - const location = useLocation(); - + // Get the first scheduled date from the event const firstScheduledDate = event?.scheduledTimes?.[0]?.initialDateScheduled ? new Date(event.scheduledTimes[0].initialDateScheduled as any) : undefined; + // Get work package names for the event title const workPackageNames = event?.workPackages.map((wp) => wp.wbsElement.name).join(', ') || 'Event'; const confirmModalTitle = @@ -68,15 +66,6 @@ const UserScheduleSettingsView = ({ } }, [confirmedAvailabilities.size, scheduleSettings.availabilities, firstDate]); - useEffect(() => { - const params = new URLSearchParams(location.search); - if (params.get('openAvailability') === 'true') { - setAvailabilityOpen(true); - params.delete('openAvailability'); - history.replace({ ...location, search: params.toString() ? `?${params.toString()}` : '' }); - } - }, [location, history]); - return ( Date: Sun, 14 Dec 2025 17:32:05 -0500 Subject: [PATCH 361/477] #3798 prettier --- src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 9431248131..5e294064e6 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -72,7 +72,6 @@ const EventClickContent: React.FC = ({ event, eventTypes const editUrl = `${routes.SETTINGS_PREFERENCES}?eventId=${event.eventId}`; const availabilityUrl = `${routes.CALENDAR}/${event.eventId}`; - const requiredText = event.requiredMembers.length > 0 ? joinPeople(event.requiredMembers) : ''; const optionalText = event.optionalMembers.length > 0 ? joinPeople(event.optionalMembers) : ''; const confirmedText = event.confirmedMembers.length > 0 ? joinPeople(event.confirmedMembers) : ''; From 80acd97ca981871fe638dabb5ba95cb1dbadd875 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Sun, 14 Dec 2025 20:13:57 -0500 Subject: [PATCH 362/477] #3798 small change --- .../UserScheduleSettings/UserScheduleSettingsView.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx index ba070b9e4e..e323c78f17 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx @@ -27,10 +27,11 @@ const UserScheduleSettingsView = ({ const [confirmedAvailabilities, setConfirmedAvailabilities] = useState(new Map()); const { mutateAsync } = useMarkUserConfirmed(event?.eventId || ''); - // Get the first scheduled date from the event - const firstScheduledDate = event?.scheduledTimes?.[0]?.initialDateScheduled - ? new Date(event.scheduledTimes[0].initialDateScheduled as any) - : undefined; + // Get first scheduled date from event + let firstScheduledDate: Date | undefined; + if (event && event.scheduledTimes && event.scheduledTimes.length > 0 && event.scheduledTimes[0].initialDateScheduled) { + firstScheduledDate = new Date(event.scheduledTimes[0].initialDateScheduled); + } // Get work package names for the event title const workPackageNames = event?.workPackages.map((wp) => wp.wbsElement.name).join(', ') || 'Event'; From 4c87083cb65f1e0a036be2b0f831a9255cf54884 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 14 Dec 2025 21:23:46 -0500 Subject: [PATCH 363/477] #3816 requested changes --- .../src/controllers/calendar.controllers.ts | 9 +---- src/backend/src/routes/calendar.routes.ts | 38 +++++++++++++++++-- src/backend/src/utils/validation.utils.ts | 9 +++++ 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 21cf5cd049..4b283ed0c8 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -1,7 +1,6 @@ import { NextFunction, Request, Response } from 'express'; import CalendarService from '../services/calendar.services'; import { getCurrentUserWithUserSettings } from '../utils/auth.utils'; -import { HttpException } from '../utils/errors.utils'; export default class CalendarController { static async createEventType(req: Request, res: Response, next: NextFunction) { @@ -371,13 +370,9 @@ export default class CalendarController { try { const { file } = req; const { eventId } = req.params; - if (!file) throw new HttpException(400, 'Invalid or undefined document data'); - const receipt = await CalendarService.uploadDocument(eventId, file, req.currentUser, req.organization); - const isProd = process.env.NODE_ENV === 'production'; - const origin = isProd ? 'https://finishlinebyner.com' : 'http://localhost:3000'; + const document = await CalendarService.uploadDocument(eventId, file!, req.currentUser, req.organization); - res.header('Access-Control-Allow-Origin', origin); - res.status(200).json(receipt); + res.status(200).json(document); } catch (error: unknown) { next(error); } diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 8cd07fa05b..949b5db41f 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,13 +1,39 @@ import express from 'express'; import { body, param } from 'express-validator'; -import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek, isEventStatus } from '../utils/validation.utils'; +import { + intMinZero, + isDate, + nonEmptyString, + validateInputs, + isDayOfWeek, + isEventStatus, + requireFile +} from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; import multer, { memoryStorage } from 'multer'; import { MAX_FILE_SIZE } from 'shared'; const calendarRouter = express.Router(); -const upload = multer({ limits: { fileSize: MAX_FILE_SIZE }, storage: memoryStorage() }); +const upload = multer({ + limits: { fileSize: MAX_FILE_SIZE }, + storage: memoryStorage(), + fileFilter: (_req, file, cb) => { + const allowedMimeTypes = [ + 'application/pdf', + 'application/msword', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'image/jpeg', + 'image/png' + ]; + + if (allowedMimeTypes.includes(file.mimetype)) { + cb(null, true); + } else { + cb(new Error('Invalid file type')); + } + } +}); calendarRouter.post( '/create', @@ -137,7 +163,13 @@ calendarRouter.post( calendarRouter.get('/document/:fileId', CalendarController.downloadDocument); -calendarRouter.post('/event/:eventId/upload-document', upload.single('pdf'), CalendarController.uploadDocument); +calendarRouter.post( + '/event/:eventId/upload-document', + upload.single('pdf'), + requireFile(body('file')), + validateInputs, + CalendarController.uploadDocument +); calendarRouter.post('/event/:eventId/approve', CalendarController.approveEvent); diff --git a/src/backend/src/utils/validation.utils.ts b/src/backend/src/utils/validation.utils.ts index a8d090c06c..73c04c4b57 100644 --- a/src/backend/src/utils/validation.utils.ts +++ b/src/backend/src/utils/validation.utils.ts @@ -250,3 +250,12 @@ export const financeDashboardFilterValidators = [ nonEmptyString(query('endDate')).optional(), nonEmptyString(query('carNumber')).optional() ]; + +export const requireFile = (chain: ValidationChain): ValidationChain => { + return chain.custom((_value, { req }) => { + if (!req.file) { + throw new Error('Invalid or undefined document data'); + } + return true; + }); +}; From e1b9b6b43ac063188d29124ac300629500e5d3fa Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 14 Dec 2025 23:47:53 -0500 Subject: [PATCH 364/477] utils and minor nitpicks --- .../pages/NewCalendarPage/YourEventsPage.tsx | 40 +++++++++---------- src/frontend/src/utils/calendar.utils.ts | 32 ++++++++++++++- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index ea6b414216..bbd0b6355f 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -6,27 +6,29 @@ import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, Tabl import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; import React, { useEffect, useState } from 'react'; -import { ConflictStatus, ScheduleSlot } from 'shared'; +import { ConflictStatus } from 'shared'; import { Event } from 'shared'; import WarningTooltip from './YourEventsComponents/WarningTooltip'; +import { getMeetingDates } from '../../utils/calendar.utils'; interface YourEventsHeadCells { id: string; label: string; } -const earliestSchedules = new Map(); +const getNextMeetingTime = (event: Event) => { + const times: Date[] = getMeetingDates(event); -const getEarliestSchedule = (event: Event) => { - if (earliestSchedules.has(event.eventId)) { - return earliestSchedules.get(event.eventId)!; - } + times.sort((a, b) => a.getUTCSeconds() - b.getUTCSeconds()); + let result = times[times.length - 1]; + times.forEach((date) => { + const now = new Date(); + const diffMs = date.getTime() - now.getTime(); + if (diffMs > 0 && date.getTime() < result.getTime()) { + result = date; + } + }); - const [result] = event.scheduledTimes - .filter((schedule): schedule is ScheduleSlot & { startTime: Date } => schedule.startTime !== undefined) - .sort((a, b) => a.startTime.getUTCSeconds() - b.startTime.getUTCSeconds()); - - earliestSchedules.set(event.eventId, result); return result; }; @@ -135,22 +137,18 @@ const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvent {events?.map((event) => { - const earliestSchedule = getEarliestSchedule(event); + const earliestSchedule = new Date(getNextMeetingTime(event)); const now = new Date(); - const diffMs = earliestSchedule.startTime.getTime() - now.getTime(); + const diffMs = earliestSchedule.getTime() - now.getTime(); const seconds = Math.floor(diffMs / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); - // Rough month estimate (30 days) - const months = Math.floor(days / 30); - const timeAway = { passed: diffMs <= 0, - months, - days: days % 30, + days, hours: hours % 24, minutes: minutes % 60, seconds: seconds % 60 @@ -163,11 +161,11 @@ const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvent {event.title} - {new Date(earliestSchedule.startTime).toLocaleDateString()}{' '} - {!timeAway.passed ? ` - In ${timeAway.months}m : ${timeAway.days}d` : '- Passed'} + {new Date(earliestSchedule).toLocaleDateString()}{' '} + {!timeAway.passed ? ` - In ${timeAway.days}d` : '- Passed'} - {new Date(earliestSchedule.startTime).toLocaleTimeString('en-US', { + {new Date(earliestSchedule).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' })}{' '} diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index c94ded949c..028aab9a52 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -1,4 +1,4 @@ -import { DayOfWeek } from 'shared'; +import { DayOfWeek, Event } from 'shared'; export const convertDayToInt = (day: DayOfWeek) => { switch (day) { @@ -20,3 +20,33 @@ export const convertDayToInt = (day: DayOfWeek) => { return -1; } }; + +export const getMeetingDates = (event: Event) => { + const times: Date[] = []; + event.scheduledTimes.forEach((schedule) => { + schedule.days.forEach((day) => { + const startTimeDate = new Date(schedule.initialDateScheduled); + const timezoneOffset = startTimeDate.getTimezoneOffset() * 60000; + const startDate = new Date(startTimeDate.getTime() + timezoneOffset); + const offset = startDate.getDay() - convertDayToInt(day); + startDate.setDate(startDate.getDate() - offset); + + // Note : schedule.startTime likely gets converted to the users timezone by default + startDate.setHours(schedule.startTime?.getHours() ?? 0); + startDate.setMinutes(schedule.startTime?.getMinutes() ?? 0); + + // adjust for the users time + const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); + times.push(startDateAdjusted); + + for (let i = 1; i <= schedule.recurrenceNumber; i++) { + const nextDate = new Date(startDateAdjusted); + nextDate.setDate(nextDate.getDate() + 7 * i); + + times.push(nextDate); + } + }); + }); + + return times; +}; From f8e8d7af02ede83122b3f3ec2d9b84fd537e7550 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sun, 14 Dec 2025 23:56:26 -0500 Subject: [PATCH 365/477] note to self --- src/frontend/src/utils/calendar.utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 028aab9a52..2b5cf92ef0 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -21,6 +21,7 @@ export const convertDayToInt = (day: DayOfWeek) => { } }; +// Get a list of dates for user viewing purposes (formatted to their timezone) export const getMeetingDates = (event: Event) => { const times: Date[] = []; event.scheduledTimes.forEach((schedule) => { From 40b20ddda0f4597e1868ef097e3e4daa5d189770 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Dec 2025 02:19:51 -0500 Subject: [PATCH 366/477] fun stuff --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 71 ++++++------------- src/frontend/src/utils/calendar.utils.ts | 26 ++++++- 2 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 83ce63101f..d00f779a34 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -19,7 +19,8 @@ import FilterModal from './FilterModal'; import { DateCalendar } from '@mui/x-date-pickers'; import { useCurrentUser } from '../../hooks/users.hooks'; import { useGetUsersTeams } from '../../hooks/teams.hooks'; -import { convertDayToInt } from '../../utils/calendar.utils'; +import { convertIntToDay, getMeetingDates } from '../../utils/calendar.utils'; +import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; const NewCalendarPage = () => { const theme = useTheme(); @@ -102,8 +103,10 @@ const NewCalendarPage = () => { if (isLoading || !allEvents) return ; if (isError) return ; + const transformedEvents = allEvents.map(filterEventTransformer); + // Sort events by their first occurrence's start time - const sortedEvents = [...allEvents].sort((event1, event2) => { + const sortedEvents = [...transformedEvents].sort((event1, event2) => { const time1 = event1.scheduledTimes[0]?.startTime ? new Date(event1.scheduledTimes[0].startTime).getTime() : 0; const time2 = event2.scheduledTimes[0]?.startTime ? new Date(event2.scheduledTimes[0].startTime).getTime() : 0; return time1 - time2; @@ -113,55 +116,23 @@ const NewCalendarPage = () => { const dayDict = new Map(); sortedEvents.forEach((event) => { - event.scheduledTimes.forEach((slot) => { - if (!slot.initialDateScheduled) return; - - // startTime is already a full timestamp, just use it directly - const startTimeDate = new Date(slot.initialDateScheduled); - - // Accessing the date actually converts it to local time, which causes the date to be off. This is a workaround. - // 60000 is for millisecond conversion - const convertedStartTime = new Date(startTimeDate.getTime() + startTimeDate.getTimezoneOffset() * 60000); - - const dayInt = convertedStartTime.getDay(); - - slot.days.forEach((day) => { - const eventDate = new Date(convertedStartTime); - eventDate.setHours(0, 0, 0, 0); - const offset = dayInt - convertDayToInt(day); - - eventDate.setDate(eventDate.getDate() - offset); - const date = datePipe(new Date(eventDate.getTime())); - - dayDict.set(date, day); - - if (eventDict.has(date)) { - // Check if this event is already in this date's array to avoid duplicates - const existingEvents = eventDict.get(date)!; - if (!existingEvents.find((e) => e.eventId === event.eventId)) { - existingEvents.push(event); - } - } else { - eventDict.set(date, [event]); - } - - for (let i = 1; i <= slot.recurrenceNumber; i++) { - const nextDate = new Date(eventDate); - nextDate.setDate(nextDate.getDate() + 7 * i); - - const date = datePipe(new Date(nextDate.getTime())); - dayDict.set(date, day); - - if (eventDict.has(date)) { - const existingEvents = eventDict.get(date)!; - if (!existingEvents.find((e) => e.eventId === event.eventId)) { - existingEvents.push(event); - } - } else { - eventDict.set(date, [event]); - } + const times: Date[] = getMeetingDates(event); + + times.forEach((date) => { + const eventDate = new Date(date); + const dateString = datePipe(eventDate); + eventDate.setHours(0, 0, 0, 0); + const day = convertIntToDay(eventDate.getDay()); + dayDict.set(dateString, day); + if (eventDict.has(dateString)) { + // Check if this event is already in this date's array to avoid duplicates + const existingEvents = eventDict.get(dateString)!; + if (!existingEvents.find((e) => e.eventId === event.eventId)) { + existingEvents.push(event); } - }); + } else { + eventDict.set(dateString, [event]); + } }); }); diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 2b5cf92ef0..3239705bfc 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -21,7 +21,29 @@ export const convertDayToInt = (day: DayOfWeek) => { } }; +export const convertIntToDay = (num: number) => { + switch (num) { + case 1: + return DayOfWeek.MONDAY; + case 2: + return DayOfWeek.TUESDAY; + case 3: + return DayOfWeek.WEDNESDAY; + case 4: + return DayOfWeek.THURSDAY; + case 5: + return DayOfWeek.FRIDAY; + case 6: + return DayOfWeek.SATURDAY; + case 0: + return DayOfWeek.SUNDAY; + default: + return DayOfWeek.MONDAY; + } +}; + // Get a list of dates for user viewing purposes (formatted to their timezone) +// Should be used when events need to be populated/displayed export const getMeetingDates = (event: Event) => { const times: Date[] = []; event.scheduledTimes.forEach((schedule) => { @@ -38,7 +60,9 @@ export const getMeetingDates = (event: Event) => { // adjust for the users time const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); - times.push(startDateAdjusted); + + // potentially needed to prevent extra events from showing up before the initial date + if (new Date(schedule.initialDateScheduled).getTime() >= startDateAdjusted.getTime()) times.push(startDateAdjusted); for (let i = 1; i <= schedule.recurrenceNumber; i++) { const nextDate = new Date(startDateAdjusted); From ba74a40ddf70edfa524fce472e479fc09c3bade3 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Dec 2025 02:21:52 -0500 Subject: [PATCH 367/477] more notes to self (or notes to all???) --- src/frontend/src/utils/calendar.utils.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 3239705bfc..fe82ecd4b3 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -50,11 +50,18 @@ export const getMeetingDates = (event: Event) => { schedule.days.forEach((day) => { const startTimeDate = new Date(schedule.initialDateScheduled); const timezoneOffset = startTimeDate.getTimezoneOffset() * 60000; + + // get the initial date (adjusted to match UTC) const startDate = new Date(startTimeDate.getTime() + timezoneOffset); + + // Calculate offset based on the current day being checked const offset = startDate.getDay() - convertDayToInt(day); + + // apply offset to get the true date of this specific event startDate.setDate(startDate.getDate() - offset); // Note : schedule.startTime likely gets converted to the users timezone by default + // set the hour and minutes startDate.setHours(schedule.startTime?.getHours() ?? 0); startDate.setMinutes(schedule.startTime?.getMinutes() ?? 0); @@ -64,10 +71,10 @@ export const getMeetingDates = (event: Event) => { // potentially needed to prevent extra events from showing up before the initial date if (new Date(schedule.initialDateScheduled).getTime() >= startDateAdjusted.getTime()) times.push(startDateAdjusted); + // add additional events for each recurrence on this day for (let i = 1; i <= schedule.recurrenceNumber; i++) { const nextDate = new Date(startDateAdjusted); nextDate.setDate(nextDate.getDate() + 7 * i); - times.push(nextDate); } }); From 2f7c00df5df6270d33517fa16858167a1798282b Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Dec 2025 02:22:45 -0500 Subject: [PATCH 368/477] even more notes to self --- src/frontend/src/utils/calendar.utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index fe82ecd4b3..204a512dce 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -52,6 +52,7 @@ export const getMeetingDates = (event: Event) => { const timezoneOffset = startTimeDate.getTimezoneOffset() * 60000; // get the initial date (adjusted to match UTC) + // this is done to ensure offset is properly calculated const startDate = new Date(startTimeDate.getTime() + timezoneOffset); // Calculate offset based on the current day being checked From bb646659adea9f9ab07088ef28e0b72f883b3971 Mon Sep 17 00:00:00 2001 From: Samuel Shrestha Date: Mon, 15 Dec 2025 14:25:12 -0500 Subject: [PATCH 369/477] filtering fixed --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 84 ++++++++----------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 00e81bdda2..5099ffc47f 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -16,7 +16,7 @@ import { FormGroup } from '@mui/material'; import PageLayout from '../../components/PageLayout'; -import { Calendar, DayOfWeek, Event } from 'shared'; +import { DayOfWeek, Event } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; @@ -34,13 +34,6 @@ import { convertDayToInt } from '../../utils/calendar.utils'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; -type CalendarWithColor = Calendar & { - id?: string; - calendarId?: string; - color?: string; - colorHexCode?: string; -}; - const NewCalendarPage = () => { const theme = useTheme(); const { @@ -65,18 +58,6 @@ const NewCalendarPage = () => { const [additionalMemberIds, setAdditionalMemberIds] = useState([user.userId]); const [additionalTeamIds, setAdditionalTeamIds] = useState(teamList); - const { - isLoading, - isError, - error, - data: allEvents - } = useFilterEvents({ - startPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, 15), - endPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15), - memberIds: memberIds.concat(additionalMemberIds), - teamIds: teamIds.concat(additionalTeamIds) - }); - const { data: allEventTypes, isLoading: allEventTypesLoading, @@ -91,7 +72,7 @@ const NewCalendarPage = () => { error: allCalendarsError } = useAllCalendars(); - const calendars = (allCalendars ?? []) as CalendarWithColor[]; + const calendars = allCalendars ?? []; const [selectedCalendarIds, setSelectedCalendarIds] = useState([]); const [selectedEvent, setSelectedEvent] = useState(); @@ -99,6 +80,19 @@ const NewCalendarPage = () => { const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); + const { + isLoading, + isError, + error, + data: allEvents + } = useFilterEvents({ + startPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, 15), + endPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15), + memberIds: memberIds.concat(additionalMemberIds), + teamIds: teamIds.concat(additionalTeamIds), + calendarIds: selectedCalendarIds.length ? selectedCalendarIds: undefined + }); + const toggleCalendar = (calendarId: string) => { setSelectedCalendarIds((prev) => prev.includes(calendarId) ? prev.filter((id) => id !== calendarId) : [...prev, calendarId] @@ -128,24 +122,15 @@ const NewCalendarPage = () => { if (isLoading || !allEvents) return ; if (isError) return ; - const getEventCalendarId = (event: any): string | undefined => - event.calendarId ?? event.calendar?.id ?? event.calendar?.calendarId; - - const baseEvents = allEvents.filter((event) => { - if (selectedCalendarIds.length === 0) { - return true; - } - - const calId = getEventCalendarId(event); - if (!calId) { - return false; - } - - return selectedCalendarIds.includes(calId); - }); + type EventWithCalendar = Event & { + calendarId?: string | null; + calendar?: { + calendarId?: string | null; + } | null; + }; // Sort events by their first occurrence's start time - const sortedEvents = [...baseEvents].sort((event1, event2) => { + const sortedEvents = [...allEvents].sort((event1, event2) => { const time1 = event1.scheduledTimes[0]?.startTime ? new Date(event1.scheduledTimes[0].startTime).getTime() : 0; const time2 = event2.scheduledTimes[0]?.startTime ? new Date(event2.scheduledTimes[0].startTime).getTime() : 0; return time1 - time2; @@ -223,6 +208,17 @@ const NewCalendarPage = () => { .concat([...Array(daysInMonth(displayMonthYear)).keys()].map((day) => day + 1)) .concat(paddingArrayEnd.length < 7 ? paddingArrayEnd : []); + + if ( + isLoading || + !allEvents || + allTeamTypesLoading || + allEventTypesLoading || + allCalendarsLoading || + allTeamsLoading + ) return ; + + if (!allTeamTypes || allTeamTypesLoading) return ; if (allTeamTypesIsError) return ; @@ -404,20 +400,12 @@ const NewCalendarPage = () => { - {allCalendarsLoading && Loading...} - - {allCalendarsIsError && ( - - {(allCalendarsError as Error | undefined)?.message ?? 'Failed to load calendars'} - - )} - - {!allCalendarsLoading && !allCalendarsIsError && calendars.length > 0 && ( + { (calendars.length > 0) && ( {calendars.map((cal) => { - const calendarId = cal.calendarId ?? cal.id!; + const calendarId = cal.calendarId; const checked = selectedCalendarIds.includes(calendarId); - const color = cal.color ?? cal.colorHexCode ?? '#999'; + const color = cal.color; return ( Date: Mon, 15 Dec 2025 14:33:04 -0500 Subject: [PATCH 370/477] lint/prettier check --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 5099ffc47f..7467da6dc9 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -90,7 +90,7 @@ const NewCalendarPage = () => { endPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15), memberIds: memberIds.concat(additionalMemberIds), teamIds: teamIds.concat(additionalTeamIds), - calendarIds: selectedCalendarIds.length ? selectedCalendarIds: undefined + calendarIds: selectedCalendarIds.length ? selectedCalendarIds : undefined }); const toggleCalendar = (calendarId: string) => { @@ -208,16 +208,8 @@ const NewCalendarPage = () => { .concat([...Array(daysInMonth(displayMonthYear)).keys()].map((day) => day + 1)) .concat(paddingArrayEnd.length < 7 ? paddingArrayEnd : []); - - if ( - isLoading || - !allEvents || - allTeamTypesLoading || - allEventTypesLoading || - allCalendarsLoading || - allTeamsLoading - ) return ; - + if (isLoading || !allEvents || allTeamTypesLoading || allEventTypesLoading || allCalendarsLoading || allTeamsLoading) + return ; if (!allTeamTypes || allTeamTypesLoading) return ; if (allTeamTypesIsError) return ; @@ -400,12 +392,11 @@ const NewCalendarPage = () => { - { (calendars.length > 0) && ( + {calendars.length > 0 && ( {calendars.map((cal) => { - const calendarId = cal.calendarId; + const { calendarId, color, name } = cal; const checked = selectedCalendarIds.includes(calendarId); - const color = cal.color; return ( Date: Mon, 15 Dec 2025 14:37:33 -0500 Subject: [PATCH 371/477] additional lint --- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 7467da6dc9..6be6c685d8 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -122,13 +122,6 @@ const NewCalendarPage = () => { if (isLoading || !allEvents) return ; if (isError) return ; - type EventWithCalendar = Event & { - calendarId?: string | null; - calendar?: { - calendarId?: string | null; - } | null; - }; - // Sort events by their first occurrence's start time const sortedEvents = [...allEvents].sort((event1, event2) => { const time1 = event1.scheduledTimes[0]?.startTime ? new Date(event1.scheduledTimes[0].startTime).getTime() : 0; From 1cce23610c3d9ab505752008b99fc0c348df294a Mon Sep 17 00:00:00 2001 From: Samuel Shrestha Date: Mon, 15 Dec 2025 15:03:56 -0500 Subject: [PATCH 372/477] last fix promise --- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 6be6c685d8..43b1b9b2be 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -388,7 +388,7 @@ const NewCalendarPage = () => { {calendars.length > 0 && ( {calendars.map((cal) => { - const { calendarId, color, name } = cal; + const { calendarId, color} = cal; const checked = selectedCalendarIds.includes(calendarId); return ( Date: Mon, 15 Dec 2025 15:06:30 -0500 Subject: [PATCH 373/477] sike prettier check --- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 43b1b9b2be..1fffe98f70 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -388,7 +388,7 @@ const NewCalendarPage = () => { {calendars.length > 0 && ( {calendars.map((cal) => { - const { calendarId, color} = cal; + const { calendarId, color } = cal; const checked = selectedCalendarIds.includes(calendarId); return ( Date: Mon, 15 Dec 2025 16:46:29 -0600 Subject: [PATCH 374/477] #3703 Added Upcoming Meetings to calendar --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 59 +++++++++++++- .../NewCalendarPage/UpcomingMeetingsCard.tsx | 77 +++++++++++++++++++ src/frontend/src/utils/calendar.utils.ts | 70 ++++++++++++++++- 3 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 55bd25492a..120058e2dc 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -19,7 +19,8 @@ import FilterModal from './FilterModal'; import { DateCalendar } from '@mui/x-date-pickers'; import { useCurrentUser } from '../../hooks/users.hooks'; import { useGetUsersTeams } from '../../hooks/teams.hooks'; -import { convertDayToInt } from '../../utils/calendar.utils'; +import { convertDayToInt, getEventsFlattened } from '../../utils/calendar.utils'; +import UpcomingMeetingsCard from './UpcomingMeetingsCard'; const NewCalendarPage = () => { const theme = useTheme(); @@ -76,6 +77,22 @@ const NewCalendarPage = () => { const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); + const [startPeriod] = useState(() => new Date()); + + const [endPeriod] = useState(() => { + const d = new Date(); + d.setDate(d.getDate() + 7); + d.setHours(23, 59, 59, 999); + return d; + }); + + const { data: upcomingEvents } = useFilterEvents({ + startPeriod, + endPeriod + }); + + const upcomingOccurences = upcomingEvents ? getEventsFlattened(upcomingEvents, startPeriod, endPeriod) : []; + const updateAdditionalTeamIds = (changed: boolean) => { setShowTeamEvents(changed); @@ -233,7 +250,13 @@ const NewCalendarPage = () => { - + {enumToArray(DAY_NAMES).map((day, index) => ( @@ -286,7 +309,10 @@ const NewCalendarPage = () => { { > More Filters + + + My Upcoming Meetings: + + + {upcomingOccurences && ( + + {upcomingOccurences?.map((event) => ( + + ))} + + )} diff --git a/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx b/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx new file mode 100644 index 0000000000..510a1ad6d6 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx @@ -0,0 +1,77 @@ +import { Card, Box, Typography, Stack } from '@mui/material'; +import BuildOutlinedIcon from '@mui/icons-material/BuildOutlined'; +import RoomOutlinedIcon from '@mui/icons-material/RoomOutlined'; +import GroupsOutlinedIcon from '@mui/icons-material/GroupsOutlined'; +import { Calendar, DayOfWeek, Event, EventType } from 'shared'; +import { getConvertedStart } from '../../utils/datetime.utils'; + +interface UpcomingMeetingProp { + calendars: Calendar[]; + event: Event; + eventTypes?: EventType[]; +} + +const dayOfWeek = DayOfWeek.MONDAY; + +const UpcomingMeetingsCard: React.FC = ({ event, calendars = [], eventTypes = [] }) => { + const convertedStartTime = getConvertedStart(event, dayOfWeek); + + const specificEventType = eventTypes?.find((eventType) => eventType.eventTypeId === event.eventTypeId); + const specificCalendar = calendars?.find((calendar) => + calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) + ); + + // optional and required members are combined and sorted by first name + const members = Array.from( + new Map([...event.requiredMembers, ...event.optionalMembers].map((u) => [u.userId, u])).values() + ).sort((a, b) => a.firstName.localeCompare(b.firstName)); + + return ( + + + + {/* Event Title */} + + + {event.title} + + + {/* Event Time */} + + {convertedStartTime} + + + + {/* Event Location */} + + {event.location ? event.location : 'N/A'} + + + {/* Event Members */} + + + + + {members.length > 0 ? members.map((u) => `${u.firstName} ${u.lastName}`).join(', ') : 'N/A'} + + + + + ); +}; + +export default UpcomingMeetingsCard; diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index c94ded949c..66e47d185c 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -1,4 +1,4 @@ -import { DayOfWeek } from 'shared'; +import { DayOfWeek, Event } from 'shared'; export const convertDayToInt = (day: DayOfWeek) => { switch (day) { @@ -20,3 +20,71 @@ export const convertDayToInt = (day: DayOfWeek) => { return -1; } }; + +// Get a list of dates for user viewing purposes (formatted to their timezone) +// Should be used when events need to be populated/displayed +export const getMeetingDates = (event: Event) => { + const times: Date[] = []; + event.scheduledTimes.forEach((schedule) => { + schedule.days.forEach((day) => { + const startTimeDate = new Date(schedule.initialDateScheduled); + const timezoneOffset = startTimeDate.getTimezoneOffset() * 60000; + + // get the initial date (adjusted to match UTC) + // this is done to ensure offset is properly calculated + const startDate = new Date(startTimeDate.getTime() + timezoneOffset); + + // Calculate offset based on the current day being checked + const offset = startDate.getDay() - convertDayToInt(day); + + // apply offset to get the true date of this specific event + startDate.setDate(startDate.getDate() - offset); + + let startTime: Date | undefined = undefined; + if (schedule.startTime) { + startTime = new Date(schedule.startTime); + } + + // Note : schedule.startTime likely gets converted to the users timezone by default + // set the hour and minutes + startDate.setHours(startTime?.getHours() ?? 0); + startDate.setMinutes(startTime?.getMinutes() ?? 0); + + // adjust for the users time + const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); + + times.push(startDateAdjusted); + + // add additional events for each recurrence on this day + for (let i = 1; i <= schedule.recurrenceNumber; i++) { + const nextDate = new Date(startDateAdjusted); + nextDate.setDate(nextDate.getDate() + 7 * i); + times.push(nextDate); + } + }); + }); + + return times; +}; + +// Returns a flat list of event occurrences within a given period +export const getEventsFlattened = (events: Event[], startPeriod: Date, endPeriod: Date): Event[] => { + const occurrences: { event: Event; date: Date }[] = []; + + events.forEach((event) => { + const eventDates = getMeetingDates(event); + + eventDates.forEach((date) => { + if (date >= startPeriod && date <= endPeriod) { + console.log(date); + occurrences.push({ event, date }); + } + }); + }); + + // Sort by date + occurrences.sort((a, b) => a.date.getTime() - b.date.getTime()); + + // Return only the events, possibly repeated for multiple occurrences + return occurrences.map(({ event }) => event); +}; From e6fe843a0f191f87288eacf590556b7ce3b77072 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 15 Dec 2025 22:03:58 -0500 Subject: [PATCH 375/477] #3400 scheduling conflicts implementation --- .../src/controllers/calendar.controllers.ts | 9 ++++ src/backend/src/routes/calendar.routes.ts | 2 + src/backend/src/services/calendar.services.ts | 21 ++++++++ src/frontend/src/apis/calendar.api.ts | 6 +++ src/frontend/src/hooks/calendar.hooks.ts | 10 +++- .../pages/NewCalendarPage/NewCalendarPage.tsx | 5 +- .../SchedulingConflictsWarning.tsx | 51 +++++++++++++++++++ src/frontend/src/utils/urls.ts | 2 + 8 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 30b4528a90..613131b182 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -471,4 +471,13 @@ export default class CalendarController { next(error); } } + + static async getPendingConflicts(req: Request, res: Response, next: NextFunction) { + try { + const conflicts = await CalendarService.getPendingConflicts(req.organization); + res.status(200).json(conflicts); + } catch (error: unknown) { + next(error); + } + } } diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 77b2baee6c..cebb44acc8 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -159,6 +159,8 @@ calendarRouter.get('/event/:eventId', CalendarController.getSingleEvent); calendarRouter.get('/events', CalendarController.getAllEvents); +calendarRouter.get('/conflicts/pending', CalendarController.getPendingConflicts); + calendarRouter.get('/event-types', CalendarController.getAllEventTypes); calendarRouter.post('/machinery/create', nonEmptyString(body('name')), validateInputs, CalendarController.createMachinery); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index dbad8f6df8..db89369b1e 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2330,4 +2330,25 @@ export default class CalendarService { }); return eventTypes.map(eventTypeTransformer); } + + /** + * Gets all events with pending scheduling conflicts + * @param organization the organization the user is currently in + * @returns All events that have scheduling conflicts requiring a review + */ + static async getPendingConflicts(organization: Organization): Promise { + const events = await prisma.event.findMany({ + where: { + dateDeleted: null, + approved: Conflict_Status.PENDING, + eventType: { + organizationId: organization.organizationId + } + }, + ...getEventQueryArgs(organization.organizationId), + orderBy: { dateCreated: 'desc' } + }); + + return events.map(eventTransformer); + } } diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 5d7c7284d7..7a0445af0e 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -147,6 +147,12 @@ export const getAllEvents = () => { }); }; +export const getPendingConflicts = () => { + return axios.get(apiUrls.calendarPendingConflicts(), { + transformResponse: (data) => JSON.parse(data).map(eventTransformer) + }); +}; + export const deleteEvent = async (id: string) => { return axios.delete(apiUrls.calendarDeleteEvent(id)); }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index d94e2f0a30..b524ae93d1 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -33,7 +33,8 @@ import { deleteEvent, setEventStatus, getAllEventTypes, - postFilterEvents + postFilterEvents, + getPendingConflicts } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; @@ -346,3 +347,10 @@ export const useSetEventStatus = (id: string) => { } ); }; + +export const usePendingConflicts = () => { + return useQuery(['conflicts', 'pending'], async () => { + const { data } = await getPendingConflicts(); + return data; + }); +}; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 55bd25492a..e35656953d 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -20,6 +20,7 @@ import { DateCalendar } from '@mui/x-date-pickers'; import { useCurrentUser } from '../../hooks/users.hooks'; import { useGetUsersTeams } from '../../hooks/teams.hooks'; import { convertDayToInt } from '../../utils/calendar.utils'; +import SchedulingConflictsWarning from './SchedulingConflictsWarning'; const NewCalendarPage = () => { const theme = useTheme(); @@ -322,11 +323,13 @@ const NewCalendarPage = () => { '&:hover': { borderColor: 'white', backgroundColor: 'rgba(255, 255, 255, 0.1)' - } + }, + mb: 2 }} > More Filters + diff --git a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx new file mode 100644 index 0000000000..96035efef1 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx @@ -0,0 +1,51 @@ +import { Box, Stack, Typography } from '@mui/material'; +import WarningIcon from '@mui/icons-material/Warning'; +import { usePendingConflicts } from '../../hooks/calendar.hooks'; +import { useHistory } from 'react-router-dom'; + +const SchedulingConflictsWarning: React.FC = () => { + const { data: conflicts, isLoading } = usePendingConflicts(); + const history = useHistory(); + + // Don't show if loading or no conflicts + if (isLoading || !conflicts || conflicts.length === 0) { + return null; + } + + return ( + + + Scheduling Conflicts: + + history.push('/calendar/reviews')} + sx={{ + bgcolor: 'transparent', + border: '2px solid #FF4444', + borderRadius: 1.5, + padding: 2, + cursor: 'pointer', + transition: 'all 0.2s', + '&:hover': { + borderColor: '#FF6666', + transform: 'translateY(-1px)' + } + }} + > + + + + + Requires Action + + + Click to Resolve + + + + + + ); +}; + +export default SchedulingConflictsWarning; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index df5afd78da..fd30e28a40 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -442,6 +442,7 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; const calendarEvents = () => `${calendar()}/events`; +const calendarPendingConflicts = () => `${calendar()}/conflicts/pending`; const calendarEventTypes = () => `${calendar()}/event-types`; const calendarCreateShop = () => `${calendar()}/shop/create`; const calendarFilterEvents = () => `${calendar()}/events/filter`; @@ -778,6 +779,7 @@ export const apiUrls = { calendarEventMarkUserConfirmed, calendarGetSingleEvent, calendarEvents, + calendarPendingConflicts, calendarDeleteEvent, calendarEventSetStatus, calendarDeleteShop, From e2ccfe7c222a6b51d51eba34d5098ad356cf7822 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Mon, 15 Dec 2025 22:08:48 -0500 Subject: [PATCH 376/477] #3816 added handleClose, no frozenRef --- .../NewCalendarPage/Components/EventModal.tsx | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx index be68f13398..1a1f2fd4b0 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx @@ -26,7 +26,8 @@ import { wbsNamePipe, wbsNumComparator, EventType, - isHead + isHead, + MAX_FILE_SIZE } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import { useAllUsers, useCurrentUser } from '../../../hooks/users.hooks'; @@ -97,8 +98,6 @@ export interface EventRoutePayload { }>; } -const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB - const schema = yup.object().shape({ title: yup.string().required('Title is required'), eventTypeId: yup.string().required('Event Type is required'), @@ -224,8 +223,6 @@ const EventModal: React.FC = ({ defaultValues: defaultFormData }); - const frozenValuesRef = React.useRef>(defaultFormData); - const shopIds = watch('shopIds'); const selectedEventTypeId = watch('eventTypeId'); const documentFiles = watch('documentFiles'); @@ -238,7 +235,7 @@ const EventModal: React.FC = ({ const allMachineryOptions = machinery.map((m) => ({ id: m.machineryId, label: m.name })); - if (shops.length === 0) { + if (shopIds.length === 0) { return allMachineryOptions; } @@ -252,7 +249,6 @@ const EventModal: React.FC = ({ useEffect(() => { if (open) { - frozenValuesRef.current = defaultFormData; reset(defaultFormData); if (initialValues?.requiredMemberIds && users) { @@ -275,11 +271,6 @@ const EventModal: React.FC = ({ .map((t) => ({ id: t.teamId, label: t.teamName })); setSelectedTeams(teamOptions); } - } else { - reset(defaultFormData); - setRequiredMembers([]); - setOptionalMembers([]); - setSelectedTeams([]); } }, [open, defaultFormData, reset, initialValues, users, teams]); @@ -288,9 +279,17 @@ const EventModal: React.FC = ({ [allowedEventTypes, selectedEventTypeId] ); - const isEditMode = !!frozenValuesRef.current.eventTypeId; + const isEditMode = !!initialValues?.eventTypeId; const computedTitle = isEditMode ? 'Edit Event' : 'Add Event'; + const handleClose = () => { + reset(defaultFormData); + setRequiredMembers([]); + setOptionalMembers([]); + setSelectedTeams([]); + onClose(); + }; + const handleDocumentRemove = (index: number) => { const currentFiles = watch('documentFiles'); setValue( @@ -425,11 +424,7 @@ const EventModal: React.FC = ({ }; await onSubmit(submitData); - onClose(); - reset(defaultFormData); - setRequiredMembers([]); - setOptionalMembers([]); - setSelectedTeams([]); + handleClose(); } catch (e: unknown) { if (e instanceof Error) toast.error(e.message); } @@ -474,10 +469,7 @@ const EventModal: React.FC = ({ return ( { - onClose(); - reset(defaultFormData); - }} + onHide={handleClose} title={computedTitle} reset={() => reset(defaultFormData)} handleUseFormSubmit={handleSubmit} From 743b968e83da2f317685e52e53ad250fa97adf13 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 15 Dec 2025 22:14:23 -0500 Subject: [PATCH 377/477] #3819 minor component adjustment --- .../src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx index 96035efef1..5d00ad97d5 100644 --- a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx +++ b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx @@ -3,11 +3,11 @@ import WarningIcon from '@mui/icons-material/Warning'; import { usePendingConflicts } from '../../hooks/calendar.hooks'; import { useHistory } from 'react-router-dom'; +//Component for main new calendar page for scheduling conflicts const SchedulingConflictsWarning: React.FC = () => { const { data: conflicts, isLoading } = usePendingConflicts(); const history = useHistory(); - // Don't show if loading or no conflicts if (isLoading || !conflicts || conflicts.length === 0) { return null; } From 0ba7595e6c915362bd45b5b058f77aa34dbf732b Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 15 Dec 2025 22:28:05 -0500 Subject: [PATCH 378/477] #3798 small changes --- src/frontend/src/pages/CalendarPage/CalendarPage.tsx | 1 - .../src/pages/NewCalendarPage/CalendarDayCard.tsx | 10 ++++------ .../src/pages/NewCalendarPage/EventClickPopup.tsx | 6 +++--- .../src/pages/NewCalendarPage/NewCalendarPage.tsx | 1 - 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx index 9d473d4c63..e9b0bba4eb 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx @@ -190,7 +190,6 @@ const CalendarPage = () => { datePipe(new Date(cardDate.getTime() - cardDate.getTimezoneOffset() * -60000)) ) ?? [] } - teamTypes={allTeamTypes} /> diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index 2092234aab..5b5f491386 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -47,7 +47,6 @@ export const getStatusIcon = (status: string, isLarge?: boolean) => { interface CalendarDayCardProps { cardDate: Date; events: Event[]; - teamTypes: TeamType[]; eventTypes?: EventType[]; calendars?: Calendar[]; dayOfWeek?: DayOfWeek; @@ -56,7 +55,6 @@ interface CalendarDayCardProps { const CalendarDayCard: React.FC = ({ cardDate, events, - teamTypes: _teamTypes, eventTypes = [], calendars = [], dayOfWeek = DayOfWeek.MONDAY @@ -68,8 +66,8 @@ const CalendarDayCard: React.FC = ({ const isCurrentDay = cardDate.toDateString() === today; const isFutureDay = cardDate >= new Date(); - const [clickedEvent, setClickedEvent] = useState(null); - const [anchorPosition, setAnchorPosition] = useState<{ top: number; left: number } | null>(null); + const [clickedEvent, setClickedEvent] = useState(); + const [anchorPosition, setAnchorPosition] = useState<{ top: number; left: number }>(); const handleOpenClickPopup = (event: Event) => { setClickedEvent(event); @@ -84,8 +82,8 @@ const CalendarDayCard: React.FC = ({ }; const handleCloseClickPopup = () => { - setClickedEvent(null); - setAnchorPosition(null); + setClickedEvent(undefined); + setAnchorPosition(undefined); }; const DayCardTitle = () => ( diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 5e294064e6..18deafb82a 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -305,8 +305,8 @@ const EventClickContent: React.FC = ({ event, eventTypes }; export interface EventClickPopupProps { - clickedEvent: Event | null; - anchorPosition: { top: number; left: number } | null; + clickedEvent?: Event; + anchorPosition?: { top: number; left: number }; onClose: () => void; eventTypes: EventType[]; calendars: Calendar[]; @@ -325,7 +325,7 @@ export const EventClickPopup: React.FC = ({ { datePipe(new Date(cardDate.getTime() + cardDate.getTimezoneOffset() * 60000)) ) ?? [] } - teamTypes={allTeamTypes} eventTypes={allEventTypes ?? []} calendars={allCalendars ?? []} dayOfWeek={ From 9ae489055225e9d149533e72c7a9212311a34d4d Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 15 Dec 2025 22:29:09 -0500 Subject: [PATCH 379/477] #3798 comments fix --- src/frontend/src/pages/CalendarPage/CalendarPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx index e9b0bba4eb..fcc054498b 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx @@ -77,7 +77,7 @@ const CalendarPage = () => { const firstDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 1); const lastDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 0); - const paddingStart = firstDayOfMonth.getDay(); // 0-6 (Sun-Sat) + const paddingStart = firstDayOfMonth.getDay(); const totalDays = lastDayOfMonth.getDate(); const totalCells = Math.ceil((paddingStart + totalDays) / 7) * 7; From 7d829bd027fee1ef5be7207b712577900dec51c8 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 15 Dec 2025 22:30:58 -0500 Subject: [PATCH 380/477] #3798 prettier fix --- src/frontend/src/pages/CalendarPage/CalendarPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx index fcc054498b..3df901c937 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx @@ -77,7 +77,7 @@ const CalendarPage = () => { const firstDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 1); const lastDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 0); - const paddingStart = firstDayOfMonth.getDay(); + const paddingStart = firstDayOfMonth.getDay(); const totalDays = lastDayOfMonth.getDate(); const totalCells = Math.ceil((paddingStart + totalDays) / 7) * 7; From e6a7836d43f3401283d6afd5873a405131fb5ce0 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Dec 2025 22:31:19 -0500 Subject: [PATCH 381/477] new filtering ideas --- src/backend/src/routes/calendar.routes.ts | 18 ++++++++++---- src/backend/src/services/calendar.services.ts | 24 +++---------------- src/backend/src/utils/validation.utils.ts | 16 ++++++++++++- .../src/pages/NewCalendarPage/CalendarTab.tsx | 4 ++-- .../pages/NewCalendarPage/NewCalendarPage.tsx | 4 ++-- src/shared/src/types/calendar-types.ts | 3 +-- 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 404e8c8835..1d7d77e2a6 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,6 +1,14 @@ import express from 'express'; import { body, param } from 'express-validator'; -import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek, isEventStatus } from '../utils/validation.utils'; +import { + intMinZero, + isDate, + nonEmptyString, + validateInputs, + isDayOfWeek, + isEventStatus, + isConflictStatus +} from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; const calendarRouter = express.Router(); @@ -229,10 +237,10 @@ calendarRouter.post( body('eventTypeIds.*').optional().isString(), body('eventIds').isArray().optional(), body('eventIds.*').isString().optional(), - body('approvalIdsIds').isArray().optional(), - body('approvalIdsIds.*').isString().optional(), - body('approvedEvents').isBoolean().optional(), - body('getPending').isBoolean().optional(), + body('approvalIds').isArray().optional(), + body('approvalIds.*').isString().optional(), + body('statuses').isArray().optional(), + isConflictStatus(body('statuses.*')), isDate(body('startPeriod')), isDate(body('endPeriod')), validateInputs, diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 074dd68a10..42f34d1a4e 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2070,18 +2070,7 @@ export default class CalendarService { * @throws NotFoundException If the given event type Ids, member IDs, team IDs, or event IDs are not found. */ static async getFilteredEvents(filters: FilterArgs, organization: Organization): Promise { - const { - memberIds, - teamIds, - calendarIds, - eventTypeIds, - eventIds, - approvalIds, - approvedEvents, - getPending, - startPeriod, - endPeriod - } = filters; + const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvalIds, startPeriod, endPeriod, statuses } = filters; // validate memberIds if (memberIds?.length) { @@ -2194,15 +2183,8 @@ export default class CalendarService { eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, approvalRequiredFromUserId: approvalIds?.length ? { in: approvalIds } : undefined, - AND: [ - memberOrTeamFilter.length ? { OR: memberOrTeamFilter } : {}, - approvedEvents - ? { - OR: [{ approved: 'APPROVED' }, { approved: 'NO_CONFLICT' }] - } - : {} - ], - approved: getPending ? 'PENDING' : undefined, + ...memberOrTeamFilter, + approved: statuses?.length ? { in: statuses } : undefined scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...fromCalendar }, diff --git a/src/backend/src/utils/validation.utils.ts b/src/backend/src/utils/validation.utils.ts index a8d090c06c..8cef80feb1 100644 --- a/src/backend/src/utils/validation.utils.ts +++ b/src/backend/src/utils/validation.utils.ts @@ -1,7 +1,15 @@ import { DayOfWeek, Event_Status, Graph_Display_Type, Graph_Type, Measure, Special_Permission } from '@prisma/client'; import { Request, Response } from 'express'; import { body, query, ValidationChain, validationResult } from 'express-validator'; -import { MaterialStatus, TaskPriority, TaskStatus, WorkPackageStage, RoleEnum, WbsElementStatus } from 'shared'; +import { + MaterialStatus, + TaskPriority, + TaskStatus, + WorkPackageStage, + RoleEnum, + WbsElementStatus, + ConflictStatus +} from 'shared'; export const intMinZero = (validationObject: ValidationChain): ValidationChain => { return validationObject.isInt({ min: 0 }).not().isString(); @@ -173,6 +181,12 @@ export const isDayOfWeek = (validationObject: ValidationChain): ValidationChain ]); }; +export const isConflictStatus = (validationObject: ValidationChain): ValidationChain => { + return validationObject + .isString() + .isIn([ConflictStatus.APPROVED, ConflictStatus.PENDING, ConflictStatus.DENIED, ConflictStatus.NO_CONFLICT]); +}; + export const descriptionBulletsValidators = [ body('descriptionBullets').isArray(), nonEmptyString(body('descriptionBullets.*.detail')), diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index de4dbc8359..f2855638a0 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -6,7 +6,7 @@ import { Box } from '@mui/material'; import FullPageTabs from '../../components/FullPageTabs'; import { useState } from 'react'; import { useCurrentUser } from '../../hooks/users.hooks'; -import { isHead, isLead } from 'shared'; +import { ConflictStatus, isHead, isLead } from 'shared'; import { useFilterEvents } from '../../hooks/calendar.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; @@ -39,7 +39,7 @@ const CalendarTab: React.FC = () => { error: reviewEventsError } = useFilterEvents({ approvalIds: [user.userId], - getPending: canViewReviews, + statuses: [ConflictStatus.PENDING], startPeriod: new Date(0), endPeriod: new Date(2099, 11, 31) // Adjust as needed }); diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index d00f779a34..9af2531299 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -5,7 +5,7 @@ import { useState } from 'react'; import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; import PageLayout from '../../components/PageLayout'; -import { DayOfWeek, Event } from 'shared'; +import { ConflictStatus, DayOfWeek, Event } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; @@ -56,7 +56,7 @@ const NewCalendarPage = () => { endPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15), memberIds: memberIds.concat(additionalMemberIds), teamIds: teamIds.concat(additionalTeamIds), - approvedEvents: true + statuses: [ConflictStatus.APPROVED, ConflictStatus.NO_CONFLICT] }); const { diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 05f9fd5313..ced8b85d8b 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -90,8 +90,7 @@ export interface FilterArgs { calendarIds?: string[]; eventTypeIds?: string[]; eventIds?: string[]; - approvedEvents?: boolean; - getPending?: boolean; + statuses?: ConflictStatus[]; approvalIds?: string[]; startPeriod: Date; endPeriod: Date; From 250b4c7d48a5f0f8546c2532635f411950e07051 Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 15 Dec 2025 22:33:25 -0500 Subject: [PATCH 382/477] #3798 removing team-type import --- src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index 5b5f491386..ca05368b9e 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { Box, Card, CardContent, Grid, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; -import { Calendar, DayOfWeek, Event, EventType, TeamType } from 'shared'; +import { Calendar, DayOfWeek, Event, EventType} from 'shared'; import ConstructionIcon from '@mui/icons-material/Construction'; import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices'; From 3f29b252052dcf36045424db4ae306a4f3fa4280 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Dec 2025 22:34:58 -0500 Subject: [PATCH 383/477] oops --- src/backend/src/services/calendar.services.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 42f34d1a4e..28ab58da52 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2070,7 +2070,8 @@ export default class CalendarService { * @throws NotFoundException If the given event type Ids, member IDs, team IDs, or event IDs are not found. */ static async getFilteredEvents(filters: FilterArgs, organization: Organization): Promise { - const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvalIds, startPeriod, endPeriod, statuses } = filters; + const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvalIds, startPeriod, endPeriod, statuses } = + filters; // validate memberIds if (memberIds?.length) { @@ -2184,7 +2185,7 @@ export default class CalendarService { eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, approvalRequiredFromUserId: approvalIds?.length ? { in: approvalIds } : undefined, ...memberOrTeamFilter, - approved: statuses?.length ? { in: statuses } : undefined + approved: statuses?.length ? { in: statuses } : undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...fromCalendar }, From 685e8fa85f12b93b6c9e5c2fcda3aaa001fe4c7f Mon Sep 17 00:00:00 2001 From: "sayegh.st@northeastern.edu" Date: Mon, 15 Dec 2025 22:36:50 -0500 Subject: [PATCH 384/477] #3798 another prettier fix --- src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index ca05368b9e..6177693976 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { Box, Card, CardContent, Grid, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; -import { Calendar, DayOfWeek, Event, EventType} from 'shared'; +import { Calendar, DayOfWeek, Event, EventType } from 'shared'; import ConstructionIcon from '@mui/icons-material/Construction'; import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices'; From 8f3fb736abfd47523c3e91d899a444c8c40bf286 Mon Sep 17 00:00:00 2001 From: Saul M <114538686+saulmanz@users.noreply.github.com> Date: Mon, 15 Dec 2025 21:37:22 -0600 Subject: [PATCH 385/477] #3703 Added suggestions --- .../src/pages/NewCalendarPage/NewCalendarPage.tsx | 4 +++- .../pages/NewCalendarPage/UpcomingMeetingsCard.tsx | 2 +- src/frontend/src/utils/calendar.utils.ts | 13 ++++--------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 120058e2dc..b22b30c4bb 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -88,7 +88,9 @@ const NewCalendarPage = () => { const { data: upcomingEvents } = useFilterEvents({ startPeriod, - endPeriod + endPeriod, + memberIds: memberIds.concat(additionalMemberIds), + teamIds: teamIds.concat(additionalTeamIds) }); const upcomingOccurences = upcomingEvents ? getEventsFlattened(upcomingEvents, startPeriod, endPeriod) : []; diff --git a/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx b/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx index 510a1ad6d6..c75db6c567 100644 --- a/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx @@ -52,7 +52,7 @@ const UpcomingMeetingsCard: React.FC = ({ event, calendars {/* Event Location */} - {event.location ? event.location : 'N/A'} + {event.location ? event.location : event.zoomLink ? event.zoomLink : 'N/A'} {/* Event Members */} diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 66e47d185c..08759d5044 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -1,4 +1,5 @@ import { DayOfWeek, Event } from 'shared'; +import { filterEventTransformer } from '../apis/transformers/calendar.transformer'; export const convertDayToInt = (day: DayOfWeek) => { switch (day) { @@ -40,15 +41,10 @@ export const getMeetingDates = (event: Event) => { // apply offset to get the true date of this specific event startDate.setDate(startDate.getDate() - offset); - let startTime: Date | undefined = undefined; - if (schedule.startTime) { - startTime = new Date(schedule.startTime); - } - // Note : schedule.startTime likely gets converted to the users timezone by default // set the hour and minutes - startDate.setHours(startTime?.getHours() ?? 0); - startDate.setMinutes(startTime?.getMinutes() ?? 0); + startDate.setHours(schedule.startTime?.getHours() ?? 0); + startDate.setMinutes(schedule.startTime?.getMinutes() ?? 0); // adjust for the users time const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); @@ -72,11 +68,10 @@ export const getEventsFlattened = (events: Event[], startPeriod: Date, endPeriod const occurrences: { event: Event; date: Date }[] = []; events.forEach((event) => { - const eventDates = getMeetingDates(event); + const eventDates = getMeetingDates(filterEventTransformer(event)); eventDates.forEach((date) => { if (date >= startPeriod && date <= endPeriod) { - console.log(date); occurrences.push({ event, date }); } }); From d1d2b3817c28932a8a5f54c840821d6d4fee5021 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Dec 2025 22:57:47 -0500 Subject: [PATCH 386/477] OR --- src/backend/src/services/calendar.services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 28ab58da52..2efd55d7ec 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2184,7 +2184,7 @@ export default class CalendarService { eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, approvalRequiredFromUserId: approvalIds?.length ? { in: approvalIds } : undefined, - ...memberOrTeamFilter, + OR: memberOrTeamFilter.length > 0 ? memberOrTeamFilter : undefined, approved: statuses?.length ? { in: statuses } : undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...fromCalendar From 71f8f3bdad3352a0eb46b25824ff42e71892cbd1 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 15 Dec 2025 22:59:39 -0500 Subject: [PATCH 387/477] #3819 used existing filteredevents endpoint for getting conflict statuses --- .../src/controllers/calendar.controllers.ts | 9 ------ src/backend/src/routes/calendar.routes.ts | 16 ++++++++-- src/backend/src/services/calendar.services.ts | 31 +++---------------- src/backend/src/utils/validation.utils.ts | 16 +++++++++- src/frontend/src/apis/calendar.api.ts | 6 ---- src/frontend/src/hooks/calendar.hooks.ts | 21 ++++++++++--- src/frontend/src/utils/urls.ts | 2 -- src/shared/src/types/calendar-types.ts | 3 +- 8 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 613131b182..30b4528a90 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -471,13 +471,4 @@ export default class CalendarController { next(error); } } - - static async getPendingConflicts(req: Request, res: Response, next: NextFunction) { - try { - const conflicts = await CalendarService.getPendingConflicts(req.organization); - res.status(200).json(conflicts); - } catch (error: unknown) { - next(error); - } - } } diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index cebb44acc8..aec0ee6694 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -1,6 +1,14 @@ import express from 'express'; import { body, param } from 'express-validator'; -import { intMinZero, isDate, nonEmptyString, validateInputs, isDayOfWeek, isEventStatus } from '../utils/validation.utils'; +import { + intMinZero, + isDate, + nonEmptyString, + validateInputs, + isDayOfWeek, + isEventStatus, + isConflictStatus +} from '../utils/validation.utils'; import CalendarController from '../controllers/calendar.controllers'; const calendarRouter = express.Router(); @@ -159,8 +167,6 @@ calendarRouter.get('/event/:eventId', CalendarController.getSingleEvent); calendarRouter.get('/events', CalendarController.getAllEvents); -calendarRouter.get('/conflicts/pending', CalendarController.getPendingConflicts); - calendarRouter.get('/event-types', CalendarController.getAllEventTypes); calendarRouter.post('/machinery/create', nonEmptyString(body('name')), validateInputs, CalendarController.createMachinery); @@ -232,6 +238,10 @@ calendarRouter.post( body('eventIds').isArray().optional(), body('eventIds.*').isString().optional(), body('approvedEvents').isBoolean().optional(), + body('approvalIds').isArray().optional(), + body('approvalIds.*').isString().optional(), + body('statuses').isArray().optional(), + isConflictStatus(body('statuses.*')), isDate(body('startPeriod')), isDate(body('endPeriod')), validateInputs, diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index db89369b1e..2efd55d7ec 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2070,7 +2070,8 @@ export default class CalendarService { * @throws NotFoundException If the given event type Ids, member IDs, team IDs, or event IDs are not found. */ static async getFilteredEvents(filters: FilterArgs, organization: Organization): Promise { - const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvedEvents, startPeriod, endPeriod } = filters; + const { memberIds, teamIds, calendarIds, eventTypeIds, eventIds, approvalIds, startPeriod, endPeriod, statuses } = + filters; // validate memberIds if (memberIds?.length) { @@ -2182,10 +2183,9 @@ export default class CalendarService { dateDeleted: null, eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, - AND: [ - memberOrTeamFilter.length ? { OR: memberOrTeamFilter } : {}, - approvedEvents ? { OR: [{ approved: 'APPROVED' }, { approved: 'NO_CONFLICT' }] } : {} - ], + approvalRequiredFromUserId: approvalIds?.length ? { in: approvalIds } : undefined, + OR: memberOrTeamFilter.length > 0 ? memberOrTeamFilter : undefined, + approved: statuses?.length ? { in: statuses } : undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...fromCalendar }, @@ -2330,25 +2330,4 @@ export default class CalendarService { }); return eventTypes.map(eventTypeTransformer); } - - /** - * Gets all events with pending scheduling conflicts - * @param organization the organization the user is currently in - * @returns All events that have scheduling conflicts requiring a review - */ - static async getPendingConflicts(organization: Organization): Promise { - const events = await prisma.event.findMany({ - where: { - dateDeleted: null, - approved: Conflict_Status.PENDING, - eventType: { - organizationId: organization.organizationId - } - }, - ...getEventQueryArgs(organization.organizationId), - orderBy: { dateCreated: 'desc' } - }); - - return events.map(eventTransformer); - } } diff --git a/src/backend/src/utils/validation.utils.ts b/src/backend/src/utils/validation.utils.ts index a8d090c06c..8cef80feb1 100644 --- a/src/backend/src/utils/validation.utils.ts +++ b/src/backend/src/utils/validation.utils.ts @@ -1,7 +1,15 @@ import { DayOfWeek, Event_Status, Graph_Display_Type, Graph_Type, Measure, Special_Permission } from '@prisma/client'; import { Request, Response } from 'express'; import { body, query, ValidationChain, validationResult } from 'express-validator'; -import { MaterialStatus, TaskPriority, TaskStatus, WorkPackageStage, RoleEnum, WbsElementStatus } from 'shared'; +import { + MaterialStatus, + TaskPriority, + TaskStatus, + WorkPackageStage, + RoleEnum, + WbsElementStatus, + ConflictStatus +} from 'shared'; export const intMinZero = (validationObject: ValidationChain): ValidationChain => { return validationObject.isInt({ min: 0 }).not().isString(); @@ -173,6 +181,12 @@ export const isDayOfWeek = (validationObject: ValidationChain): ValidationChain ]); }; +export const isConflictStatus = (validationObject: ValidationChain): ValidationChain => { + return validationObject + .isString() + .isIn([ConflictStatus.APPROVED, ConflictStatus.PENDING, ConflictStatus.DENIED, ConflictStatus.NO_CONFLICT]); +}; + export const descriptionBulletsValidators = [ body('descriptionBullets').isArray(), nonEmptyString(body('descriptionBullets.*.detail')), diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 7a0445af0e..5d7c7284d7 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -147,12 +147,6 @@ export const getAllEvents = () => { }); }; -export const getPendingConflicts = () => { - return axios.get(apiUrls.calendarPendingConflicts(), { - transformResponse: (data) => JSON.parse(data).map(eventTransformer) - }); -}; - export const deleteEvent = async (id: string) => { return axios.delete(apiUrls.calendarDeleteEvent(id)); }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index b524ae93d1..718bf8a856 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -8,7 +8,8 @@ import { Event, EventStatus, EventType, - FilterArgs + FilterArgs, + ConflictStatus } from 'shared'; import { getAllShops, @@ -33,8 +34,7 @@ import { deleteEvent, setEventStatus, getAllEventTypes, - postFilterEvents, - getPendingConflicts + postFilterEvents } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; @@ -350,7 +350,20 @@ export const useSetEventStatus = (id: string) => { export const usePendingConflicts = () => { return useQuery(['conflicts', 'pending'], async () => { - const { data } = await getPendingConflicts(); + // Use a wide date range to catch all pending conflicts + const startPeriod = new Date(); + startPeriod.setFullYear(startPeriod.getFullYear() - 1); + + const endPeriod = new Date(); + endPeriod.setFullYear(endPeriod.getFullYear() + 5); + + const filterArgs: FilterArgs = { + statuses: [ConflictStatus.PENDING], + startPeriod, + endPeriod + }; + + const { data } = await postFilterEvents(filterArgs); return data; }); }; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index fd30e28a40..df5afd78da 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -442,7 +442,6 @@ const retrospectiveBudgets = () => `${API_URL}/retrospective/budgets`; const calendar = () => `${API_URL}/calendar`; const calendarShops = () => `${calendar()}/shops`; const calendarEvents = () => `${calendar()}/events`; -const calendarPendingConflicts = () => `${calendar()}/conflicts/pending`; const calendarEventTypes = () => `${calendar()}/event-types`; const calendarCreateShop = () => `${calendar()}/shop/create`; const calendarFilterEvents = () => `${calendar()}/events/filter`; @@ -779,7 +778,6 @@ export const apiUrls = { calendarEventMarkUserConfirmed, calendarGetSingleEvent, calendarEvents, - calendarPendingConflicts, calendarDeleteEvent, calendarEventSetStatus, calendarDeleteShop, diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 638ce9e863..ced8b85d8b 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -90,7 +90,8 @@ export interface FilterArgs { calendarIds?: string[]; eventTypeIds?: string[]; eventIds?: string[]; - approvedEvents?: boolean; + statuses?: ConflictStatus[]; + approvalIds?: string[]; startPeriod: Date; endPeriod: Date; } From eabcab5c436ca597d17bdbefbc237f24c280c6af Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Mon, 15 Dec 2025 23:10:14 -0500 Subject: [PATCH 388/477] #3819 Utilized existing hook instead of making new custom hook for pending conflicts --- src/frontend/src/hooks/calendar.hooks.ts | 23 +------------------ .../SchedulingConflictsWarning.tsx | 18 +++++++++++++-- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 718bf8a856..d94e2f0a30 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -8,8 +8,7 @@ import { Event, EventStatus, EventType, - FilterArgs, - ConflictStatus + FilterArgs } from 'shared'; import { getAllShops, @@ -347,23 +346,3 @@ export const useSetEventStatus = (id: string) => { } ); }; - -export const usePendingConflicts = () => { - return useQuery(['conflicts', 'pending'], async () => { - // Use a wide date range to catch all pending conflicts - const startPeriod = new Date(); - startPeriod.setFullYear(startPeriod.getFullYear() - 1); - - const endPeriod = new Date(); - endPeriod.setFullYear(endPeriod.getFullYear() + 5); - - const filterArgs: FilterArgs = { - statuses: [ConflictStatus.PENDING], - startPeriod, - endPeriod - }; - - const { data } = await postFilterEvents(filterArgs); - return data; - }); -}; diff --git a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx index 5d00ad97d5..acf421b630 100644 --- a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx +++ b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx @@ -1,13 +1,27 @@ import { Box, Stack, Typography } from '@mui/material'; import WarningIcon from '@mui/icons-material/Warning'; -import { usePendingConflicts } from '../../hooks/calendar.hooks'; +import { useFilterEvents } from '../../hooks/calendar.hooks'; import { useHistory } from 'react-router-dom'; +import { ConflictStatus } from 'shared'; //Component for main new calendar page for scheduling conflicts const SchedulingConflictsWarning: React.FC = () => { - const { data: conflicts, isLoading } = usePendingConflicts(); const history = useHistory(); + // Filter for events with pending conflicts (set a range date for now 1 year back and 5 years forward + // since we might not be interested in all unresolved conflicts) + const startPeriod = new Date(); + startPeriod.setFullYear(startPeriod.getFullYear() - 1); + + const endPeriod = new Date(); + endPeriod.setFullYear(endPeriod.getFullYear() + 5); + + const { data: conflicts, isLoading } = useFilterEvents({ + statuses: [ConflictStatus.PENDING], + startPeriod, + endPeriod + }); + if (isLoading || !conflicts || conflicts.length === 0) { return null; } From 81be9ed4422431ef1c914b84b261394e0079a9e4 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 15 Dec 2025 23:25:43 -0500 Subject: [PATCH 389/477] minor filtering changes --- src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index f2855638a0..4fa812be06 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -38,8 +38,8 @@ const CalendarTab: React.FC = () => { isError: reviewEventsIsError, error: reviewEventsError } = useFilterEvents({ - approvalIds: [user.userId], - statuses: [ConflictStatus.PENDING], + approvalIds: canViewReviews ? [] : [user.userId], + statuses: canViewReviews ? [ConflictStatus.PENDING] : [], startPeriod: new Date(0), endPeriod: new Date(2099, 11, 31) // Adjust as needed }); From a2d17ec04fbd784bd08c815325759f4f63ea51f9 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Tue, 16 Dec 2025 13:40:11 -0500 Subject: [PATCH 390/477] #3819 Passed in the filters from new calendar to get correct conflcits --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 5 ++++- .../SchedulingConflictsWarning.tsx | 22 ++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index e35656953d..b578ef9c09 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -329,7 +329,10 @@ const NewCalendarPage = () => { > More Filters - + diff --git a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx index acf421b630..92062e9db9 100644 --- a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx +++ b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx @@ -3,13 +3,19 @@ import WarningIcon from '@mui/icons-material/Warning'; import { useFilterEvents } from '../../hooks/calendar.hooks'; import { useHistory } from 'react-router-dom'; import { ConflictStatus } from 'shared'; +import LoadingIndicator from '../../components/LoadingIndicator'; + +interface SchedulingConflictsWarningProps { + memberIds: string[]; + teamIds: string[]; +} //Component for main new calendar page for scheduling conflicts -const SchedulingConflictsWarning: React.FC = () => { +const SchedulingConflictsWarning: React.FC = ({ memberIds, teamIds }) => { const history = useHistory(); - // Filter for events with pending conflicts (set a range date for now 1 year back and 5 years forward - // since we might not be interested in all unresolved conflicts) + // Filter for events with pending conflicts using the same filters as the calendar + // Use a wide date range (1 year back, 5 years forward) to catch all relevant conflicts const startPeriod = new Date(); startPeriod.setFullYear(startPeriod.getFullYear() - 1); @@ -19,10 +25,16 @@ const SchedulingConflictsWarning: React.FC = () => { const { data: conflicts, isLoading } = useFilterEvents({ statuses: [ConflictStatus.PENDING], startPeriod, - endPeriod + endPeriod, + memberIds, + teamIds }); - if (isLoading || !conflicts || conflicts.length === 0) { + if (isLoading) { + return ; + } + + if (!conflicts || conflicts.length === 0) { return null; } From 193c5d717d7c9cdd1bebb9fb7f35cd5c4733d037 Mon Sep 17 00:00:00 2001 From: Saul M <114538686+saulmanz@users.noreply.github.com> Date: Tue, 16 Dec 2025 13:02:59 -0600 Subject: [PATCH 391/477] #3703 Now shows team and team types when no members are available --- .../pages/NewCalendarPage/UpcomingMeetingsCard.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx b/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx index c75db6c567..093c859044 100644 --- a/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/UpcomingMeetingsCard.tsx @@ -59,14 +59,12 @@ const UpcomingMeetingsCard: React.FC = ({ event, calendars - - {members.length > 0 ? members.map((u) => `${u.firstName} ${u.lastName}`).join(', ') : 'N/A'} + + {members.length > 0 + ? members.map((u) => `${u.firstName} ${u.lastName}`).join(', ') + : event.teams.length > 0 + ? event.teams.map((t) => t.teamName).join(', ') + : (event.teamType?.name ?? 'N/A')} From 269845b6580fdc4b38e773bf21bc1d07b490d8d6 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Tue, 16 Dec 2025 14:54:44 -0500 Subject: [PATCH 392/477] #3819 lil changes in prop passing --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 10 ++++-- .../SchedulingConflictsWarning.tsx | 34 +++++++++++++------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index b578ef9c09..0374db88f9 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -46,14 +46,18 @@ const NewCalendarPage = () => { const [additionalMemberIds, setAdditionalMemberIds] = useState([user.userId]); const [additionalTeamIds, setAdditionalTeamIds] = useState(teamList); + // Date range for filtering events (current month ±1 month) + const startPeriod = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, 15); + const endPeriod = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15); + const { isLoading, isError, error, data: allEvents } = useFilterEvents({ - startPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, 15), - endPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15), + startPeriod, + endPeriod, memberIds: memberIds.concat(additionalMemberIds), teamIds: teamIds.concat(additionalTeamIds) }); @@ -332,6 +336,8 @@ const NewCalendarPage = () => { diff --git a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx index 92062e9db9..f57212b3b5 100644 --- a/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx +++ b/src/frontend/src/pages/NewCalendarPage/SchedulingConflictsWarning.tsx @@ -4,25 +4,31 @@ import { useFilterEvents } from '../../hooks/calendar.hooks'; import { useHistory } from 'react-router-dom'; import { ConflictStatus } from 'shared'; import LoadingIndicator from '../../components/LoadingIndicator'; +import ErrorPage from '../ErrorPage'; interface SchedulingConflictsWarningProps { memberIds: string[]; teamIds: string[]; + startPeriod: Date; + endPeriod: Date; } //Component for main new calendar page for scheduling conflicts -const SchedulingConflictsWarning: React.FC = ({ memberIds, teamIds }) => { +const SchedulingConflictsWarning: React.FC = ({ + memberIds, + teamIds, + startPeriod, + endPeriod +}) => { const history = useHistory(); // Filter for events with pending conflicts using the same filters as the calendar - // Use a wide date range (1 year back, 5 years forward) to catch all relevant conflicts - const startPeriod = new Date(); - startPeriod.setFullYear(startPeriod.getFullYear() - 1); - - const endPeriod = new Date(); - endPeriod.setFullYear(endPeriod.getFullYear() + 5); - - const { data: conflicts, isLoading } = useFilterEvents({ + const { + data: conflicts, + isLoading, + isError, + error + } = useFilterEvents({ statuses: [ConflictStatus.PENDING], startPeriod, endPeriod, @@ -30,11 +36,17 @@ const SchedulingConflictsWarning: React.FC = ({ teamIds }); - if (isLoading) { + if (isLoading || !conflicts) { return ; } - if (!conflicts || conflicts.length === 0) { + // There are conflicts, but error fetching them + if (isError) { + return ; + } + + // If no conflicts, don't show the warning + if (conflicts.length === 0) { return null; } From 5916cecd71682d9c59ccde6e24d3996ceb239d09 Mon Sep 17 00:00:00 2001 From: Samuel Shrestha Date: Tue, 16 Dec 2025 19:29:48 -0500 Subject: [PATCH 393/477] requests part 2 done --- src/backend/src/services/calendar.services.ts | 23 ++++++----- .../pages/NewCalendarPage/NewCalendarPage.tsx | 40 +++++++++++-------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 39c06ee829..7d95c8141f 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2114,21 +2114,22 @@ export default class CalendarService { } // filters for selected calendars - const fromCalendar = calendarIds?.length - ? { - eventType: { - is: { - organizationId: organization.organizationId, - calendars: { - some: { - calendarId: { in: calendarIds }, - organizationId: organization.organizationId + const fromCalendar = + calendarIds !== undefined + ? { + eventType: { + is: { + organizationId: organization.organizationId, + calendars: { + some: { + calendarId: { in: calendarIds }, + organizationId: organization.organizationId + } } } } } - } - : undefined; + : undefined; // get event using filter args const events = await prisma.event.findMany({ diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 1fffe98f70..f42a223d4f 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -2,7 +2,7 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { Box, Grid, @@ -75,11 +75,20 @@ const NewCalendarPage = () => { const calendars = allCalendars ?? []; const [selectedCalendarIds, setSelectedCalendarIds] = useState([]); + const [didInitCalendarFilters, setDidInitCalendarFilters] = useState(false); const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); + useEffect(() => { + if (didInitCalendarFilters) return; + if (!calendars.length) return; + + setSelectedCalendarIds(calendars.map((c) => c.calendarId)); + setDidInitCalendarFilters(true); + }, [calendars, didInitCalendarFilters]); + const { isLoading, isError, @@ -90,7 +99,7 @@ const NewCalendarPage = () => { endPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15), memberIds: memberIds.concat(additionalMemberIds), teamIds: teamIds.concat(additionalTeamIds), - calendarIds: selectedCalendarIds.length ? selectedCalendarIds : undefined + calendarIds: selectedCalendarIds }); const toggleCalendar = (calendarId: string) => { @@ -122,6 +131,18 @@ const NewCalendarPage = () => { if (isLoading || !allEvents) return ; if (isError) return ; + if (!allTeamTypes || allTeamTypesLoading) return ; + if (allTeamTypesIsError) return ; + + if (!allEventTypes || allEventTypesLoading) return ; + if (allEventTypesIsError) return ; + + if (!allCalendars || allCalendarsLoading) return ; + if (allCalendarsIsError) return ; + + if (!allTeams || allTeamsLoading) return ; + if (allTeamsIsError) return ; + // Sort events by their first occurrence's start time const sortedEvents = [...allEvents].sort((event1, event2) => { const time1 = event1.scheduledTimes[0]?.startTime ? new Date(event1.scheduledTimes[0].startTime).getTime() : 0; @@ -201,21 +222,6 @@ const NewCalendarPage = () => { .concat([...Array(daysInMonth(displayMonthYear)).keys()].map((day) => day + 1)) .concat(paddingArrayEnd.length < 7 ? paddingArrayEnd : []); - if (isLoading || !allEvents || allTeamTypesLoading || allEventTypesLoading || allCalendarsLoading || allTeamsLoading) - return ; - - if (!allTeamTypes || allTeamTypesLoading) return ; - if (allTeamTypesIsError) return ; - - if (!allEventTypes || allEventTypesLoading) return ; - if (allEventTypesIsError) return ; - - if (!allCalendars || allCalendarsLoading) return ; - if (allCalendarsIsError) return ; - - if (!allTeams || allTeamsLoading) return ; - if (allTeamsIsError) return ; - return ( <> {selectedEvent && ( From 543d3caac242508173f62c0c5247342094c7790b Mon Sep 17 00:00:00 2001 From: Samuel Shrestha Date: Tue, 16 Dec 2025 19:58:25 -0500 Subject: [PATCH 394/477] lint fixes --- .../src/pages/NewCalendarPage/NewCalendarPage.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index f42a223d4f..77a9edf038 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -2,7 +2,7 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Box, Grid, @@ -75,19 +75,20 @@ const NewCalendarPage = () => { const calendars = allCalendars ?? []; const [selectedCalendarIds, setSelectedCalendarIds] = useState([]); - const [didInitCalendarFilters, setDidInitCalendarFilters] = useState(false); const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); + const didInitCalendarFilters = useRef(false); + useEffect(() => { - if (didInitCalendarFilters) return; - if (!calendars.length) return; + if (didInitCalendarFilters.current) return; + if (!allCalendars?.length) return; - setSelectedCalendarIds(calendars.map((c) => c.calendarId)); - setDidInitCalendarFilters(true); - }, [calendars, didInitCalendarFilters]); + setSelectedCalendarIds(allCalendars.map((c) => c.calendarId)); + didInitCalendarFilters.current = true; + }, [allCalendars]); const { isLoading, From affcfbbd07643c9df85cd932d2a5ae22dc4b981f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 16 Dec 2025 20:34:30 -0500 Subject: [PATCH 395/477] functionality --- src/frontend/src/apis/calendar.api.ts | 8 + src/frontend/src/hooks/calendar.hooks.ts | 38 ++++- .../src/pages/NewCalendarPage/CalendarTab.tsx | 32 +++- .../pages/NewCalendarPage/EventClickPopup.tsx | 145 +++++++++++++----- .../pages/NewCalendarPage/NewCalendarPage.tsx | 31 +--- .../YourEventsComponents/WarningTooltip.tsx | 2 +- .../pages/NewCalendarPage/YourEventsPage.tsx | 43 +++++- src/frontend/src/utils/urls.ts | 4 + 8 files changed, 235 insertions(+), 68 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 5d7c7284d7..633a833816 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -163,6 +163,14 @@ export const setEventStatus = async (id: string, payload: { status: EventStatus }); }; +export const approveEvent = async (id: string) => { + return axios.post(apiUrls.calendarApproveEvent(id)); +}; + +export const denyEvent = async (id: string) => { + return axios.post(apiUrls.calendarDenyEvent(id)); +}; + export const postDeleteCalendar = async (id: string) => { return axios.post(apiUrls.calendarDeleteCalendar(id)); }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index d94e2f0a30..be0b340f86 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -33,7 +33,9 @@ import { deleteEvent, setEventStatus, getAllEventTypes, - postFilterEvents + postFilterEvents, + approveEvent, + denyEvent } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; @@ -346,3 +348,37 @@ export const useSetEventStatus = (id: string) => { } ); }; + +export const useApproveEvent = (id: string) => { + const queryClient = useQueryClient(); + return useMutation( + ['events', id], + async () => { + const { data } = await approveEvent(id); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['events', id]); + queryClient.invalidateQueries(['filter-events']); + } + } + ); +}; + +export const useDenyEvent = (id: string) => { + const queryClient = useQueryClient(); + return useMutation( + ['events', id], + async () => { + const { data } = await denyEvent(id); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['events', id]); + queryClient.invalidateQueries(['filter-events']); + } + } + ); +}; diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index 4fa812be06..ccd7915558 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -7,7 +7,7 @@ import FullPageTabs from '../../components/FullPageTabs'; import { useState } from 'react'; import { useCurrentUser } from '../../hooks/users.hooks'; import { ConflictStatus, isHead, isLead } from 'shared'; -import { useFilterEvents } from '../../hooks/calendar.hooks'; +import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; @@ -44,6 +44,20 @@ const CalendarTab: React.FC = () => { endPeriod: new Date(2099, 11, 31) // Adjust as needed }); + const { + data: allEventTypes, + isLoading: allEventTypesLoading, + isError: allEventTypesIsError, + error: allEventTypesError + } = useAllEventTypes(); + + const { + data: allCalendars, + isLoading: allCalendarsLoading, + isError: allCalendarsIsError, + error: allCalendarsError + } = useAllCalendars(); + const yourEvents = untransformedYourEvents?.map(filterEventTransformer); const reviewEvents = untransformedReviewEvents?.map(filterEventTransformer); @@ -53,6 +67,12 @@ const CalendarTab: React.FC = () => { if (!reviewEvents || reviewEventsLoading) return ; if (reviewEventsIsError) return ; + if (!allEventTypes || allEventTypesLoading) return ; + if (allEventTypesIsError) return ; + + if (!allCalendars || allCalendarsLoading) return ; + if (allCalendarsIsError) return ; + if (canViewReviews) tabs.push({ tabUrlValue: 'reviews', tabName: 'Review Bookings' }); return ( @@ -72,9 +92,15 @@ const CalendarTab: React.FC = () => { } > {tabIndex === 0 ? ( - + ) : ( - + )} ); diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 18deafb82a..9cf340823c 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -24,6 +24,9 @@ import EditIcon from '@mui/icons-material/Edit'; import PeopleIcon from '@mui/icons-material/People'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; +import NERSuccessButton from '../../components/NERSuccessButton'; +import NERFailButton from '../../components/NERFailButton'; +import { useApproveEvent, useCreateShop, useDenyEvent } from '../../hooks/calendar.hooks'; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ @@ -43,7 +46,10 @@ interface EventClickContentProps { event: Event; eventTypes: EventType[]; calendars: Calendar[]; - dayOfWeek: DayOfWeek; + dayOfWeek?: DayOfWeek; + disable: boolean; + addApprovalButtons: boolean; + onClose: () => void; } const joinPeople = (members: { firstName: string; lastName: string }[]) => @@ -54,12 +60,23 @@ const hasValue = (v?: string | null) => { return s.length > 0 && s.toLowerCase() !== 'n/a'; }; -const EventClickContent: React.FC = ({ event, eventTypes, calendars, dayOfWeek }) => { +const EventClickContent: React.FC = ({ + event, + eventTypes, + calendars, + dayOfWeek, + disable, + addApprovalButtons, + onClose +}) => { + const { mutateAsync: approveEvent } = useApproveEvent(event.eventId); + const { mutateAsync: denyEvent } = useDenyEvent(event.eventId); + const theme = useTheme(); const name = event.workPackages?.[0]?.wbsElement?.name || event.title; - const startTime = getConvertedStart(event, dayOfWeek); - const endTime = getConvertedEnd(event, dayOfWeek); + const startTime = dayOfWeek ? getConvertedStart(event, dayOfWeek) : ''; + const endTime = dayOfWeek ? getConvertedEnd(event, dayOfWeek) : ''; const specificEventType = eventTypes.find((et) => et.eventTypeId === event.eventTypeId); const specificCalendar = calendars.find((calendar) => @@ -99,25 +116,26 @@ const EventClickContent: React.FC = ({ event, eventTypes > {/* Edit -> availability page */} - - - - + {!disable && ( + + + + )} {getTeamTypeIcon(event.teamType?.name ?? '', true)} = ({ event, eventTypes - - - {startTime} – {endTime} - + {dayOfWeek && } + {dayOfWeek && ( + + {startTime} – {endTime} + + )} {hasValue(locationText) && ( <> @@ -197,6 +217,7 @@ const EventClickContent: React.FC = ({ event, eventTypes component={RouterLink} to={availabilityUrl} onClick={stopClick} + disabled={disable} sx={{ textTransform: 'none', borderRadius: 999, @@ -261,9 +282,15 @@ const EventClickContent: React.FC = ({ event, eventTypes {hasValue(event.zoomLink) && ( - e.stopPropagation()}> - Zoom Link - + {disable ? ( + + Zoom Link + + ) : ( + e.stopPropagation()}> + Zoom Link + + )} )} @@ -273,9 +300,15 @@ const EventClickContent: React.FC = ({ event, eventTypes Question doc:{' '} - e.stopPropagation()}> - Question Document Link - + {disable ? ( + + Question Document Link + + ) : ( + e.stopPropagation()}> + Question Document Link + + )} )} @@ -299,6 +332,29 @@ const EventClickContent: React.FC = ({ event, eventTypes )} + {addApprovalButtons && ( + + { + await approveEvent(); + onClose(); + }} + > + Approve + + { + await denyEvent(); + onClose(); + }} + > + Deny + + + )} ); @@ -310,7 +366,9 @@ export interface EventClickPopupProps { onClose: () => void; eventTypes: EventType[]; calendars: Calendar[]; - dayOfWeek: DayOfWeek; + dayOfWeek?: DayOfWeek; + disable?: boolean; + addApprovalButtons?: boolean; } export const EventClickPopup: React.FC = ({ @@ -319,7 +377,9 @@ export const EventClickPopup: React.FC = ({ onClose, eventTypes, calendars, - dayOfWeek + dayOfWeek, + disable = false, + addApprovalButtons = false }) => { return ( = ({ anchorOrigin={{ vertical: 'center', horizontal: 'center' }} transformOrigin={{ vertical: 'center', horizontal: 'center' }} disableRestoreFocus + PaperProps={{ + sx: { + backgroundImage: 'none' + } + }} > {clickedEvent && ( - + )} ); diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index b28033e5b3..f462481a6a 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -5,10 +5,10 @@ import { useState } from 'react'; import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; import PageLayout from '../../components/PageLayout'; -import { ConflictStatus, DayOfWeek, Event } from 'shared'; +import { Calendar, ConflictStatus, DayOfWeek, Event, EventType } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; -import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; +import { useFilterEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; @@ -22,7 +22,12 @@ import { useGetUsersTeams } from '../../hooks/teams.hooks'; import { convertIntToDay, getMeetingDates } from '../../utils/calendar.utils'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; -const NewCalendarPage = () => { +interface NewCalendarPageProps { + allEventTypes: EventType[]; + allCalendars: Calendar[]; +} + +const NewCalendarPage: React.FC = ({ allEventTypes, allCalendars }) => { const theme = useTheme(); const { data: allTeamTypes, @@ -59,20 +64,6 @@ const NewCalendarPage = () => { statuses: [ConflictStatus.APPROVED, ConflictStatus.NO_CONFLICT] }); - const { - data: allEventTypes, - isLoading: allEventTypesLoading, - isError: allEventTypesIsError, - error: allEventTypesError - } = useAllEventTypes(); - - const { - data: allCalendars, - isLoading: allCalendarsLoading, - isError: allCalendarsIsError, - error: allCalendarsError - } = useAllCalendars(); - const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); @@ -155,12 +146,6 @@ const NewCalendarPage = () => { if (!allTeamTypes || allTeamTypesLoading) return ; if (allTeamTypesIsError) return ; - if (!allEventTypes || allEventTypesLoading) return ; - if (allEventTypesIsError) return ; - - if (!allCalendars || allCalendarsLoading) return ; - if (allCalendarsIsError) return ; - if (!allTeams || allTeamsLoading) return ; if (allTeamsIsError) return ; diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx index bec872b126..35f6452dd2 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx @@ -61,8 +61,8 @@ const WarningTooltip: React.FC = ({ warning, buttonText, on } }} onClick={(e) => { - e.stopPropagation(); onClick(); + e.stopPropagation(); }} > {buttonText} diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index bbd0b6355f..1ea844aab2 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -6,10 +6,12 @@ import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, Tabl import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; import React, { useEffect, useState } from 'react'; -import { ConflictStatus } from 'shared'; +import { Calendar, ConflictStatus, DayOfWeek, EventType } from 'shared'; import { Event } from 'shared'; import WarningTooltip from './YourEventsComponents/WarningTooltip'; -import { getMeetingDates } from '../../utils/calendar.utils'; +import { convertIntToDay, getMeetingDates } from '../../utils/calendar.utils'; +import { EventClickPopup } from './EventClickPopup'; +import { datePipe } from '../../utils/pipes'; interface YourEventsHeadCells { id: string; @@ -35,14 +37,36 @@ const getNextMeetingTime = (event: Event) => { export interface EventTableArgs { yourEvents: Event[]; reviewEvents: Event[]; + allEventTypes: EventType[]; + allCalendars: Calendar[]; tab: number; } -const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvents }) => { +const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvents, allEventTypes, allCalendars }) => { // Convert to include proper dates // Done this way to allow the old events transformer to function properly // but provide better utility to this file (without breaking other files that may rely on eventTransformer) + const [clickedEvent, setClickedEvent] = useState(); + const [anchorPosition, setAnchorPosition] = useState<{ top: number; left: number }>(); + + const handleOpenClickPopup = (event: Event) => { + setClickedEvent(event); + if (typeof window !== 'undefined') { + setAnchorPosition({ + top: window.innerHeight / 2, + left: window.innerWidth / 2 + }); + } else { + setAnchorPosition({ top: 0, left: 0 }); + } + }; + + const handleCloseClickPopup = () => { + setClickedEvent(undefined); + setAnchorPosition(undefined); + }; + const headCells: readonly YourEventsHeadCells[] = [ { id: 'eventsName', @@ -228,7 +252,9 @@ const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvent {}} + onClick={() => { + handleOpenClickPopup(event); + }} /> )} @@ -252,6 +278,15 @@ const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvent + ); }; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index df5afd78da..0d6df04be5 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -463,6 +463,8 @@ const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; +const calendarApproveEvent = (id: string) => `${calendar()}/event/${id}/approve`; +const calendarDenyEvent = (id: string) => `${calendar()}/event/${id}/deny`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -789,6 +791,8 @@ export const apiUrls = { calendarCreateEventType, calendarEditEventType, calendarDeleteEventType, + calendarApproveEvent, + calendarDenyEvent, version }; From 878ee4d8a5bc6620e2e90287721e712ad183f9d3 Mon Sep 17 00:00:00 2001 From: Edison Kwok Date: Tue, 16 Dec 2025 20:40:16 -0500 Subject: [PATCH 396/477] #3819 minor fix --- src/backend/src/services/calendar.services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 2efd55d7ec..85d3670eb5 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2184,7 +2184,7 @@ export default class CalendarService { eventId: eventIds?.length ? { in: eventIds } : undefined, eventTypeId: eventTypeIds?.length ? { in: eventTypeIds } : undefined, approvalRequiredFromUserId: approvalIds?.length ? { in: approvalIds } : undefined, - OR: memberOrTeamFilter.length > 0 ? memberOrTeamFilter : undefined, + OR: memberOrTeamFilter.length ? memberOrTeamFilter : undefined, approved: statuses?.length ? { in: statuses } : undefined, scheduledTimes: buildScheduledTimesOverlap(startPeriod, endPeriod), ...fromCalendar From faf71c1ba9dd85d83d31dcc875c0f600838b1d81 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 16 Dec 2025 20:57:00 -0500 Subject: [PATCH 397/477] minor fix --- src/frontend/src/utils/calendar.utils.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 204a512dce..76a2d0008c 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -44,9 +44,11 @@ export const convertIntToDay = (num: number) => { // Get a list of dates for user viewing purposes (formatted to their timezone) // Should be used when events need to be populated/displayed -export const getMeetingDates = (event: Event) => { +export const getMeetingDates = (event: Event, startTimes: boolean = true) => { const times: Date[] = []; event.scheduledTimes.forEach((schedule) => { + const specificTime = startTimes ? schedule.startTime : schedule.endTime; + schedule.days.forEach((day) => { const startTimeDate = new Date(schedule.initialDateScheduled); const timezoneOffset = startTimeDate.getTimezoneOffset() * 60000; @@ -62,9 +64,9 @@ export const getMeetingDates = (event: Event) => { startDate.setDate(startDate.getDate() - offset); // Note : schedule.startTime likely gets converted to the users timezone by default - // set the hour and minutes - startDate.setHours(schedule.startTime?.getHours() ?? 0); - startDate.setMinutes(schedule.startTime?.getMinutes() ?? 0); + // set the hour and minutes using UTC to match the adjusted date + startDate.setHours(specificTime?.getUTCHours() ?? 0); + startDate.setMinutes(specificTime?.getUTCMinutes() ?? 0); // adjust for the users time const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); From d272fa52bffc9b6a4b98ae214dbe1fa84fdb59f8 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 16 Dec 2025 21:14:20 -0500 Subject: [PATCH 398/477] Revert "functionality" This reverts commit affcfbbd07643c9df85cd932d2a5ae22dc4b981f. --- src/frontend/src/apis/calendar.api.ts | 8 - src/frontend/src/hooks/calendar.hooks.ts | 38 +---- .../src/pages/NewCalendarPage/CalendarTab.tsx | 32 +--- .../pages/NewCalendarPage/EventClickPopup.tsx | 145 +++++------------- .../pages/NewCalendarPage/NewCalendarPage.tsx | 31 +++- .../YourEventsComponents/WarningTooltip.tsx | 2 +- .../pages/NewCalendarPage/YourEventsPage.tsx | 43 +----- src/frontend/src/utils/urls.ts | 4 - 8 files changed, 68 insertions(+), 235 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 633a833816..5d7c7284d7 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -163,14 +163,6 @@ export const setEventStatus = async (id: string, payload: { status: EventStatus }); }; -export const approveEvent = async (id: string) => { - return axios.post(apiUrls.calendarApproveEvent(id)); -}; - -export const denyEvent = async (id: string) => { - return axios.post(apiUrls.calendarDenyEvent(id)); -}; - export const postDeleteCalendar = async (id: string) => { return axios.post(apiUrls.calendarDeleteCalendar(id)); }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index be0b340f86..d94e2f0a30 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -33,9 +33,7 @@ import { deleteEvent, setEventStatus, getAllEventTypes, - postFilterEvents, - approveEvent, - denyEvent + postFilterEvents } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; @@ -348,37 +346,3 @@ export const useSetEventStatus = (id: string) => { } ); }; - -export const useApproveEvent = (id: string) => { - const queryClient = useQueryClient(); - return useMutation( - ['events', id], - async () => { - const { data } = await approveEvent(id); - return data; - }, - { - onSuccess: () => { - queryClient.invalidateQueries(['events', id]); - queryClient.invalidateQueries(['filter-events']); - } - } - ); -}; - -export const useDenyEvent = (id: string) => { - const queryClient = useQueryClient(); - return useMutation( - ['events', id], - async () => { - const { data } = await denyEvent(id); - return data; - }, - { - onSuccess: () => { - queryClient.invalidateQueries(['events', id]); - queryClient.invalidateQueries(['filter-events']); - } - } - ); -}; diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index ccd7915558..4fa812be06 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -7,7 +7,7 @@ import FullPageTabs from '../../components/FullPageTabs'; import { useState } from 'react'; import { useCurrentUser } from '../../hooks/users.hooks'; import { ConflictStatus, isHead, isLead } from 'shared'; -import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; +import { useFilterEvents } from '../../hooks/calendar.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; @@ -44,20 +44,6 @@ const CalendarTab: React.FC = () => { endPeriod: new Date(2099, 11, 31) // Adjust as needed }); - const { - data: allEventTypes, - isLoading: allEventTypesLoading, - isError: allEventTypesIsError, - error: allEventTypesError - } = useAllEventTypes(); - - const { - data: allCalendars, - isLoading: allCalendarsLoading, - isError: allCalendarsIsError, - error: allCalendarsError - } = useAllCalendars(); - const yourEvents = untransformedYourEvents?.map(filterEventTransformer); const reviewEvents = untransformedReviewEvents?.map(filterEventTransformer); @@ -67,12 +53,6 @@ const CalendarTab: React.FC = () => { if (!reviewEvents || reviewEventsLoading) return ; if (reviewEventsIsError) return ; - if (!allEventTypes || allEventTypesLoading) return ; - if (allEventTypesIsError) return ; - - if (!allCalendars || allCalendarsLoading) return ; - if (allCalendarsIsError) return ; - if (canViewReviews) tabs.push({ tabUrlValue: 'reviews', tabName: 'Review Bookings' }); return ( @@ -92,15 +72,9 @@ const CalendarTab: React.FC = () => { } > {tabIndex === 0 ? ( - + ) : ( - + )} ); diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 9cf340823c..18deafb82a 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -24,9 +24,6 @@ import EditIcon from '@mui/icons-material/Edit'; import PeopleIcon from '@mui/icons-material/People'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; -import NERSuccessButton from '../../components/NERSuccessButton'; -import NERFailButton from '../../components/NERFailButton'; -import { useApproveEvent, useCreateShop, useDenyEvent } from '../../hooks/calendar.hooks'; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ @@ -46,10 +43,7 @@ interface EventClickContentProps { event: Event; eventTypes: EventType[]; calendars: Calendar[]; - dayOfWeek?: DayOfWeek; - disable: boolean; - addApprovalButtons: boolean; - onClose: () => void; + dayOfWeek: DayOfWeek; } const joinPeople = (members: { firstName: string; lastName: string }[]) => @@ -60,23 +54,12 @@ const hasValue = (v?: string | null) => { return s.length > 0 && s.toLowerCase() !== 'n/a'; }; -const EventClickContent: React.FC = ({ - event, - eventTypes, - calendars, - dayOfWeek, - disable, - addApprovalButtons, - onClose -}) => { - const { mutateAsync: approveEvent } = useApproveEvent(event.eventId); - const { mutateAsync: denyEvent } = useDenyEvent(event.eventId); - +const EventClickContent: React.FC = ({ event, eventTypes, calendars, dayOfWeek }) => { const theme = useTheme(); const name = event.workPackages?.[0]?.wbsElement?.name || event.title; - const startTime = dayOfWeek ? getConvertedStart(event, dayOfWeek) : ''; - const endTime = dayOfWeek ? getConvertedEnd(event, dayOfWeek) : ''; + const startTime = getConvertedStart(event, dayOfWeek); + const endTime = getConvertedEnd(event, dayOfWeek); const specificEventType = eventTypes.find((et) => et.eventTypeId === event.eventTypeId); const specificCalendar = calendars.find((calendar) => @@ -116,26 +99,25 @@ const EventClickContent: React.FC = ({ > {/* Edit -> availability page */} - {!disable && ( - - - - )} + + + + {getTeamTypeIcon(event.teamType?.name ?? '', true)} = ({ - {dayOfWeek && } - {dayOfWeek && ( - - {startTime} – {endTime} - - )} + + + {startTime} – {endTime} + {hasValue(locationText) && ( <> @@ -217,7 +197,6 @@ const EventClickContent: React.FC = ({ component={RouterLink} to={availabilityUrl} onClick={stopClick} - disabled={disable} sx={{ textTransform: 'none', borderRadius: 999, @@ -282,15 +261,9 @@ const EventClickContent: React.FC = ({ {hasValue(event.zoomLink) && ( - {disable ? ( - - Zoom Link - - ) : ( - e.stopPropagation()}> - Zoom Link - - )} + e.stopPropagation()}> + Zoom Link + )} @@ -300,15 +273,9 @@ const EventClickContent: React.FC = ({ Question doc:{' '} - {disable ? ( - - Question Document Link - - ) : ( - e.stopPropagation()}> - Question Document Link - - )} + e.stopPropagation()}> + Question Document Link + )} @@ -332,29 +299,6 @@ const EventClickContent: React.FC = ({ )} - {addApprovalButtons && ( - - { - await approveEvent(); - onClose(); - }} - > - Approve - - { - await denyEvent(); - onClose(); - }} - > - Deny - - - )} ); @@ -366,9 +310,7 @@ export interface EventClickPopupProps { onClose: () => void; eventTypes: EventType[]; calendars: Calendar[]; - dayOfWeek?: DayOfWeek; - disable?: boolean; - addApprovalButtons?: boolean; + dayOfWeek: DayOfWeek; } export const EventClickPopup: React.FC = ({ @@ -377,9 +319,7 @@ export const EventClickPopup: React.FC = ({ onClose, eventTypes, calendars, - dayOfWeek, - disable = false, - addApprovalButtons = false + dayOfWeek }) => { return ( = ({ anchorOrigin={{ vertical: 'center', horizontal: 'center' }} transformOrigin={{ vertical: 'center', horizontal: 'center' }} disableRestoreFocus - PaperProps={{ - sx: { - backgroundImage: 'none' - } - }} > {clickedEvent && ( - + )} ); diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index f462481a6a..b28033e5b3 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -5,10 +5,10 @@ import { useState } from 'react'; import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; import PageLayout from '../../components/PageLayout'; -import { Calendar, ConflictStatus, DayOfWeek, Event, EventType } from 'shared'; +import { ConflictStatus, DayOfWeek, Event } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; -import { useFilterEvents } from '../../hooks/calendar.hooks'; +import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; @@ -22,12 +22,7 @@ import { useGetUsersTeams } from '../../hooks/teams.hooks'; import { convertIntToDay, getMeetingDates } from '../../utils/calendar.utils'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; -interface NewCalendarPageProps { - allEventTypes: EventType[]; - allCalendars: Calendar[]; -} - -const NewCalendarPage: React.FC = ({ allEventTypes, allCalendars }) => { +const NewCalendarPage = () => { const theme = useTheme(); const { data: allTeamTypes, @@ -64,6 +59,20 @@ const NewCalendarPage: React.FC = ({ allEventTypes, allCal statuses: [ConflictStatus.APPROVED, ConflictStatus.NO_CONFLICT] }); + const { + data: allEventTypes, + isLoading: allEventTypesLoading, + isError: allEventTypesIsError, + error: allEventTypesError + } = useAllEventTypes(); + + const { + data: allCalendars, + isLoading: allCalendarsLoading, + isError: allCalendarsIsError, + error: allCalendarsError + } = useAllCalendars(); + const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); @@ -146,6 +155,12 @@ const NewCalendarPage: React.FC = ({ allEventTypes, allCal if (!allTeamTypes || allTeamTypesLoading) return ; if (allTeamTypesIsError) return ; + if (!allEventTypes || allEventTypesLoading) return ; + if (allEventTypesIsError) return ; + + if (!allCalendars || allCalendarsLoading) return ; + if (allCalendarsIsError) return ; + if (!allTeams || allTeamsLoading) return ; if (allTeamsIsError) return ; diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx index 35f6452dd2..bec872b126 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx @@ -61,8 +61,8 @@ const WarningTooltip: React.FC = ({ warning, buttonText, on } }} onClick={(e) => { - onClick(); e.stopPropagation(); + onClick(); }} > {buttonText} diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index 1ea844aab2..bbd0b6355f 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -6,12 +6,10 @@ import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, Tabl import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; import React, { useEffect, useState } from 'react'; -import { Calendar, ConflictStatus, DayOfWeek, EventType } from 'shared'; +import { ConflictStatus } from 'shared'; import { Event } from 'shared'; import WarningTooltip from './YourEventsComponents/WarningTooltip'; -import { convertIntToDay, getMeetingDates } from '../../utils/calendar.utils'; -import { EventClickPopup } from './EventClickPopup'; -import { datePipe } from '../../utils/pipes'; +import { getMeetingDates } from '../../utils/calendar.utils'; interface YourEventsHeadCells { id: string; @@ -37,36 +35,14 @@ const getNextMeetingTime = (event: Event) => { export interface EventTableArgs { yourEvents: Event[]; reviewEvents: Event[]; - allEventTypes: EventType[]; - allCalendars: Calendar[]; tab: number; } -const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvents, allEventTypes, allCalendars }) => { +const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvents }) => { // Convert to include proper dates // Done this way to allow the old events transformer to function properly // but provide better utility to this file (without breaking other files that may rely on eventTransformer) - const [clickedEvent, setClickedEvent] = useState(); - const [anchorPosition, setAnchorPosition] = useState<{ top: number; left: number }>(); - - const handleOpenClickPopup = (event: Event) => { - setClickedEvent(event); - if (typeof window !== 'undefined') { - setAnchorPosition({ - top: window.innerHeight / 2, - left: window.innerWidth / 2 - }); - } else { - setAnchorPosition({ top: 0, left: 0 }); - } - }; - - const handleCloseClickPopup = () => { - setClickedEvent(undefined); - setAnchorPosition(undefined); - }; - const headCells: readonly YourEventsHeadCells[] = [ { id: 'eventsName', @@ -252,9 +228,7 @@ const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvent { - handleOpenClickPopup(event); - }} + onClick={() => {}} /> )} @@ -278,15 +252,6 @@ const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvent - ); }; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 0d6df04be5..df5afd78da 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -463,8 +463,6 @@ const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; -const calendarApproveEvent = (id: string) => `${calendar()}/event/${id}/approve`; -const calendarDenyEvent = (id: string) => `${calendar()}/event/${id}/deny`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -791,8 +789,6 @@ export const apiUrls = { calendarCreateEventType, calendarEditEventType, calendarDeleteEventType, - calendarApproveEvent, - calendarDenyEvent, version }; From 2fa932ca81a996fe7d94171e7c28d103c80f8ec1 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 16 Dec 2025 21:15:52 -0500 Subject: [PATCH 399/477] Revert "minor fix" This reverts commit faf71c1ba9dd85d83d31dcc875c0f600838b1d81. --- src/frontend/src/utils/calendar.utils.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 76a2d0008c..204a512dce 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -44,11 +44,9 @@ export const convertIntToDay = (num: number) => { // Get a list of dates for user viewing purposes (formatted to their timezone) // Should be used when events need to be populated/displayed -export const getMeetingDates = (event: Event, startTimes: boolean = true) => { +export const getMeetingDates = (event: Event) => { const times: Date[] = []; event.scheduledTimes.forEach((schedule) => { - const specificTime = startTimes ? schedule.startTime : schedule.endTime; - schedule.days.forEach((day) => { const startTimeDate = new Date(schedule.initialDateScheduled); const timezoneOffset = startTimeDate.getTimezoneOffset() * 60000; @@ -64,9 +62,9 @@ export const getMeetingDates = (event: Event, startTimes: boolean = true) => { startDate.setDate(startDate.getDate() - offset); // Note : schedule.startTime likely gets converted to the users timezone by default - // set the hour and minutes using UTC to match the adjusted date - startDate.setHours(specificTime?.getUTCHours() ?? 0); - startDate.setMinutes(specificTime?.getUTCMinutes() ?? 0); + // set the hour and minutes + startDate.setHours(schedule.startTime?.getHours() ?? 0); + startDate.setMinutes(schedule.startTime?.getMinutes() ?? 0); // adjust for the users time const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); From 5a401a3bc4ca5dcadbd3fc8f67836ac67387e921 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 16 Dec 2025 21:16:49 -0500 Subject: [PATCH 400/477] Reapply "functionality" This reverts commit d272fa52bffc9b6a4b98ae214dbe1fa84fdb59f8. --- src/frontend/src/apis/calendar.api.ts | 8 + src/frontend/src/hooks/calendar.hooks.ts | 38 ++++- .../src/pages/NewCalendarPage/CalendarTab.tsx | 32 +++- .../pages/NewCalendarPage/EventClickPopup.tsx | 145 +++++++++++++----- .../pages/NewCalendarPage/NewCalendarPage.tsx | 31 +--- .../YourEventsComponents/WarningTooltip.tsx | 2 +- .../pages/NewCalendarPage/YourEventsPage.tsx | 43 +++++- src/frontend/src/utils/urls.ts | 4 + 8 files changed, 235 insertions(+), 68 deletions(-) diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 5d7c7284d7..633a833816 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -163,6 +163,14 @@ export const setEventStatus = async (id: string, payload: { status: EventStatus }); }; +export const approveEvent = async (id: string) => { + return axios.post(apiUrls.calendarApproveEvent(id)); +}; + +export const denyEvent = async (id: string) => { + return axios.post(apiUrls.calendarDenyEvent(id)); +}; + export const postDeleteCalendar = async (id: string) => { return axios.post(apiUrls.calendarDeleteCalendar(id)); }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index d94e2f0a30..be0b340f86 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -33,7 +33,9 @@ import { deleteEvent, setEventStatus, getAllEventTypes, - postFilterEvents + postFilterEvents, + approveEvent, + denyEvent } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; @@ -346,3 +348,37 @@ export const useSetEventStatus = (id: string) => { } ); }; + +export const useApproveEvent = (id: string) => { + const queryClient = useQueryClient(); + return useMutation( + ['events', id], + async () => { + const { data } = await approveEvent(id); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['events', id]); + queryClient.invalidateQueries(['filter-events']); + } + } + ); +}; + +export const useDenyEvent = (id: string) => { + const queryClient = useQueryClient(); + return useMutation( + ['events', id], + async () => { + const { data } = await denyEvent(id); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['events', id]); + queryClient.invalidateQueries(['filter-events']); + } + } + ); +}; diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index 4fa812be06..ccd7915558 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -7,7 +7,7 @@ import FullPageTabs from '../../components/FullPageTabs'; import { useState } from 'react'; import { useCurrentUser } from '../../hooks/users.hooks'; import { ConflictStatus, isHead, isLead } from 'shared'; -import { useFilterEvents } from '../../hooks/calendar.hooks'; +import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; @@ -44,6 +44,20 @@ const CalendarTab: React.FC = () => { endPeriod: new Date(2099, 11, 31) // Adjust as needed }); + const { + data: allEventTypes, + isLoading: allEventTypesLoading, + isError: allEventTypesIsError, + error: allEventTypesError + } = useAllEventTypes(); + + const { + data: allCalendars, + isLoading: allCalendarsLoading, + isError: allCalendarsIsError, + error: allCalendarsError + } = useAllCalendars(); + const yourEvents = untransformedYourEvents?.map(filterEventTransformer); const reviewEvents = untransformedReviewEvents?.map(filterEventTransformer); @@ -53,6 +67,12 @@ const CalendarTab: React.FC = () => { if (!reviewEvents || reviewEventsLoading) return ; if (reviewEventsIsError) return ; + if (!allEventTypes || allEventTypesLoading) return ; + if (allEventTypesIsError) return ; + + if (!allCalendars || allCalendarsLoading) return ; + if (allCalendarsIsError) return ; + if (canViewReviews) tabs.push({ tabUrlValue: 'reviews', tabName: 'Review Bookings' }); return ( @@ -72,9 +92,15 @@ const CalendarTab: React.FC = () => { } > {tabIndex === 0 ? ( - + ) : ( - + )} ); diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 18deafb82a..9cf340823c 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -24,6 +24,9 @@ import EditIcon from '@mui/icons-material/Edit'; import PeopleIcon from '@mui/icons-material/People'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; +import NERSuccessButton from '../../components/NERSuccessButton'; +import NERFailButton from '../../components/NERFailButton'; +import { useApproveEvent, useCreateShop, useDenyEvent } from '../../hooks/calendar.hooks'; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ @@ -43,7 +46,10 @@ interface EventClickContentProps { event: Event; eventTypes: EventType[]; calendars: Calendar[]; - dayOfWeek: DayOfWeek; + dayOfWeek?: DayOfWeek; + disable: boolean; + addApprovalButtons: boolean; + onClose: () => void; } const joinPeople = (members: { firstName: string; lastName: string }[]) => @@ -54,12 +60,23 @@ const hasValue = (v?: string | null) => { return s.length > 0 && s.toLowerCase() !== 'n/a'; }; -const EventClickContent: React.FC = ({ event, eventTypes, calendars, dayOfWeek }) => { +const EventClickContent: React.FC = ({ + event, + eventTypes, + calendars, + dayOfWeek, + disable, + addApprovalButtons, + onClose +}) => { + const { mutateAsync: approveEvent } = useApproveEvent(event.eventId); + const { mutateAsync: denyEvent } = useDenyEvent(event.eventId); + const theme = useTheme(); const name = event.workPackages?.[0]?.wbsElement?.name || event.title; - const startTime = getConvertedStart(event, dayOfWeek); - const endTime = getConvertedEnd(event, dayOfWeek); + const startTime = dayOfWeek ? getConvertedStart(event, dayOfWeek) : ''; + const endTime = dayOfWeek ? getConvertedEnd(event, dayOfWeek) : ''; const specificEventType = eventTypes.find((et) => et.eventTypeId === event.eventTypeId); const specificCalendar = calendars.find((calendar) => @@ -99,25 +116,26 @@ const EventClickContent: React.FC = ({ event, eventTypes > {/* Edit -> availability page */} - - - - + {!disable && ( + + + + )} {getTeamTypeIcon(event.teamType?.name ?? '', true)} = ({ event, eventTypes - - - {startTime} – {endTime} - + {dayOfWeek && } + {dayOfWeek && ( + + {startTime} – {endTime} + + )} {hasValue(locationText) && ( <> @@ -197,6 +217,7 @@ const EventClickContent: React.FC = ({ event, eventTypes component={RouterLink} to={availabilityUrl} onClick={stopClick} + disabled={disable} sx={{ textTransform: 'none', borderRadius: 999, @@ -261,9 +282,15 @@ const EventClickContent: React.FC = ({ event, eventTypes {hasValue(event.zoomLink) && ( - e.stopPropagation()}> - Zoom Link - + {disable ? ( + + Zoom Link + + ) : ( + e.stopPropagation()}> + Zoom Link + + )} )} @@ -273,9 +300,15 @@ const EventClickContent: React.FC = ({ event, eventTypes Question doc:{' '} - e.stopPropagation()}> - Question Document Link - + {disable ? ( + + Question Document Link + + ) : ( + e.stopPropagation()}> + Question Document Link + + )} )} @@ -299,6 +332,29 @@ const EventClickContent: React.FC = ({ event, eventTypes )} + {addApprovalButtons && ( + + { + await approveEvent(); + onClose(); + }} + > + Approve + + { + await denyEvent(); + onClose(); + }} + > + Deny + + + )} ); @@ -310,7 +366,9 @@ export interface EventClickPopupProps { onClose: () => void; eventTypes: EventType[]; calendars: Calendar[]; - dayOfWeek: DayOfWeek; + dayOfWeek?: DayOfWeek; + disable?: boolean; + addApprovalButtons?: boolean; } export const EventClickPopup: React.FC = ({ @@ -319,7 +377,9 @@ export const EventClickPopup: React.FC = ({ onClose, eventTypes, calendars, - dayOfWeek + dayOfWeek, + disable = false, + addApprovalButtons = false }) => { return ( = ({ anchorOrigin={{ vertical: 'center', horizontal: 'center' }} transformOrigin={{ vertical: 'center', horizontal: 'center' }} disableRestoreFocus + PaperProps={{ + sx: { + backgroundImage: 'none' + } + }} > {clickedEvent && ( - + )} ); diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index b28033e5b3..f462481a6a 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -5,10 +5,10 @@ import { useState } from 'react'; import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button } from '@mui/material'; import PageLayout from '../../components/PageLayout'; -import { ConflictStatus, DayOfWeek, Event } from 'shared'; +import { Calendar, ConflictStatus, DayOfWeek, Event, EventType } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; -import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; +import { useFilterEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; @@ -22,7 +22,12 @@ import { useGetUsersTeams } from '../../hooks/teams.hooks'; import { convertIntToDay, getMeetingDates } from '../../utils/calendar.utils'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; -const NewCalendarPage = () => { +interface NewCalendarPageProps { + allEventTypes: EventType[]; + allCalendars: Calendar[]; +} + +const NewCalendarPage: React.FC = ({ allEventTypes, allCalendars }) => { const theme = useTheme(); const { data: allTeamTypes, @@ -59,20 +64,6 @@ const NewCalendarPage = () => { statuses: [ConflictStatus.APPROVED, ConflictStatus.NO_CONFLICT] }); - const { - data: allEventTypes, - isLoading: allEventTypesLoading, - isError: allEventTypesIsError, - error: allEventTypesError - } = useAllEventTypes(); - - const { - data: allCalendars, - isLoading: allCalendarsLoading, - isError: allCalendarsIsError, - error: allCalendarsError - } = useAllCalendars(); - const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); @@ -155,12 +146,6 @@ const NewCalendarPage = () => { if (!allTeamTypes || allTeamTypesLoading) return ; if (allTeamTypesIsError) return ; - if (!allEventTypes || allEventTypesLoading) return ; - if (allEventTypesIsError) return ; - - if (!allCalendars || allCalendarsLoading) return ; - if (allCalendarsIsError) return ; - if (!allTeams || allTeamsLoading) return ; if (allTeamsIsError) return ; diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx index bec872b126..35f6452dd2 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsComponents/WarningTooltip.tsx @@ -61,8 +61,8 @@ const WarningTooltip: React.FC = ({ warning, buttonText, on } }} onClick={(e) => { - e.stopPropagation(); onClick(); + e.stopPropagation(); }} > {buttonText} diff --git a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx index bbd0b6355f..1ea844aab2 100644 --- a/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/YourEventsPage.tsx @@ -6,10 +6,12 @@ import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, Tabl import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; import React, { useEffect, useState } from 'react'; -import { ConflictStatus } from 'shared'; +import { Calendar, ConflictStatus, DayOfWeek, EventType } from 'shared'; import { Event } from 'shared'; import WarningTooltip from './YourEventsComponents/WarningTooltip'; -import { getMeetingDates } from '../../utils/calendar.utils'; +import { convertIntToDay, getMeetingDates } from '../../utils/calendar.utils'; +import { EventClickPopup } from './EventClickPopup'; +import { datePipe } from '../../utils/pipes'; interface YourEventsHeadCells { id: string; @@ -35,14 +37,36 @@ const getNextMeetingTime = (event: Event) => { export interface EventTableArgs { yourEvents: Event[]; reviewEvents: Event[]; + allEventTypes: EventType[]; + allCalendars: Calendar[]; tab: number; } -const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvents }) => { +const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvents, allEventTypes, allCalendars }) => { // Convert to include proper dates // Done this way to allow the old events transformer to function properly // but provide better utility to this file (without breaking other files that may rely on eventTransformer) + const [clickedEvent, setClickedEvent] = useState(); + const [anchorPosition, setAnchorPosition] = useState<{ top: number; left: number }>(); + + const handleOpenClickPopup = (event: Event) => { + setClickedEvent(event); + if (typeof window !== 'undefined') { + setAnchorPosition({ + top: window.innerHeight / 2, + left: window.innerWidth / 2 + }); + } else { + setAnchorPosition({ top: 0, left: 0 }); + } + }; + + const handleCloseClickPopup = () => { + setClickedEvent(undefined); + setAnchorPosition(undefined); + }; + const headCells: readonly YourEventsHeadCells[] = [ { id: 'eventsName', @@ -228,7 +252,9 @@ const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvent {}} + onClick={() => { + handleOpenClickPopup(event); + }} /> )} @@ -252,6 +278,15 @@ const YourEventsPage: React.FC = ({ tab, yourEvents, reviewEvent + ); }; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index df5afd78da..0d6df04be5 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -463,6 +463,8 @@ const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; +const calendarApproveEvent = (id: string) => `${calendar()}/event/${id}/approve`; +const calendarDenyEvent = (id: string) => `${calendar()}/event/${id}/deny`; /**************** Other Endpoints ****************/ const version = () => `https://api.github.com/repos/Northeastern-Electric-Racing/FinishLine/releases/latest`; @@ -789,6 +791,8 @@ export const apiUrls = { calendarCreateEventType, calendarEditEventType, calendarDeleteEventType, + calendarApproveEvent, + calendarDenyEvent, version }; From b6d7852f08d8458d65dd5831a835754e9aa1e327 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 16 Dec 2025 21:16:59 -0500 Subject: [PATCH 401/477] Reapply "minor fix" This reverts commit 2fa932ca81a996fe7d94171e7c28d103c80f8ec1. --- src/frontend/src/utils/calendar.utils.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 204a512dce..76a2d0008c 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -44,9 +44,11 @@ export const convertIntToDay = (num: number) => { // Get a list of dates for user viewing purposes (formatted to their timezone) // Should be used when events need to be populated/displayed -export const getMeetingDates = (event: Event) => { +export const getMeetingDates = (event: Event, startTimes: boolean = true) => { const times: Date[] = []; event.scheduledTimes.forEach((schedule) => { + const specificTime = startTimes ? schedule.startTime : schedule.endTime; + schedule.days.forEach((day) => { const startTimeDate = new Date(schedule.initialDateScheduled); const timezoneOffset = startTimeDate.getTimezoneOffset() * 60000; @@ -62,9 +64,9 @@ export const getMeetingDates = (event: Event) => { startDate.setDate(startDate.getDate() - offset); // Note : schedule.startTime likely gets converted to the users timezone by default - // set the hour and minutes - startDate.setHours(schedule.startTime?.getHours() ?? 0); - startDate.setMinutes(schedule.startTime?.getMinutes() ?? 0); + // set the hour and minutes using UTC to match the adjusted date + startDate.setHours(specificTime?.getUTCHours() ?? 0); + startDate.setMinutes(specificTime?.getUTCMinutes() ?? 0); // adjust for the users time const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); From ab8c9844df6dbea8c179cc21ca72a6f5b6937e51 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Tue, 16 Dec 2025 21:19:23 -0500 Subject: [PATCH 402/477] minor adjustment maybe --- src/frontend/src/utils/calendar.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 76a2d0008c..06dbc64afc 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -72,7 +72,7 @@ export const getMeetingDates = (event: Event, startTimes: boolean = true) => { const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); // potentially needed to prevent extra events from showing up before the initial date - if (new Date(schedule.initialDateScheduled).getTime() >= startDateAdjusted.getTime()) times.push(startDateAdjusted); + times.push(startDateAdjusted); // add additional events for each recurrence on this day for (let i = 1; i <= schedule.recurrenceNumber; i++) { From 43b2960b88ebefe6613b9c2735aa8200a4639e61 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 00:40:47 -0500 Subject: [PATCH 403/477] readability changes --- src/frontend/src/utils/datetime.utils.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/frontend/src/utils/datetime.utils.ts b/src/frontend/src/utils/datetime.utils.ts index 588a5129e6..8f9e573351 100644 --- a/src/frontend/src/utils/datetime.utils.ts +++ b/src/frontend/src/utils/datetime.utils.ts @@ -65,20 +65,18 @@ export const isPastEvent = (startDate: Date, endDate: Date) => { return startDate < endDate; }; +// gets the start time of an event for a given day export const getConvertedStart = (event: Event, dayOfWeek: DayOfWeek) => { const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); - const initialTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(Date.now()); - const startTime = new Date( - // getTimezoneOffset() is based on UTC (in minutes), and we need to inverse it and multiply by milliseconds to get the proper date - // for instance, if we were in UTC+3, it would return -180, which we need to invert and multiply to - initialTime.getTime() - ); + + const startTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(Date.now()); const convertedStartTime = startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); return convertedStartTime; }; +// gets the end time of an event for a given day export const getConvertedEnd = (event: Event, dayOfWeek: DayOfWeek) => { const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); @@ -86,8 +84,7 @@ export const getConvertedEnd = (event: Event, dayOfWeek: DayOfWeek) => { const convertedEndTime = endTime.toLocaleTimeString('en-US', { hour: 'numeric', - minute: '2-digit', - timeZoneName: 'short' + minute: '2-digit' }); return convertedEndTime; From a94011d8813069942d6bf57b997e9f1c1d34e402 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 00:41:42 -0500 Subject: [PATCH 404/477] formatting 2 --- src/frontend/src/utils/calendar.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 06dbc64afc..edc2bb3730 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -42,7 +42,7 @@ export const convertIntToDay = (num: number) => { } }; -// Get a list of dates for user viewing purposes (formatted to their timezone) +// Get a list of dates for user viewing purposes (formatted to their timezone, with date and start time) // Should be used when events need to be populated/displayed export const getMeetingDates = (event: Event, startTimes: boolean = true) => { const times: Date[] = []; From 2c715a5fdb5dd86c741251a8ba6ca72dd0f28de3 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 01:03:32 -0500 Subject: [PATCH 405/477] time changes --- .../pages/NewCalendarPage/EventClickPopup.tsx | 15 ++++++++++++- src/frontend/src/utils/calendar.utils.ts | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 9cf340823c..83743dd04a 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -27,6 +27,7 @@ import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; import NERSuccessButton from '../../components/NERSuccessButton'; import NERFailButton from '../../components/NERFailButton'; import { useApproveEvent, useCreateShop, useDenyEvent } from '../../hooks/calendar.hooks'; +import { convertDayToDayShorthand } from '../../utils/calendar.utils'; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ @@ -157,7 +158,19 @@ const EventClickContent: React.FC = ({ {startTime} – {endTime} )} - + {!dayOfWeek && } + {!dayOfWeek && ( + + {event.scheduledTimes.map((slot) => ( + + {slot.startTime?.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) ?? 'N/A'} –{' '} + {slot.endTime?.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) ?? 'N/A'} + {' : '} + {slot.days.map((day) => convertDayToDayShorthand(day)).join(', ')} + + ))} + + )} {hasValue(locationText) && ( <> diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index edc2bb3730..f3154ddb51 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -42,6 +42,27 @@ export const convertIntToDay = (num: number) => { } }; +export const convertDayToDayShorthand = (day: DayOfWeek) => { + switch (day) { + case DayOfWeek.MONDAY: + return 'M'; + case DayOfWeek.TUESDAY: + return 'T'; + case DayOfWeek.WEDNESDAY: + return 'W'; + case DayOfWeek.THURSDAY: + return 'Th'; + case DayOfWeek.FRIDAY: + return 'F'; + case DayOfWeek.SATURDAY: + return 'Sat'; + case DayOfWeek.SUNDAY: + return 'S'; + default: + return 'Undefined'; + } +}; + // Get a list of dates for user viewing purposes (formatted to their timezone, with date and start time) // Should be used when events need to be populated/displayed export const getMeetingDates = (event: Event, startTimes: boolean = true) => { From 61be6f0384ac543097090d6d10099a18fb586838 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 01:06:44 -0500 Subject: [PATCH 406/477] documentation --- src/frontend/src/utils/calendar.utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index f3154ddb51..4d64fd6eb4 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -63,7 +63,8 @@ export const convertDayToDayShorthand = (day: DayOfWeek) => { } }; -// Get a list of dates for user viewing purposes (formatted to their timezone, with date and start time) +// Get a list of dates for user viewing purposes (formatted to their timezone, with date and start/end time) +// If start/end time is not needed, then only use the provided day // Should be used when events need to be populated/displayed export const getMeetingDates = (event: Event, startTimes: boolean = true) => { const times: Date[] = []; From 3303d4b3f7c809212b5b38c0cfe40b268b94643b Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 01:17:16 -0500 Subject: [PATCH 407/477] easir logic --- src/frontend/src/utils/calendar.utils.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 4d64fd6eb4..404020a82c 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -85,14 +85,14 @@ export const getMeetingDates = (event: Event, startTimes: boolean = true) => { // apply offset to get the true date of this specific event startDate.setDate(startDate.getDate() - offset); - // Note : schedule.startTime likely gets converted to the users timezone by default - // set the hour and minutes using UTC to match the adjusted date - startDate.setHours(specificTime?.getUTCHours() ?? 0); - startDate.setMinutes(specificTime?.getUTCMinutes() ?? 0); - // adjust for the users time const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); + // Note : schedule.startTime likely gets converted to the users timezone by default + // set the hour and minutes using UTC to match the adjusted date + startDateAdjusted.setHours(specificTime?.getHours() ?? 0); + startDateAdjusted.setMinutes(specificTime?.getMinutes() ?? 0); + // potentially needed to prevent extra events from showing up before the initial date times.push(startDateAdjusted); From 47540317ec601a5638f56f740855766ab219f5dc Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 01:17:29 -0500 Subject: [PATCH 408/477] comment fix --- src/frontend/src/utils/calendar.utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 404020a82c..f240723832 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -89,7 +89,6 @@ export const getMeetingDates = (event: Event, startTimes: boolean = true) => { const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); // Note : schedule.startTime likely gets converted to the users timezone by default - // set the hour and minutes using UTC to match the adjusted date startDateAdjusted.setHours(specificTime?.getHours() ?? 0); startDateAdjusted.setMinutes(specificTime?.getMinutes() ?? 0); From 1c9ac01c187e968ed07de5fd09693b380738558b Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 01:30:38 -0500 Subject: [PATCH 409/477] reversion --- src/frontend/src/utils/calendar.utils.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index f240723832..4d64fd6eb4 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -85,13 +85,14 @@ export const getMeetingDates = (event: Event, startTimes: boolean = true) => { // apply offset to get the true date of this specific event startDate.setDate(startDate.getDate() - offset); + // Note : schedule.startTime likely gets converted to the users timezone by default + // set the hour and minutes using UTC to match the adjusted date + startDate.setHours(specificTime?.getUTCHours() ?? 0); + startDate.setMinutes(specificTime?.getUTCMinutes() ?? 0); + // adjust for the users time const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); - // Note : schedule.startTime likely gets converted to the users timezone by default - startDateAdjusted.setHours(specificTime?.getHours() ?? 0); - startDateAdjusted.setMinutes(specificTime?.getMinutes() ?? 0); - // potentially needed to prevent extra events from showing up before the initial date times.push(startDateAdjusted); From 6b4a2e5adc29365384df5c2d483b02adf6708922 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 01:31:26 -0500 Subject: [PATCH 410/477] re-update --- src/frontend/src/utils/calendar.utils.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 4d64fd6eb4..9c97221c0f 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -79,17 +79,16 @@ export const getMeetingDates = (event: Event, startTimes: boolean = true) => { // this is done to ensure offset is properly calculated const startDate = new Date(startTimeDate.getTime() + timezoneOffset); + // set the hour and minutes using UTC to match the adjusted date + startDate.setHours(specificTime?.getUTCHours() ?? 0); + startDate.setMinutes(specificTime?.getUTCMinutes() ?? 0); + // Calculate offset based on the current day being checked const offset = startDate.getDay() - convertDayToInt(day); // apply offset to get the true date of this specific event startDate.setDate(startDate.getDate() - offset); - // Note : schedule.startTime likely gets converted to the users timezone by default - // set the hour and minutes using UTC to match the adjusted date - startDate.setHours(specificTime?.getUTCHours() ?? 0); - startDate.setMinutes(specificTime?.getUTCMinutes() ?? 0); - // adjust for the users time const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); From 7d0e6525d21039843c874fafddafe0d8ac9519bb Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 02:32:26 -0500 Subject: [PATCH 411/477] basic errors --- .../src/pages/NewCalendarPage/CalendarTab.tsx | 7 +- .../pages/NewCalendarPage/NewCalendarPage.tsx | 83 ++++++++++++++++++- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index ccd7915558..08471fb5ef 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -92,7 +92,12 @@ const CalendarTab: React.FC = () => { } > {tabIndex === 0 ? ( - + ) : ( = ({ allEventTypes, allCalendars }) => { +const NewCalendarPage: React.FC = ({ allEventTypes, yourEvents, reviewEvents, allCalendars }) => { const theme = useTheme(); const { data: allTeamTypes, @@ -64,10 +68,18 @@ const NewCalendarPage: React.FC = ({ allEventTypes, allCal statuses: [ConflictStatus.APPROVED, ConflictStatus.NO_CONFLICT] }); + const history = useHistory(); const [selectedEvent, setSelectedEvent] = useState(); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); const [openFilterModal, setOpenFilterModal] = useState(false); + const [pendingEvent, setPendingEvent] = useState( + yourEvents.filter((event) => event.approved === ConflictStatus.PENDING).length > 0 + ); + const [deniedEvent, setDeniedEvent] = useState( + yourEvents.filter((event) => event.approved === ConflictStatus.DENIED).length > 0 + ); + const [reviewEvent, setReviewEvent] = useState(reviewEvents.length > 0); const updateAdditionalTeamIds = (changed: boolean) => { setShowTeamEvents(changed); @@ -161,6 +173,73 @@ const NewCalendarPage: React.FC = ({ allEventTypes, allCal teamTypes={allTeamTypes} /> )} + + {deniedEvent && ( + } + variant="filled" + severity="error" + onClose={() => setDeniedEvent(false)} + > + An event that you scheduled conflicts with another event and has been denied. Please edit the event to put it + back up for re-approval, or to a time and location that does not conflict. + + )} + {pendingEvent && ( + } + variant="filled" + severity="error" + onClose={() => setPendingEvent(false)} + > + An event that you scheduled conflicts with another event. The event creator has been notified and must allow your + event to take place in order to continue. + + )} + {reviewEvent && ( + } + variant="filled" + severity="error" + onClose={() => setReviewEvent(false)} + > + + An event has been scheduled that conflicts with one of your own events. + + + + )} + From 78aaad2607ea01b2a75f138b34721aae34f68068 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 12:03:16 -0500 Subject: [PATCH 412/477] fun updates --- .../src/controllers/calendar.controllers.ts | 11 +++++ src/backend/src/routes/calendar.routes.ts | 2 + src/backend/src/services/calendar.services.ts | 45 ++++++++++++++++--- src/backend/src/utils/calendar.utils.ts | 23 +++++----- src/frontend/src/apis/calendar.api.ts | 6 +++ src/frontend/src/hooks/calendar.hooks.ts | 14 +++++- src/frontend/src/utils/urls.ts | 2 + 7 files changed, 86 insertions(+), 17 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 30b4528a90..a6da787466 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -454,6 +454,17 @@ export default class CalendarController { } } + static async getConflictingEvent(req: Request, res: Response, next: NextFunction) { + try { + const { eventId } = req.params; + + const event = await CalendarService.getConflictingEvent(req.currentUser, eventId, req.organization); + res.status(200).json(event); + } catch (error: unknown) { + next(error); + } + } + static async getAllEvents(req: Request, res: Response, next: NextFunction) { try { const events = await CalendarService.getAllEvents(req.organization); diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 1d7d77e2a6..754ee0e79e 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -163,6 +163,8 @@ calendarRouter.post( calendarRouter.post('/event/:eventId/delete', CalendarController.deleteEvent); +calendarRouter.get('/event/conflict/:eventId', CalendarController.getConflictingEvent); + calendarRouter.get('/event/:eventId', CalendarController.getSingleEvent); calendarRouter.get('/events', CalendarController.getAllEvents); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 2efd55d7ec..d4de19c4d9 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -404,7 +404,7 @@ export default class CalendarService { } // Check for conflicts - const { hasConflict, approverUserId } = await checkEventConflicts(scheduleSlot, organization, location, undefined); + const { hasConflict, conflictingEvent } = await checkEventConflicts(scheduleSlot, organization, location, undefined); const computeEndDate = (initial: Date, recurrenceNumber: number) => { const weeks = Math.max(1, recurrenceNumber ?? 0); @@ -462,7 +462,7 @@ export default class CalendarService { }, status: foundEventType.requiresConfirmation ? Event_Status.UNCONFIRMED : Event_Status.CONFIRMED, approved: hasConflict ? Conflict_Status.PENDING : Conflict_Status.NO_CONFLICT, - approvalRequiredFromUserId: hasConflict ? approverUserId : null, + approvalRequiredFromUserId: hasConflict ? conflictingEvent?.userCreated.userId : null, location, zoomLink, questionDocument, @@ -831,7 +831,7 @@ export default class CalendarService { let approverUserId: string | undefined; if (scheduleChanged || locationChanged) { - const { hasConflict: conflict, approverUserId: approver } = await checkEventConflicts( + const { hasConflict: conflict, conflictingEvent } = await checkEventConflicts( scheduleSlot, organization, location, @@ -839,7 +839,7 @@ export default class CalendarService { ); hasConflict = conflict; - approverUserId = approver; + approverUserId = conflictingEvent?.userCreated.userId; } if (scheduleChanged) { @@ -2285,7 +2285,7 @@ export default class CalendarService { * Retrieves a single event * * @param submitter the user who is trying to retrieve the event - * @param designReviewId the id of the event to retrieve + * @param eventId the id of the event to retrieve * @param organizationId the organization that the user is currently in * @returns the event */ @@ -2302,6 +2302,41 @@ export default class CalendarService { return eventTransformer(event); } + /** + * Retrieves a potential conflicting event + * If no conflict exists, returns the original event + * + * @param submitter the user who is trying to retrieve the event + * @param eventId the id of the event to retrieve + * @param organizationId the organization that the user is currently in + * @returns the event + */ + static async getConflictingEvent(_submitter: User, eventId: string, organization: Organization): Promise { + const event = await prisma.event.findUnique({ + where: { eventId }, + ...getEventQueryArgs(organization.organizationId) + }); + + if (!event) throw new NotFoundException('Event', eventId); + + if (event.dateDeleted) throw new DeletedException('Event', eventId); + + const transformedEvent = eventTransformer(event); + + const { hasConflict, conflictingEvent } = await checkEventConflicts( + transformedEvent.scheduledTimes, + organization, + transformedEvent.location, + transformedEvent.eventId + ); + + if (hasConflict && conflictingEvent) { + return conflictingEvent; + } + + return transformedEvent; + } + /** * Gets all events in the database * @param organizationId the organization id of the current user diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index 2b03e39837..0e6c845ffe 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -1,7 +1,10 @@ import { Prisma, Event_Type, Organization } from '@prisma/client'; -import { User, ScheduleSlotCreateArgs, Event } from 'shared'; +import { User, ScheduleSlotCreateArgs, Event, Team } from 'shared'; import { InvalidEventTypeConfigurationException } from './errors.utils'; import prisma from '../prisma/prisma'; +import teamTransformer from '../transformers/teams.transformer'; +import { getEventQueryArgs } from '../prisma-query-args/event.query-args'; +import { eventTransformer } from '../transformers/calendar.transformer'; export function buildScheduledTimesOverlap(start?: Date, end?: Date): Prisma.Schedule_SlotListRelationFilter | undefined { if (!start && !end) return undefined; @@ -113,7 +116,7 @@ export async function checkEventConflicts( organization: Organization, location?: string, eventId?: string -): Promise<{ hasConflict: boolean; approverUserId?: string }> { +): Promise<{ hasConflict: boolean; conflictingEvent?: Event }> { // No conflict if there's no location if (!location) { return { hasConflict: false }; @@ -134,12 +137,7 @@ export async function checkEventConflicts( organizationId: organization.organizationId } }, - include: { - scheduledTimes: true - }, - orderBy: { - dateCreated: 'asc' // Earlier events have priority - } + ...getEventQueryArgs(organization.organizationId) }); // Check each schedule slot against existing events @@ -163,12 +161,12 @@ export async function checkEventConflicts( // If both are all-day events, they conflict if (newSlot.allDay && existingSlot.allDay) { - return { hasConflict: true, approverUserId: event.userCreatedId }; + return { hasConflict: true, conflictingEvent: eventTransformer(event) }; } // If one is all-day and the other isn't, they conflict if (newSlot.allDay || existingSlot.allDay) { - return { hasConflict: true, approverUserId: event.userCreatedId }; + return { hasConflict: true, conflictingEvent: eventTransformer(event) }; } // Check time overlap (both have specific times) @@ -181,7 +179,10 @@ export async function checkEventConflicts( const timeOverlap = newStart < existingEnd && newEnd > existingStart; if (timeOverlap) { - return { hasConflict: true, approverUserId: event.userCreatedId }; + return { + hasConflict: true, + conflictingEvent: eventTransformer(event) + }; } } } diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 633a833816..3f590f0c79 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -125,6 +125,12 @@ export const getSingleEvent = async (id: string) => { }); }; +export const getConflictingEvent = async (id: string) => { + return axios.get(apiUrls.calendarGetConflictingEvent(id), { + transformResponse: (data) => eventTransformer(JSON.parse(data)) + }); +}; + export const postCreateEventType = (payload: EventTypeCreateArgs) => { return axios.post(apiUrls.calendarCreateEventType(), payload, { transformResponse: (data) => JSON.parse(data) as EventType diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index be0b340f86..092041444d 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -35,7 +35,8 @@ import { getAllEventTypes, postFilterEvents, approveEvent, - denyEvent + denyEvent, + getConflictingEvent } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; @@ -297,6 +298,17 @@ export const useSingleEvent = (id?: string) => { ); }; +export const useConflictingEvent = (id?: string) => { + return useQuery( + ['events', 'conflicting', id], + async () => { + const { data } = await getConflictingEvent(id!); + return data; + }, + { enabled: !!id } + ); +}; + export const useAllEvents = () => { return useQuery(['events'], async () => { const { data } = await getAllEvents(); diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 0d6df04be5..17cf7051a0 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -461,6 +461,7 @@ const calendarEditEventType = (eventTypeId: string) => `${calendar()}/event-type const calendarDeleteEventType = (eventTypeId: string) => `${calendar()}/event-type/${eventTypeId}/delete`; const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id}/confirm-schedule`; const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; +const calendarGetConflictingEvent = (id: string) => `${calendar()}/event/conflict/${id}`; const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; const calendarApproveEvent = (id: string) => `${calendar()}/event/${id}/approve`; @@ -779,6 +780,7 @@ export const apiUrls = { calendarEditShop, calendarEventMarkUserConfirmed, calendarGetSingleEvent, + calendarGetConflictingEvent, calendarEvents, calendarDeleteEvent, calendarEventSetStatus, From 3c3fea2015f12f8deef7acfd153f1606e72b898f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 12:58:50 -0500 Subject: [PATCH 413/477] getting things to work as intended --- src/backend/src/utils/calendar.utils.ts | 3 +- src/frontend/src/hooks/calendar.hooks.ts | 19 ++-- .../pages/NewCalendarPage/NewCalendarPage.tsx | 92 ++++++++++++++++--- 3 files changed, 93 insertions(+), 21 deletions(-) diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index 0e6c845ffe..b7b5bf07e9 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -1,5 +1,5 @@ import { Prisma, Event_Type, Organization } from '@prisma/client'; -import { User, ScheduleSlotCreateArgs, Event, Team } from 'shared'; +import { User, ScheduleSlotCreateArgs, Event, Team, ConflictStatus } from 'shared'; import { InvalidEventTypeConfigurationException } from './errors.utils'; import prisma from '../prisma/prisma'; import teamTransformer from '../transformers/teams.transformer'; @@ -133,6 +133,7 @@ export async function checkEventConflicts( eventId: eventId ? { not: eventId } : undefined, // Exclude current event if editing location, dateDeleted: null, + approved: { in: [ConflictStatus.APPROVED, ConflictStatus.NO_CONFLICT] }, eventType: { organizationId: organization.organizationId } diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 092041444d..e62d13e371 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -298,15 +298,16 @@ export const useSingleEvent = (id?: string) => { ); }; -export const useConflictingEvent = (id?: string) => { - return useQuery( - ['events', 'conflicting', id], - async () => { - const { data } = await getConflictingEvent(id!); - return data; - }, - { enabled: !!id } - ); +export const useConflictingEvents = (ids: string[]) => { + return useQuery(['events', 'conflicting', ids], async () => { + const results = await Promise.all( + ids.map(async (id) => { + const { data } = await getConflictingEvent(id); + return data; + }) + ); + return results; + }); }; export const useAllEvents = () => { diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index c7184d7313..bf1e832c67 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -2,13 +2,13 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { useState } from 'react'; +import { useMemo, useState } from 'react'; import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button, Alert, Snackbar } from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { Calendar, ConflictStatus, DayOfWeek, Event, EventType } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; -import { useFilterEvents } from '../../hooks/calendar.hooks'; +import { useConflictingEvents, useFilterEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; @@ -42,7 +42,6 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv const [memberIds, setMemberIds] = useState([]); const [teamIds, setTeamIds] = useState([]); - const [showInvitedEvents, setShowInvitedEvents] = useState(true); const [showTeamEvents, setShowTeamEvents] = useState(true); @@ -81,6 +80,28 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv ); const [reviewEvent, setReviewEvent] = useState(reviewEvents.length > 0); + const filteredToPending = yourEvents + .filter((event) => event.approved === ConflictStatus.PENDING) + .map((event) => event.eventId); + + const filteredToDenied = yourEvents + .filter((event) => event.approved === ConflictStatus.DENIED) + .map((event) => event.eventId); + + const { + data: conflictingEvents, + isLoading: conflictingEventsLoading, + isError: conflictingEventsIsError, + error: conflictingEventsError + } = useConflictingEvents(filteredToPending); + + const { + data: conflictingDeniedEvents, + isLoading: conflictingDeniedEventsLoading, + isError: conflictingDeniedEventsIsError, + error: conflictingDeniedEventsError + } = useConflictingEvents(filteredToDenied); + const updateAdditionalTeamIds = (changed: boolean) => { setShowTeamEvents(changed); @@ -101,10 +122,30 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv } }; - if (isLoading || !allEvents) return ; + const yourConflicts = useMemo( + () => conflictingEvents?.filter((event, i) => filteredToPending[i] !== event.eventId) ?? [], + [conflictingEvents, filteredToPending] + ); - if (isLoading || !allEvents) return ; + const yourConflictsDenied = useMemo( + () => conflictingDeniedEvents?.filter((event, i) => filteredToDenied[i] !== event.eventId) ?? [], + [conflictingDeniedEvents, filteredToDenied] + ); + + if ( + isLoading || + !allEvents || + conflictingEventsLoading || + !conflictingEvents || + conflictingEventsLoading || + !conflictingEvents || + conflictingDeniedEventsLoading || + !conflictingDeniedEvents + ) + return ; if (isError) return ; + if (conflictingEventsIsError) return ; + if (conflictingDeniedEventsIsError) return ; const transformedEvents = allEvents.map(filterEventTransformer); @@ -186,13 +227,39 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv > {deniedEvent && ( } + icon={} variant="filled" severity="error" - onClose={() => setDeniedEvent(false)} + onClose={() => setReviewEvent(false)} > - An event that you scheduled conflicts with another event and has been denied. Please edit the event to put it - back up for re-approval, or to a time and location that does not conflict. + + + {' '} + You have scheduled an event at the same time and location as {yourConflicts[0].title} and was denied. + Edit the event to put it up for re-approval, or change the time/location to not conflict with other events. + + + )} {pendingEvent && ( @@ -202,8 +269,11 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv severity="error" onClose={() => setPendingEvent(false)} > - An event that you scheduled conflicts with another event. The event creator has been notified and must allow your - event to take place in order to continue. + You have scheduled an event at the same time and location as {yourConflicts[0].title}.{' '} + + {yourConflicts[0].userCreated.firstName} {yourConflicts[0].userCreated.lastName} + {' '} + has been notified of this and must allow your event to take place in order to continue. )} {reviewEvent && ( From 02c10ab36ba8eb0444cb7a787d22b34227b2f58e Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Wed, 17 Dec 2025 20:56:25 -0500 Subject: [PATCH 414/477] better review warnings --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 49 ++++++++++++++++--- src/frontend/src/utils/calendar.utils.ts | 28 +++++++++++ 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index bf1e832c67..6723eda99d 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -3,7 +3,7 @@ * See the LICENSE file in the repository root folder for details. */ import { useMemo, useState } from 'react'; -import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button, Alert, Snackbar } from '@mui/material'; +import { Box, Grid, Stack, Typography, useMediaQuery, useTheme, Button, Alert } from '@mui/material'; import PageLayout from '../../components/PageLayout'; import { Calendar, ConflictStatus, DayOfWeek, Event, EventType } from 'shared'; import CalendarDayCard from './CalendarDayCard'; @@ -19,7 +19,7 @@ import FilterModal from './FilterModal'; import { DateCalendar } from '@mui/x-date-pickers'; import { useCurrentUser } from '../../hooks/users.hooks'; import { useGetUsersTeams } from '../../hooks/teams.hooks'; -import { convertIntToDay, getMeetingDates } from '../../utils/calendar.utils'; +import { convertIntToDay, getMeetingDates, getOverlapTime } from '../../utils/calendar.utils'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; import WarningIcon from '@mui/icons-material/Warning'; import { useHistory } from 'react-router-dom'; @@ -75,10 +75,14 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv const [pendingEvent, setPendingEvent] = useState( yourEvents.filter((event) => event.approved === ConflictStatus.PENDING).length > 0 ); + const [deniedEvent, setDeniedEvent] = useState( yourEvents.filter((event) => event.approved === ConflictStatus.DENIED).length > 0 ); - const [reviewEvent, setReviewEvent] = useState(reviewEvents.length > 0); + + const [reviewEvent, setReviewEvent] = useState( + reviewEvents.filter((event) => event.approvalRequiredFrom?.userId === user.userId).length > 0 + ); const filteredToPending = yourEvents .filter((event) => event.approved === ConflictStatus.PENDING) @@ -102,6 +106,16 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv error: conflictingDeniedEventsError } = useConflictingEvents(filteredToDenied); + const yourReviewEvents = reviewEvents.filter((event) => event.approvalRequiredFrom?.userId === user.userId); + const { + data: untransformedConflictingReviewEvents, + isLoading: conflictingReviewEventsLoading, + isError: conflictingReviewEventsIsError, + error: conflictingReviewEventsError + } = useConflictingEvents(yourReviewEvents.map((event) => event.eventId)); + + const conflictingReviewEvents = untransformedConflictingReviewEvents?.map(filterEventTransformer); + const updateAdditionalTeamIds = (changed: boolean) => { setShowTeamEvents(changed); @@ -140,12 +154,15 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv conflictingEventsLoading || !conflictingEvents || conflictingDeniedEventsLoading || - !conflictingDeniedEvents + !conflictingDeniedEvents || + conflictingReviewEventsLoading || + !conflictingReviewEvents ) return ; if (isError) return ; if (conflictingEventsIsError) return ; if (conflictingDeniedEventsIsError) return ; + if (conflictingReviewEventsIsError) return ; const transformedEvents = allEvents.map(filterEventTransformer); @@ -230,13 +247,14 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv icon={} variant="filled" severity="error" - onClose={() => setReviewEvent(false)} + onClose={() => setDeniedEvent(false)} > {' '} - You have scheduled an event at the same time and location as {yourConflicts[0].title} and was denied. - Edit the event to put it up for re-approval, or change the time/location to not conflict with other events. + You have scheduled an event at the same time and location as {yourConflictsDenied[0].title} and was + denied. Edit the event to put it up for re-approval, or change the time/location to not conflict with other + events. + + + My Upcoming Meetings: + - - My Upcoming Meetings: - + {upcomingOccurences && ( + + {upcomingOccurences?.map((event) => ( + + ))} + + )} + {/* Calendar Selector */} + + + t.typography.h4.fontFamily, + fontWeight: 400, + fontSize: 22 + }} + > + Calendars: + - {upcomingOccurences && ( - - {upcomingOccurences?.map((event) => ( - - ))} + + + + {calendars.length > 0 && ( + + {calendars.map((cal) => { + const { calendarId, color } = cal; + const checked = selectedCalendarIds.includes(calendarId); + return ( + toggleCalendar(calendarId)} + icon={} + checkedIcon={} + sx={{ + p: 0.5, + color, + '&.Mui-checked': { color } + }} + /> + } + label={ + t.typography.h6.fontFamily, + fontSize: 16, + color, + fontWeight: 500 + }} + > + {cal.name} + + } + /> + ); + })} + + )} - )} + From c5dcf8fcf0f621e12d2b99f72fb9c1aa5d2fcd1c Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 29 Dec 2025 16:01:28 -0500 Subject: [PATCH 433/477] lint --- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 2f223121c0..668c8a9f16 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -2,7 +2,7 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { useEffect, useMemo, useState, useRef } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { Box, Grid, From ad309c2ed0be3c9c7f61e04282651160b88d0d84 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 29 Dec 2025 16:20:47 -0500 Subject: [PATCH 434/477] accidentally removed a feature in a prior merge, oops --- .../pages/NewCalendarPage/NewCalendarPage.tsx | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 668c8a9f16..feb040b941 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -41,6 +41,7 @@ import { useHistory } from 'react-router-dom'; import UpcomingMeetingsCard from './UpcomingMeetingsCard'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked'; +import SchedulingConflictsWarning from './SchedulingConflictsWarning'; interface NewCalendarPageProps { allEventTypes: EventType[]; @@ -88,14 +89,17 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv } }, [allTeams, teamList, additionalTeamIds.length, showTeamEvents]); + const startPeriod = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, 15); + const endPeriod = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15); + const { isLoading, isError, error, data: allEvents } = useFilterEvents({ - startPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, 15), - endPeriod: new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 15), + startPeriod, + endPeriod, memberIds: memberIds.concat(additionalMemberIds), teamIds: teamIds.concat(additionalTeamIds), statuses: [ConflictStatus.APPROVED, ConflictStatus.NO_CONFLICT], @@ -151,9 +155,9 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv const { mutateAsync: createEvent } = useCreateEvent(); const { isLoading: documentsIsLoading, mutateAsync: uploadDocuments } = useUploadManyDocuments(); - const [startPeriod] = useState(() => new Date()); + const [upcomingStartPeriod] = useState(() => new Date()); - const [endPeriod] = useState(() => { + const [upcomingEndPeriod] = useState(() => { const d = new Date(); d.setDate(d.getDate() + 7); d.setHours(23, 59, 59, 999); @@ -161,13 +165,15 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv }); const { data: upcomingEvents } = useFilterEvents({ - startPeriod, - endPeriod, + startPeriod: upcomingStartPeriod, + endPeriod: upcomingEndPeriod, memberIds: memberIds.concat(additionalMemberIds), teamIds: teamIds.concat(additionalTeamIds) }); - const upcomingOccurences = upcomingEvents ? getEventsFlattened(upcomingEvents, startPeriod, endPeriod) : []; + const upcomingOccurences = upcomingEvents + ? getEventsFlattened(upcomingEvents, upcomingStartPeriod, upcomingEndPeriod) + : []; const toggleCalendar = (calendarId: string) => { setSelectedCalendarIds((prev) => @@ -570,6 +576,12 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv } }} /> + My Upcoming Meetings: @@ -628,7 +640,8 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv '&:hover': { borderColor: 'white', backgroundColor: 'rgba(255, 255, 255, 0.1)' - } + }, + mb: 2 }} > More Filters From 9a7b9caa6de551453c560f6e4b0fa5c029beac1f Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Mon, 29 Dec 2025 20:18:08 -0500 Subject: [PATCH 435/477] ideas --- .../AvailabilityScheduleView.tsx | 87 ++++++++++++++----- .../Components/EventAvailabilityPage.tsx | 4 +- .../Components/EventTimeSlot.tsx | 29 +++++++ 3 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx index d019b2c52d..38041919e0 100644 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx @@ -1,4 +1,4 @@ -import { Grid } from '@mui/material'; +import { Grid, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; import { Availability, Event, getDayOfWeek, getNextSevenDays, User } from 'shared'; import { enumToArray, @@ -10,6 +10,7 @@ import { import TimeSlot from '../../../components/TimeSlot'; import React, { useState } from 'react'; import { datePipe } from '../../../utils/pipes'; +import EventTimeSlot from '../../NewCalendarPage/Components/EventTimeSlot'; interface AvailabilityScheduleViewProps { availableUsers: Map; @@ -80,30 +81,68 @@ const AvailabilityScheduleView: React.FC = ({ unavailableUsers.set(time, currentUnavailableUsers); } + const stickyLeft = { + position: 'sticky', + left: 0, + zIndex: 2, + bgcolor: 'background.paper' + }; + return ( - - - {potentialDays.map((day) => ( - - ))} - {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( - - - {potentialDays.map((day, dayIndex) => { - const index = dayIndex * enumToArray(REVIEW_TIMES).length + timeIndex; - return ( - handleTimeslotClick(index, day)} - icon={existingMeetingData.get(index)} - /> - ); - })} - - ))} - + + + + + + {potentialDays.map((day) => ( + + + {getDayOfWeek(day) + ' ' + datePipe(day)} + + + ))} + + + + {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( + + + + {time} + + + {potentialDays.map((day, dayIndex) => { + const index = dayIndex * enumToArray(REVIEW_TIMES).length + timeIndex; + return ( + + handleTimeslotClick(index, day)} + /> + + ); + })} + + ))} + +
+
); }; diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx index d81a940cd6..5473bc7974 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx @@ -266,7 +266,7 @@ export const EventAvailabilityPage: React.FC = () => { Available - + {currentAvailableUsers.length > 0 ? ( currentAvailableUsers.map((user) => ( @@ -286,7 +286,7 @@ export const EventAvailabilityPage: React.FC = () => { Unavailable - + {currentUnavailableUsers.length > 0 ? ( currentUnavailableUsers.map((user) => ( diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx new file mode 100644 index 0000000000..26603173a7 --- /dev/null +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx @@ -0,0 +1,29 @@ +import { Box } from '@mui/system'; + +interface EventTimeSlotProps { + backgroundColor?: string; + onClick?: () => void; + selected?: boolean; +} + +const EventTimeSlot: React.FC = ({ backgroundColor, onClick, selected = false }) => { + return ( + + + + ); +}; + +export default EventTimeSlot; From 249871c253c9c3f661ad348cbfea9357542650b6 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 30 Dec 2025 19:31:16 -0500 Subject: [PATCH 436/477] #3818 bug fixes --- .../AvailabilityScheduleView.tsx | 10 ++-- .../EventDetailPage/AvailabilityView.tsx | 14 ------ .../EventDetailPage/EventDetailPage.tsx | 3 -- .../Components/EventAvailabilityPage.tsx | 46 +++++++++---------- .../Availability/SingleAvailabilityModal.tsx | 15 +++++- .../Availability/SingleAvailabilityView.tsx | 20 ++++++-- 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx index d019b2c52d..02b1522f24 100644 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx @@ -18,7 +18,6 @@ interface AvailabilityScheduleViewProps { existingMeetingData: Map; setCurrentAvailableUsers: (val: User[]) => void; setCurrentUnavailableUsers: (val: User[]) => void; - onSelectedTimeslotChanged: (val: number | null, day: Date | null) => void; dateRangeTitle: string; event: Event; displayDate?: Date; @@ -32,7 +31,6 @@ const AvailabilityScheduleView: React.FC = ({ setCurrentAvailableUsers, setCurrentUnavailableUsers, dateRangeTitle, - onSelectedTimeslotChanged, event, displayDate }) => { @@ -42,18 +40,16 @@ const AvailabilityScheduleView: React.FC = ({ const initialDate = displayDate || event.scheduledTimes[0]?.initialDateScheduled || new Date(); const potentialDays = getNextSevenDays(initialDate); - const handleTimeslotClick = (index: number, day: Date) => { + const handleTimeslotClick = (index: number, _day: Date) => { if (selectedTimeslot === index) { - setSelectedTimeslot(null); // unselect + setSelectedTimeslot(null); setCurrentAvailableUsers([]); setCurrentUnavailableUsers([]); } else { - setSelectedTimeslot(index); // select + setSelectedTimeslot(index); setCurrentAvailableUsers(availableUsers.get(index) || []); setCurrentUnavailableUsers(unavailableUsers.get(index) || []); } - - onSelectedTimeslotChanged(index, day); }; // Populates the availableUsers map diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx index b04d835b2e..e4b1563da4 100644 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx @@ -15,11 +15,8 @@ interface AvailabilityViewProps { allEvents: Event[]; handleEdit: (data?: FinalizeEventInformation) => void; selectedDate: Date; - setSelectDate: (date: Date) => void; startTime: number; endTime: number; - setStartTime: (time: number) => void; - setEndTime: (time: number) => void; requiredUserIds: string[]; optionalUserIds: string[]; } @@ -29,11 +26,8 @@ const AvailabilityView: React.FC = ({ allEvents, handleEdit, selectedDate, - setSelectDate, startTime, endTime, - setStartTime, - setEndTime, requiredUserIds, optionalUserIds }) => { @@ -68,13 +62,6 @@ const AvailabilityView: React.FC = ({ return drDate >= startRange && drDate <= endRange; }); - const onSelectedTimeslotChanged = (index: number | null, day: Date | null) => { - if (index === null || day === null) return; - setStartTime(index); - setEndTime(index + 1); - setSelectDate(day); - }; - // Find conflicting events for the selected time const conflictingEvents = allEvents.filter((currEvent) => { if (currEvent.eventId === event.eventId) return false; @@ -131,7 +118,6 @@ const AvailabilityView: React.FC = ({ setCurrentAvailableUsers={setCurrentAvailableUsers} setCurrentUnavailableUsers={setCurrentUnavailableUsers} dateRangeTitle={dateRangePipe(startDateRange, endDateRange)} - onSelectedTimeslotChanged={onSelectedTimeslotChanged} event={event} />
diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx index 76ed2f963a..ba8c7f0c52 100644 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx @@ -299,13 +299,10 @@ const EventDetailPage: React.FC = ({ event }) => { event={event} allEvents={allEvents} selectedDate={date} - setSelectDate={setDate} requiredUserIds={requiredUsers.map((user) => user.id)} optionalUserIds={optionalUsers.map((user) => user.id)} startTime={startTime} endTime={endTime} - setStartTime={setStartTime} - setEndTime={setEndTime} /> ); diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx index d81a940cd6..47d8726883 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx @@ -71,14 +71,12 @@ export const EventAvailabilityPage: React.FC = () => { const toast = useToast(); const currentUser = useCurrentUser(); - // ALL STATE HOOKS const [editAvailabilityOpen, setEditAvailabilityOpen] = useState(false); const [viewAvailabilityOpen, setViewAvailabilityOpen] = useState(false); const [confirmedAvailabilities, setConfirmedAvailabilities] = useState>(new Map()); const [currentAvailableUsers, setCurrentAvailableUsers] = useState([]); const [currentUnavailableUsers, setCurrentUnavailableUsers] = useState([]); - // ALL DATA FETCHING HOOKS const { data: event, isError: eventError, error: eventErrorMsg, isLoading: eventLoading } = useSingleEvent(eventId); const { @@ -88,7 +86,6 @@ export const EventAvailabilityPage: React.FC = () => { error: settingsError } = useUserScheduleSettings(currentUser.userId); - // Get ALL user IDs who should be shown in team availability const allRelevantUserIds = useMemo(() => { if (!event) return []; @@ -127,10 +124,8 @@ export const EventAvailabilityPage: React.FC = () => { error: usersErrorMsg } = useManyUsersWithScheduleSettings(allRelevantUserIds); - // MUTATION HOOK const { mutateAsync: markUserConfirmed } = useMarkUserConfirmed(eventId); - // COMPUTED VALUES WITH USEMEMO const displayDate = useMemo(() => { if (dateParam) { return new Date(dateParam); @@ -144,7 +139,6 @@ export const EventAvailabilityPage: React.FC = () => { return isUserOnEvent(currentUser, event); }, [currentUser, event]); - // EFFECTS useEffect(() => { if (userScheduleSettings && userScheduleSettings.availabilities.length > 0) { const confirmed = getMostRecentAvailabilities(userScheduleSettings.availabilities, displayDate); @@ -154,7 +148,6 @@ export const EventAvailabilityPage: React.FC = () => { } }, [userScheduleSettings, displayDate]); - // NOW CONDITIONAL RETURNS - AFTER ALL HOOKS if (eventLoading || !event) return ; if (eventError) return ; @@ -164,11 +157,9 @@ export const EventAvailabilityPage: React.FC = () => { if (usersLoading || !relevantUsers) return ; if (usersError) return ; - // COMPUTED VALUES (after conditional returns) const workPackageNames = event.workPackages.map((wp) => wp.wbsElement.name).join(', ') || event.title; const editModalTitle = `Update your availability for ${workPackageNames} on the week of ${displayDate.toLocaleDateString()}`; - // EVENT HANDLERS const handleConfirm = async () => { try { await markUserConfirmed({ availability: Array.from(confirmedAvailabilities.values()) }); @@ -185,12 +176,6 @@ export const EventAvailabilityPage: React.FC = () => { history.push(routes.NEW_CALENDAR); }; - const onSelectedTimeslotChanged = (_index: number | null, _day: Date | null) => { - // This is called when a timeslot is clicked in the heatmap - // The component already updates currentAvailableUsers and currentUnavailableUsers - }; - - // BUILD AVAILABILITY MAPS const availableUsers = new Map(); const unavailableUsers = new Map(); const usersToAvailabilities = new Map(); @@ -218,10 +203,18 @@ export const EventAvailabilityPage: React.FC = () => { return ( - {/* Top Row - Side by Side */} {/* My Availability Section */} - + My Availability @@ -249,8 +242,16 @@ export const EventAvailabilityPage: React.FC = () => { - {/* Team Availability Summary */} - + {eventNamePipe(event)} Availability @@ -261,7 +262,6 @@ export const EventAvailabilityPage: React.FC = () => { - {/* Available Users */} Available @@ -281,7 +281,6 @@ export const EventAvailabilityPage: React.FC = () => { - {/* Unavailable Users */} Unavailable @@ -304,7 +303,6 @@ export const EventAvailabilityPage: React.FC = () => { - {/* Full Width Heatmap Below */} { setCurrentAvailableUsers={setCurrentAvailableUsers} setCurrentUnavailableUsers={setCurrentUnavailableUsers} dateRangeTitle={dateRangeTitle} - onSelectedTimeslotChanged={onSelectedTimeslotChanged} event={event} displayDate={displayDate} /> @@ -323,17 +320,16 @@ export const EventAvailabilityPage: React.FC = () => { - {/* Action Buttons */} Close - {/* Modals */} setViewAvailabilityOpen(false)} header="My Availability" availabilites={userScheduleSettings.availabilities} + initialDate={displayDate} /> void; + initialDate?: Date; } -const SingleAvailabilityModal: React.FC = ({ open, onHide, header, availabilites }) => { +const SingleAvailabilityModal: React.FC = ({ + open, + onHide, + header, + availabilites, + initialDate +}) => { const existingMeetingData = new Map }>(); return ( - + ); }; diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx index 6ef266f6e5..d308c9268b 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx @@ -3,16 +3,30 @@ import { HeatmapColors, enumToArray, REVIEW_TIMES, ExistingMeetingData } from '. import TimeSlot from '../../../../components/TimeSlot'; import { Availability, getDayOfWeek, getMostRecentAvailabilities } from 'shared'; import { datePipe } from '../../../../utils/pipes'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import NERArrows from '../../../../components/NERArrows'; interface SingleAvailabilityViewProps { totalAvailability: Availability[]; existingMeetingData: ExistingMeetingData; + initialDate?: Date; } -const SingleAvailabilityView: React.FC = ({ totalAvailability, existingMeetingData }) => { - const [startDate, setStartDate] = useState(new Date()); +const SingleAvailabilityView: React.FC = ({ + totalAvailability, + existingMeetingData, + initialDate +}) => { + // Use initialDate if provided, otherwise default to today + const [startDate, setStartDate] = useState(initialDate || new Date()); + + // Update startDate when initialDate changes + useEffect(() => { + if (initialDate) { + setStartDate(initialDate); + } + }, [initialDate]); + const selectedTimes = getMostRecentAvailabilities(totalAvailability, startDate); const onArrowIncrease = () => { From 87e010dcaab150641feecc3d561b6867e7bde8af Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 30 Dec 2025 20:23:24 -0500 Subject: [PATCH 437/477] #3818 ui changes --- .../AvailabilityScheduleView.tsx | 15 +- .../EventDetailPage/AvailabilityView.tsx | 3 - .../Components/EventAvailabilityPage.tsx | 5 - .../Components/EventTimeSlot.tsx | 18 ++- .../Availability/AvailabilityEditModal.tsx | 4 +- .../Availability/EditAvailability.tsx | 153 ++++++++++-------- .../Availability/SingleAvailabilityModal.tsx | 18 ++- .../Availability/SingleAvailabilityView.tsx | 121 +++++++++----- 8 files changed, 191 insertions(+), 146 deletions(-) diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx index ba9d20e2e0..37ad0201b0 100644 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx @@ -1,13 +1,6 @@ -import { Grid, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; +import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; import { Availability, Event, getDayOfWeek, getNextSevenDays, User } from 'shared'; -import { - enumToArray, - REVIEW_TIMES, - HeatmapColors, - getBackgroundColor, - NUMBER_OF_TIME_SLOTS -} from '../../../utils/design-review.utils'; -import TimeSlot from '../../../components/TimeSlot'; +import { enumToArray, REVIEW_TIMES, getBackgroundColor, NUMBER_OF_TIME_SLOTS } from '../../../utils/design-review.utils'; import React, { useState } from 'react'; import { datePipe } from '../../../utils/pipes'; import EventTimeSlot from '../../NewCalendarPage/Components/EventTimeSlot'; @@ -16,10 +9,8 @@ interface AvailabilityScheduleViewProps { availableUsers: Map; unavailableUsers: Map; usersToAvailabilities: Map; - existingMeetingData: Map; setCurrentAvailableUsers: (val: User[]) => void; setCurrentUnavailableUsers: (val: User[]) => void; - dateRangeTitle: string; event: Event; displayDate?: Date; } @@ -28,10 +19,8 @@ const AvailabilityScheduleView: React.FC = ({ availableUsers, unavailableUsers, usersToAvailabilities, - existingMeetingData, setCurrentAvailableUsers, setCurrentUnavailableUsers, - dateRangeTitle, event, displayDate }) => { diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx index e4b1563da4..12ed72d152 100644 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx @@ -4,7 +4,6 @@ import { useState } from 'react'; import AvailabilityScheduleView from './AvailabilityScheduleView'; import UserAvailabilites from './UserAvailabilitesView'; import { getWeekDateRange } from '../../../utils/design-review.utils'; -import { dateRangePipe } from '../../../utils/pipes'; import { FinalizeEventInformation } from './EventDetailPage'; import { useManyUsersWithScheduleSettings } from '../../../hooks/users.hooks'; import LoadingIndicator from '../../../components/LoadingIndicator'; @@ -114,10 +113,8 @@ const AvailabilityView: React.FC = ({ availableUsers={availableUsers} unavailableUsers={unavailableUsers} usersToAvailabilities={usersToAvailabilities} - existingMeetingData={existingMeetingData} setCurrentAvailableUsers={setCurrentAvailableUsers} setCurrentUnavailableUsers={setCurrentUnavailableUsers} - dateRangeTitle={dateRangePipe(startDateRange, endDateRange)} event={event} /> diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx index 22dd460167..9dc460603f 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx @@ -179,15 +179,12 @@ export const EventAvailabilityPage: React.FC = () => { const availableUsers = new Map(); const unavailableUsers = new Map(); const usersToAvailabilities = new Map(); - const existingMeetingData = new Map(); relevantUsers.forEach((user: UserWithScheduleSettings) => { const availability = getMostRecentAvailabilities(user.scheduleSettings?.availabilities ?? [], displayDate); usersToAvailabilities.set(user, availability ?? []); }); - const dateRangeTitle = `Week of ${displayDate.toLocaleDateString()}`; - const getAvailabilitySummary = () => { if (confirmedAvailabilities.size === 0) { return 'No availability set yet. Click "Edit My Availability" to get started.'; @@ -309,10 +306,8 @@ export const EventAvailabilityPage: React.FC = () => { availableUsers={availableUsers} unavailableUsers={unavailableUsers} usersToAvailabilities={usersToAvailabilities} - existingMeetingData={existingMeetingData} setCurrentAvailableUsers={setCurrentAvailableUsers} setCurrentUnavailableUsers={setCurrentUnavailableUsers} - dateRangeTitle={dateRangeTitle} event={event} displayDate={displayDate} /> diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx index 26603173a7..386e447eae 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx @@ -4,11 +4,21 @@ interface EventTimeSlotProps { backgroundColor?: string; onClick?: () => void; selected?: boolean; + onMouseDown?: (e: React.MouseEvent) => void; + onMouseEnter?: (e: React.MouseEvent) => void; + onMouseUp?: () => void; } -const EventTimeSlot: React.FC = ({ backgroundColor, onClick, selected = false }) => { +const EventTimeSlot: React.FC = ({ + backgroundColor, + onClick, + selected = false, + onMouseDown, + onMouseEnter, + onMouseUp +}) => { return ( - + = ({ backgroundColor, onClick, display: 'flex', borderStyle: 'solid', borderColor: selected ? '#ffff8c' : 'gray', - borderWidth: selected ? '2px' : '0.1px' + borderWidth: selected ? '2px' : '0.1px', + userSelect: 'none', // Prevent text selection while dragging + cursor: 'pointer' }} /> diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal.tsx index bd0f39c29e..e4c270eb97 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal.tsx @@ -25,7 +25,6 @@ const AvailabilityEditModal: React.FC = ({ initialDate, canChangeDateRange = true }) => { - const existingMeetingData = new Map }>(); const onCancel = () => { setConfirmedAvailabilities(new Map()); onHide(); @@ -38,12 +37,11 @@ const AvailabilityEditModal: React.FC = ({ title={header} onSubmit={onSubmit} submitText="Save" - paperProps={{ maxWidth: '900px', maxHeight: '680px' }} + paperProps={{ maxWidth: '1200px', maxHeight: '680px' }} > ; setEditedAvailabilities: (val: Map) => void; - existingMeetingData: ExistingMeetingData; totalAvailabilities: Availability[]; initialDate: Date; canChangeDateRange?: boolean; @@ -20,28 +19,21 @@ const EditAvailability: React.FC = ({ editedAvailabilities, totalAvailabilities, setEditedAvailabilities, - existingMeetingData, initialDate, canChangeDateRange = true }) => { const [currentlyDisplayedAvailabilities, setCurrentlyDisplayedAvailabilities] = useState(() => { const availabilities = Array.from(editedAvailabilities.values()); if (availabilities.length === 0) { - const defaultAvailabilities: Availability[] = []; - for (let i = 0; i < 7; i++) { - const date = addDaysToDate(initialDate, i); - defaultAvailabilities.push({ - dateSet: date, - availability: [] - }); - } + // Load existing availabilities instead of creating empty ones + const existingForWeek = getMostRecentAvailabilities(totalAvailabilities, initialDate); - defaultAvailabilities.forEach((availability) => { + existingForWeek.forEach((availability) => { editedAvailabilities.set(availability.dateSet.getTime(), availability); }); setEditedAvailabilities(editedAvailabilities); - return defaultAvailabilities; + return existingForWeek; } return availabilities; }); @@ -50,9 +42,7 @@ const EditAvailability: React.FC = ({ const handleMouseDown = (event: any, availability: Availability, selectedTime: number) => { event.preventDefault(); - toggleTimeSlot(availability, selectedTime); - setIsDragging(true); }; @@ -119,62 +109,91 @@ const EditAvailability: React.FC = ({ setCurrentlyDisplayedAvailabilities(getMostRecentAvailabilities(Array.from(editedAvailabilities.values()), initialDate)); }; + const stickyLeft = { + position: 'sticky', + left: 0, + zIndex: 2, + bgcolor: 'background.paper' + }; + return ( - - - - Available times in green - - + + + Available times in green + Invert Availability - - - {currentlyDisplayedAvailabilities.map((availability) => ( - - {getDayOfWeek(availability.dateSet)}
{datePipe(availability.dateSet)} - - } - /> - ))} - {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( - - - {currentlyDisplayedAvailabilities.map((availability, dayIndex) => { - const backgroundColor = availability.availability.includes(timeIndex) ? HeatmapColors[3] : HeatmapColors[0]; - return ( - handleMouseDown(e, availability, timeIndex)} - onMouseEnter={(e) => handleMouseEnter(e, availability, timeIndex)} - onMouseUp={handleMouseUp} - icon={existingMeetingData.get(dayIndex)?.iconMap.get(timeIndex)} - /> - ); - })} - - ))} +
+ + + + + + + {currentlyDisplayedAvailabilities.map((availability, idx) => ( + + + {getDayOfWeek(availability.dateSet)} +
+ {datePipe(availability.dateSet)} +
+
+ ))} +
+
+ + {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( + + + + {time} + + + {currentlyDisplayedAvailabilities.map((availability, dayIndex) => { + const isAvailable = availability.availability.includes(timeIndex); + return ( + + handleMouseDown(e, availability, timeIndex)} + onMouseEnter={(e) => handleMouseEnter(e, availability, timeIndex)} + onMouseUp={handleMouseUp} + /> + + ); + })} + + ))} + +
+
+ {canChangeDateRange && ( - + - +
)} - + ); }; diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityModal.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityModal.tsx index 88877b3525..3426338706 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityModal.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityModal.tsx @@ -17,15 +17,17 @@ const SingleAvailabilityModal: React.FC = ({ availabilites, initialDate }) => { - const existingMeetingData = new Map }>(); - return ( - - + + ); }; diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx index d308c9268b..e060e3859f 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx @@ -1,26 +1,19 @@ -import { Box, Grid } from '@mui/material'; -import { HeatmapColors, enumToArray, REVIEW_TIMES, ExistingMeetingData } from '../../../../utils/design-review.utils'; -import TimeSlot from '../../../../components/TimeSlot'; +import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; import { Availability, getDayOfWeek, getMostRecentAvailabilities } from 'shared'; import { datePipe } from '../../../../utils/pipes'; -import { useEffect, useState } from 'react'; +import { useState, useEffect } from 'react'; import NERArrows from '../../../../components/NERArrows'; +import { enumToArray, REVIEW_TIMES, getBackgroundColor } from '../../../../utils/design-review.utils'; +import EventTimeSlot from '../../../NewCalendarPage/Components/EventTimeSlot'; interface SingleAvailabilityViewProps { totalAvailability: Availability[]; - existingMeetingData: ExistingMeetingData; initialDate?: Date; } -const SingleAvailabilityView: React.FC = ({ - totalAvailability, - existingMeetingData, - initialDate -}) => { - // Use initialDate if provided, otherwise default to today +const SingleAvailabilityView: React.FC = ({ totalAvailability, initialDate }) => { const [startDate, setStartDate] = useState(initialDate || new Date()); - // Update startDate when initialDate changes useEffect(() => { if (initialDate) { setStartDate(initialDate); @@ -30,45 +23,85 @@ const SingleAvailabilityView: React.FC = ({ const selectedTimes = getMostRecentAvailabilities(totalAvailability, startDate); const onArrowIncrease = () => { - setStartDate(new Date(startDate.setDate(startDate.getDate() + 7))); + const newDate = new Date(startDate); + newDate.setDate(newDate.getDate() + 7); + setStartDate(newDate); }; const onArrowDecrease = () => { - setStartDate(new Date(startDate.setDate(startDate.getDate() - 7))); + const newDate = new Date(startDate); + newDate.setDate(newDate.getDate() - 7); + setStartDate(newDate); }; + + const stickyLeft = { + position: 'sticky', + left: 0, + zIndex: 2, + bgcolor: 'background.paper' + }; + return ( - - - {selectedTimes.map((availability) => ( - - ))} - {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( - - - {selectedTimes.map((availability, dayIndex) => { - const backgroundColor = availability.availability.includes(timeIndex) ? HeatmapColors[3] : HeatmapColors[0]; - return ( - - ); - })} - - ))} - + + + + + + + {selectedTimes.map((availability, idx) => ( + + + {getDayOfWeek(availability.dateSet) + ' ' + datePipe(availability.dateSet)} + + + ))} + + + + {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( + + + + {time} + + + {selectedTimes.map((availability, dayIndex) => { + const isAvailable = availability.availability.includes(timeIndex); + return ( + + {}} + /> + + ); + })} + + ))} + +
+
+ -
+ ); }; From 43d12cbc7134428f8265f2249293830ca87185ef Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 1 Jan 2026 14:27:43 -0500 Subject: [PATCH 438/477] minor fix --- src/frontend/src/pages/NewCalendarPage/EventsTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx index 3ed6fe6204..c1e382d779 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx @@ -175,7 +175,7 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, return ( - + Date: Thu, 1 Jan 2026 15:32:17 -0500 Subject: [PATCH 439/477] test --- .../Components/EditEventModal.tsx | 1 + .../src/pages/NewCalendarPage/EventsTable.tsx | 128 ++++++++++++++++-- src/frontend/src/utils/calendar.utils.ts | 31 +++++ 3 files changed, 149 insertions(+), 11 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx index a89a73d5c0..8d1abf2425 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx @@ -7,6 +7,7 @@ export interface EditEventModalProps { onSubmit: (data: EventRoutePayload) => void; initialValues: Partial; eventTypes: EventType[]; + defaultDate?: Date; } const EditEventModal: React.FC = (props) => { diff --git a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx index c1e382d779..27ac279496 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx @@ -2,15 +2,32 @@ * This file is part of NER's FinishLine and licensed under GNU AGPLv3. * See the LICENSE file in the repository root folder for details. */ -import { Box, Link, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; +import { + Box, + IconButton, + Link, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Tooltip, + Typography +} from '@mui/material'; import PageTitle from '../../layouts/PageTitle/PageTitle'; import TableCellHuge from './YourEventsComponents/TableCellHuge'; import React, { useEffect, useState } from 'react'; import { Calendar, ConflictStatus, EventType } from 'shared'; import { Event } from 'shared'; import WarningTooltip from './YourEventsComponents/WarningTooltip'; -import { getMeetingDates } from '../../utils/calendar.utils'; +import { convertEventToFormValues, getMeetingDates } from '../../utils/calendar.utils'; import { EventClickPopup } from './EventClickPopup'; +import { EditEventArgs, useEditEvent, useUploadManyDocuments } from '../../hooks/calendar.hooks'; +import EditEventModal from './Components/EditEventModal'; +import { EventRoutePayload } from './Components/EventModal'; +import { useToast } from '../../hooks/toasts.hooks'; +import EditIcon from '@mui/icons-material/Edit'; interface YourEventsHeadCells { id: string; @@ -83,9 +100,17 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, // Done this way to allow the old events transformer to function properly // but provide better utility to this file (without breaking other files that may rely on eventTransformer) + const toast = useToast(); + const [clickedEvent, setClickedEvent] = useState(); const [anchorPosition, setAnchorPosition] = useState<{ top: number; left: number }>(); + const [clickedEditEvent, setClickedEditEvent] = useState(); + const [showEditModal, setShowEditModal] = useState(false); + + const { mutateAsync: editEvent } = useEditEvent(clickedEditEvent?.eventId ?? ''); + const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); + const handleOpenClickPopup = (event: Event) => { setClickedEvent(event); if (typeof window !== 'undefined') { @@ -103,6 +128,66 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, setAnchorPosition(undefined); }; + const handleEdit = (event: Event) => { + setClickedEditEvent(event); + setShowEditModal(true); + }; + + const handleCloseEdit = () => { + setClickedEditEvent(undefined); + setShowEditModal(false); + }; + + const handleEditSubmit = async (data: EventRoutePayload) => { + if (!clickedEditEvent) return; + + try { + const { scheduleSlot, documentFiles, ...eventData } = data; + + if (!scheduleSlot || scheduleSlot.length === 0) { + throw new Error('Missing scheduleSlot'); + } + + // Convert EventRoutePayload to EditEventArgs format + const editArgs: EditEventArgs = { + ...eventData, + status: clickedEditEvent.status, // Use existing event status + documents: clickedEditEvent.documents.map((doc) => ({ + name: doc.name, + googleFileId: doc.googleFileId + })), + scheduleSlot: scheduleSlot.map((slot) => ({ + days: slot.days, + startTime: slot.startTime, + endTime: slot.endTime, + recurrenceNumber: slot.recurrenceNumber, + initialDateScheduled: slot.initialDateScheduled, + allDay: slot.allDay + })) + }; + + const editedEvent = await editEvent(editArgs); + + // Upload new documents if any + const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); + + if (filesToUpload.length > 0) { + await uploadDocuments({ + id: editedEvent.eventId, + files: filesToUpload + }); + } + + toast.success('Event updated successfully!'); + setShowEditModal(false); + handleCloseEdit(); + } catch (err) { + if (err instanceof Error) { + toast.error(err.message); + } + } + }; + const headCells: readonly YourEventsHeadCells[] = [ { id: 'eventsName', @@ -164,15 +249,6 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, const events = tab === 1 ? yourEvents : reviewEvents; - const [, setUpdate] = useState(true); // Linting... - - useEffect(() => { - const timer = setInterval(() => { - setUpdate((prev) => !prev); - }, 1000); - return () => clearInterval(timer); - }, []); - return ( @@ -193,6 +269,7 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, {headCells.map((headCell) => ( ))} + {tab === 1 && } @@ -284,6 +361,25 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, )} + {tab === 1 && ( + + + + + { + handleEdit(event); + }} + > + + + + + + + )} ); })} @@ -312,6 +408,16 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, disable={true} addApprovalButtons={true} /> + {clickedEditEvent && showEditModal && ( + + )} ); }; diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 7446fd17fe..1b5f1df416 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -1,5 +1,6 @@ import { DayOfWeek, Event } from 'shared'; import { filterEventTransformer } from '../apis/transformers/calendar.transformer'; +import { EventFormValues } from '../pages/NewCalendarPage/Components/EventModal'; export const convertDayToInt = (day: DayOfWeek) => { switch (day) { @@ -157,3 +158,33 @@ export const getEventsFlattened = (events: Event[], startPeriod: Date, endPeriod // Return only the events, possibly repeated for multiple occurrences return occurrences.map(({ event }) => event); }; + +export const convertEventToFormValues = (event: Event): Partial => { + return { + title: event.title, + eventTypeId: event.eventTypeId, + requiredMemberIds: event.requiredMembers.map((m) => m.userId), + optionalMemberIds: event.optionalMembers.map((m) => m.userId), + teamIds: event.teams.map((t) => t.teamId), + teamTypeId: event.teamType?.teamTypeId, + location: event.location, + zoomLink: event.zoomLink, + shopIds: event.shops.map((s) => s.shopId), + machineryIds: event.machinery.map((m) => m.machineryId), + workPackageIds: event.workPackages.map((wp) => wp.workPackageId), + documentFiles: event.documents.map((doc) => ({ + name: doc.name, + googleFileId: doc.googleFileId + })), + questionDocumentLink: event.questionDocumentLink, + description: event.description, + scheduleDate: event.scheduledTimes[0]?.initialDateScheduled + ? new Date(event.scheduledTimes[0].initialDateScheduled) + : new Date(), + startTime: event.scheduledTimes[0]?.startTime ? new Date(event.scheduledTimes[0].startTime) : undefined, + endTime: event.scheduledTimes[0]?.endTime ? new Date(event.scheduledTimes[0].endTime) : undefined, + allDay: event.scheduledTimes[0]?.allDay ?? false, + recurrenceNumber: event.scheduledTimes[0]?.recurrenceNumber ?? 0, + days: event.scheduledTimes[0]?.days ?? [] + }; +}; From 4c933b7a9b62ddbf5a2a5a55c8be5a3672f88e2c Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 1 Jan 2026 16:06:52 -0500 Subject: [PATCH 440/477] fix the edit --- src/backend/src/services/calendar.services.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 356ea1cbdc..90b85fd873 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -854,6 +854,7 @@ export default class CalendarService { data: { days: s.days, startTime: s.startTime ?? null, + endTime: s.endTime ?? null, endDate: computeEndDate(s.initialDateScheduled, s.recurrenceNumber), recurrenceNumber: s.recurrenceNumber, initialDateScheduled: s.initialDateScheduled, From 1d2d90bd35acfa3b3f89305c0d802dab0a8c89fc Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 1 Jan 2026 16:20:27 -0500 Subject: [PATCH 441/477] delete modal update --- .../src/pages/NewCalendarPage/EventsTable.tsx | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx index 27ac279496..74eb36cfaa 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx @@ -23,11 +23,13 @@ import { Event } from 'shared'; import WarningTooltip from './YourEventsComponents/WarningTooltip'; import { convertEventToFormValues, getMeetingDates } from '../../utils/calendar.utils'; import { EventClickPopup } from './EventClickPopup'; -import { EditEventArgs, useEditEvent, useUploadManyDocuments } from '../../hooks/calendar.hooks'; +import { EditEventArgs, useDeleteEvent, useEditEvent, useUploadManyDocuments } from '../../hooks/calendar.hooks'; import EditEventModal from './Components/EditEventModal'; import { EventRoutePayload } from './Components/EventModal'; import { useToast } from '../../hooks/toasts.hooks'; import EditIcon from '@mui/icons-material/Edit'; +import DeleteIcon from '@mui/icons-material/Delete'; +import NERDeleteModal from '../../components/NERDeleteModal'; interface YourEventsHeadCells { id: string; @@ -108,6 +110,8 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, const [clickedEditEvent, setClickedEditEvent] = useState(); const [showEditModal, setShowEditModal] = useState(false); + const [eventToDelete, setEventToDelete] = useState(undefined); + const { mutateAsync: editEvent } = useEditEvent(clickedEditEvent?.eventId ?? ''); const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); @@ -138,6 +142,23 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, setShowEditModal(false); }; + const { mutateAsync: deleteEvent } = useDeleteEvent(eventToDelete?.eventId ?? ''); + + const handleEventDelete = async () => { + if (!eventToDelete) return; + setEventToDelete(undefined); + try { + await deleteEvent(); + toast.success('Event deleted successfully'); + } catch (e: unknown) { + if (e instanceof Error) { + toast.error(e.message, 3000); + } else { + toast.error('Failed to delete event', 3000); + } + } + }; + const handleEditSubmit = async (data: EventRoutePayload) => { if (!clickedEditEvent) return; @@ -377,6 +398,18 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents,
+ + + setEventToDelete(event)} + > + + + + )} @@ -418,6 +451,13 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, defaultDate={new Date()} /> )} + setEventToDelete(undefined)} + formId="delete-event-form" + dataType={eventToDelete?.title || ''} + onFormSubmit={handleEventDelete} + /> ); }; From 59abbd64a70b59e936b70ce6f13de971f7a23965 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 1 Jan 2026 16:41:43 -0500 Subject: [PATCH 442/477] abstract just in case --- .../src/pages/NewCalendarPage/CalendarTab.tsx | 70 ++++++++++++++++- .../src/pages/NewCalendarPage/EventsTable.tsx | 75 ++++++------------- 2 files changed, 89 insertions(+), 56 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index 37c6d88c87..7e93d3e958 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -5,17 +5,28 @@ import { Box } from '@mui/material'; import FullPageTabs from '../../components/FullPageTabs'; import { useState } from 'react'; import { useCurrentUser } from '../../hooks/users.hooks'; -import { ConflictStatus, isHead, isLead } from 'shared'; -import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; +import { Event, ConflictStatus, isHead, isLead } from 'shared'; +import { + EditEventArgs, + useAllCalendars, + useAllEventTypes, + useFilterEvents, + useUploadManyDocuments +} from '../../hooks/calendar.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; import EventsTable from './EventsTable'; +import { EventRoutePayload } from './Components/EventModal'; +import { useToast } from '../../hooks/toasts.hooks'; const CalendarTab: React.FC = () => { const [tabIndex, setTabIndex] = useState(0); const user = useCurrentUser(); const canViewReviews = isHead(user.role) || isLead(user.role); + const toast = useToast(); + const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); + const tabs = [ { tabUrlValue: 'mainCalendar', tabName: 'Calendar' }, { tabUrlValue: 'yourEvents', tabName: 'Your Events' } @@ -82,6 +93,60 @@ const CalendarTab: React.FC = () => { if (canViewReviews) tabs.push({ tabUrlValue: 'reviews', tabName: 'Review Bookings' }); + const handleEditSubmit = async ( + data: EventRoutePayload, + event: Event, + editEvent: (editArgs: EditEventArgs) => Promise, + onClose: () => void + ) => { + if (!event) return; + + try { + const { scheduleSlot, documentFiles, ...eventData } = data; + + if (!scheduleSlot || scheduleSlot.length === 0) { + throw new Error('Missing scheduleSlot'); + } + + // Convert EventRoutePayload to EditEventArgs format + const editArgs: EditEventArgs = { + ...eventData, + status: event.status, // Use existing event status + documents: event.documents.map((doc) => ({ + name: doc.name, + googleFileId: doc.googleFileId + })), + scheduleSlot: scheduleSlot.map((slot) => ({ + days: slot.days, + startTime: slot.startTime, + endTime: slot.endTime, + recurrenceNumber: slot.recurrenceNumber, + initialDateScheduled: slot.initialDateScheduled, + allDay: slot.allDay + })) + }; + + const editedEvent = await editEvent(editArgs); + + // Upload new documents if any + const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); + + if (filesToUpload.length > 0) { + await uploadDocuments({ + id: editedEvent.eventId, + files: filesToUpload + }); + } + + toast.success('Event updated successfully!'); + onClose(); + } catch (err) { + if (err instanceof Error) { + toast.error(err.message); + } + } + }; + return ( { reviewEvents={reviewEvents ?? []} allEventTypes={allEventTypes} allCalendars={allCalendars} + handleEditSubmit={handleEditSubmit} /> )} diff --git a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx index 74eb36cfaa..b3e6411363 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx @@ -23,7 +23,7 @@ import { Event } from 'shared'; import WarningTooltip from './YourEventsComponents/WarningTooltip'; import { convertEventToFormValues, getMeetingDates } from '../../utils/calendar.utils'; import { EventClickPopup } from './EventClickPopup'; -import { EditEventArgs, useDeleteEvent, useEditEvent, useUploadManyDocuments } from '../../hooks/calendar.hooks'; +import { EditEventArgs, useDeleteEvent, useEditEvent } from '../../hooks/calendar.hooks'; import EditEventModal from './Components/EditEventModal'; import { EventRoutePayload } from './Components/EventModal'; import { useToast } from '../../hooks/toasts.hooks'; @@ -58,6 +58,12 @@ export interface EventTableArgs { allEventTypes: EventType[]; allCalendars: Calendar[]; tab: number; + handleEditSubmit: ( + data: EventRoutePayload, + event: Event, + editEvent: (editArgs: EditEventArgs) => Promise, + onClose: () => void + ) => Promise; } // trigger re-renders specifically for the timer @@ -97,7 +103,14 @@ const CountdownElement = ({ targetDate }: { targetDate: Date }) => { ); }; -const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, allEventTypes, allCalendars }) => { +const EventsTable: React.FC = ({ + tab, + yourEvents, + reviewEvents, + allEventTypes, + allCalendars, + handleEditSubmit +}) => { // Convert to include proper dates // Done this way to allow the old events transformer to function properly // but provide better utility to this file (without breaking other files that may rely on eventTransformer) @@ -113,7 +126,6 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, const [eventToDelete, setEventToDelete] = useState(undefined); const { mutateAsync: editEvent } = useEditEvent(clickedEditEvent?.eventId ?? ''); - const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); const handleOpenClickPopup = (event: Event) => { setClickedEvent(event); @@ -159,56 +171,6 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, } }; - const handleEditSubmit = async (data: EventRoutePayload) => { - if (!clickedEditEvent) return; - - try { - const { scheduleSlot, documentFiles, ...eventData } = data; - - if (!scheduleSlot || scheduleSlot.length === 0) { - throw new Error('Missing scheduleSlot'); - } - - // Convert EventRoutePayload to EditEventArgs format - const editArgs: EditEventArgs = { - ...eventData, - status: clickedEditEvent.status, // Use existing event status - documents: clickedEditEvent.documents.map((doc) => ({ - name: doc.name, - googleFileId: doc.googleFileId - })), - scheduleSlot: scheduleSlot.map((slot) => ({ - days: slot.days, - startTime: slot.startTime, - endTime: slot.endTime, - recurrenceNumber: slot.recurrenceNumber, - initialDateScheduled: slot.initialDateScheduled, - allDay: slot.allDay - })) - }; - - const editedEvent = await editEvent(editArgs); - - // Upload new documents if any - const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); - - if (filesToUpload.length > 0) { - await uploadDocuments({ - id: editedEvent.eventId, - files: filesToUpload - }); - } - - toast.success('Event updated successfully!'); - setShowEditModal(false); - handleCloseEdit(); - } catch (err) { - if (err instanceof Error) { - toast.error(err.message); - } - } - }; - const headCells: readonly YourEventsHeadCells[] = [ { id: 'eventsName', @@ -445,7 +407,12 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, { + handleEditSubmit(data, clickedEditEvent, editEvent, () => { + setShowEditModal(false); + handleCloseEdit(); + }); + }} initialValues={convertEventToFormValues(clickedEditEvent)} eventTypes={allEventTypes} defaultDate={new Date()} From 525869eb339b7ccd502b3fa96bdc9838e32c5d05 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 1 Jan 2026 16:52:15 -0500 Subject: [PATCH 443/477] remove unnecessary files --- src/frontend/src/app/AppAuthenticated.tsx | 2 - src/frontend/src/layouts/Sidebar/Sidebar.tsx | 5 - .../src/pages/CalendarPage/Calendar.tsx | 19 -- .../CalendarComponents/MonthSelector.tsx | 53 ----- .../src/pages/CalendarPage/CalendarPage.tsx | 211 ------------------ .../pages/CalendarPage/EventSummaryModal.tsx | 176 --------------- .../SummaryComponents/EventDelayModal.tsx | 54 ----- .../SummaryComponents/EventPill.tsx | 23 -- .../EventSummaryModalAttendees.tsx | 119 ---------- .../EventSummaryModalButtons.tsx | 79 ------- .../EventSummaryModalDetails.tsx | 151 ------------- .../pages/NewCalendarPage/NewCalendarPage.tsx | 12 - 12 files changed, 904 deletions(-) delete mode 100644 src/frontend/src/pages/CalendarPage/Calendar.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/CalendarComponents/MonthSelector.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/CalendarPage.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/SummaryComponents/EventDelayModal.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/SummaryComponents/EventPill.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalAttendees.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalButtons.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx diff --git a/src/frontend/src/app/AppAuthenticated.tsx b/src/frontend/src/app/AppAuthenticated.tsx index ed47bc82c6..300e198b02 100644 --- a/src/frontend/src/app/AppAuthenticated.tsx +++ b/src/frontend/src/app/AppAuthenticated.tsx @@ -26,7 +26,6 @@ import { Box } from '@mui/system'; import { Container, IconButton, useTheme } from '@mui/material'; import ErrorPage from '../pages/ErrorPage'; import { Role, isGuest } from 'shared'; -import Calendar from '../pages/CalendarPage/Calendar'; import { useState } from 'react'; import ArrowCircleRightTwoToneIcon from '@mui/icons-material/ArrowCircleRightTwoTone'; import HiddenContentMargin from '../components/HiddenContentMargin'; @@ -127,7 +126,6 @@ const AppAuthenticated: React.FC = ({ userId, userRole }) - diff --git a/src/frontend/src/layouts/Sidebar/Sidebar.tsx b/src/frontend/src/layouts/Sidebar/Sidebar.tsx index 687a08ea47..4e51ff444e 100644 --- a/src/frontend/src/layouts/Sidebar/Sidebar.tsx +++ b/src/frontend/src/layouts/Sidebar/Sidebar.tsx @@ -92,11 +92,6 @@ const Sidebar = ({ drawerOpen, setDrawerOpen, moveContent, setMoveContent }: Sid { name: 'Calendar', icon: , - route: routes.CALENDAR - }, - { - name: 'New Calendar', - icon: , route: routes.NEW_CALENDAR }, { diff --git a/src/frontend/src/pages/CalendarPage/Calendar.tsx b/src/frontend/src/pages/CalendarPage/Calendar.tsx deleted file mode 100644 index 56c94ae19d..0000000000 --- a/src/frontend/src/pages/CalendarPage/Calendar.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This file is part of NER's FinishLine and licensed under GNU AGPLv3. - * See the LICENSE file in the repository root folder for details. - */ -import { Route, Switch } from 'react-router-dom'; -import { routes } from '../../utils/routes'; -import CalendarPage from './CalendarPage'; -import DesignReviewDetails from './EventDetailPage/EventDetails'; - -const Calendar: React.FC = () => { - return ( - - - - - ); -}; - -export default Calendar; diff --git a/src/frontend/src/pages/CalendarPage/CalendarComponents/MonthSelector.tsx b/src/frontend/src/pages/CalendarPage/CalendarComponents/MonthSelector.tsx deleted file mode 100644 index 730b511573..0000000000 --- a/src/frontend/src/pages/CalendarPage/CalendarComponents/MonthSelector.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Box, MenuItem, TextField } from '@mui/material'; -import { Dispatch, SetStateAction } from 'react'; -import { enumToArray, MONTH_NAMES } from '../../../utils/design-review.utils'; - -interface MonthSelectorProps { - displayMonth: Date; - setDisplayMonth: Dispatch>; -} - -const MonthSelector: React.FC = ({ displayMonth, setDisplayMonth }) => { - // TODO change this to use Pagination instead of hardocding 50 years - const years = [...Array(50).keys()].map((num) => (num + 2024).toString()); - - return ( - - { - displayMonth.setMonth(Number(event.target.value)); - setDisplayMonth(new Date(displayMonth)); - }} - > - {enumToArray(MONTH_NAMES).map((month, index) => { - return ( - - {month} - - ); - })} - - - { - displayMonth.setFullYear(Number.parseInt(event.target.value)); - setDisplayMonth(new Date(displayMonth)); - }} - > - {years.map((year) => ( - - {year} - - ))} - - - ); -}; - -export default MonthSelector; diff --git a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx b/src/frontend/src/pages/CalendarPage/CalendarPage.tsx deleted file mode 100644 index 3df901c937..0000000000 --- a/src/frontend/src/pages/CalendarPage/CalendarPage.tsx +++ /dev/null @@ -1,211 +0,0 @@ -/* - * This file is part of NER's FinishLine and licensed under GNU AGPLv3. - * See the LICENSE file in the repository root folder for details. - */ -import { useState } from 'react'; -import { Box, Grid, Stack, Tooltip, Typography, useMediaQuery, useTheme } from '@mui/material'; -import PageLayout from '../../components/PageLayout'; -import { Event, EventStatus } from 'shared'; -import MonthSelector from '../CalendarPage/CalendarComponents/MonthSelector'; -import CalendarDayCard, { getTeamTypeIcon } from '../NewCalendarPage/CalendarDayCard'; -import { DAY_NAMES, enumToArray } from '../../utils/design-review.utils'; -import ActionsMenu from '../../components/ActionsMenu'; -import { useAllEvents } from '../../hooks/calendar.hooks'; -import ErrorPage from '../ErrorPage'; -import { useCurrentUser } from '../../hooks/users.hooks'; -import { datePipe } from '../../utils/pipes'; -import LoadingIndicator from '../../components/LoadingIndicator'; -import DRCSummaryModal from './EventSummaryModal'; -import { useAllTeamTypes } from '../../hooks/team-types.hooks'; -import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; - -const CalendarPage = () => { - const theme = useTheme(); - const { - data: allTeamTypes, - isLoading: allTeamTypesLoading, - isError: allTeamTypesIsError, - error: allTeamTypesError - } = useAllTeamTypes(); - - const [displayMonthYear, setDisplayMonthYear] = useState(new Date()); - const { isLoading, isError, error, data: allEvents } = useAllEvents(); - const user = useCurrentUser(); - const [selectedEvent, setSelectedEvent] = useState(); - const isLargerView = useMediaQuery(theme.breakpoints.up('md')); - const isExtraSmallView = useMediaQuery(theme.breakpoints.down('sm')); - if (isLoading || !allEvents) return ; - if (isError) return ; - - // Sort events by date and time - const sortedEvents = [...allEvents].sort((event1, event2) => { - const date1 = event1.scheduledTimes[0]?.initialDateScheduled - ? new Date(event1.scheduledTimes[0].initialDateScheduled).getTime() - : 0; - const date2 = event2.scheduledTimes[0]?.initialDateScheduled - ? new Date(event2.scheduledTimes[0].initialDateScheduled).getTime() - : 0; - - if (date1 === date2) { - const time1 = event1.scheduledTimes[0]?.startTime ? new Date(event1.scheduledTimes[0].startTime).getTime() : 0; - const time2 = event2.scheduledTimes[0]?.startTime ? new Date(event2.scheduledTimes[0].startTime).getTime() : 0; - return time1 - time2; - } - return date1 - date2; - }); - - const eventDict = new Map(); - sortedEvents.forEach((event) => { - const firstScheduledDate = event.scheduledTimes[0]?.initialDateScheduled; - if (!firstScheduledDate) return; - - // Convert string to Date - const dateObj = new Date(firstScheduledDate); - const date = datePipe(new Date(dateObj.getTime() - dateObj.getTimezoneOffset() * -60000)); - if (eventDict.has(date)) { - eventDict.get(date)?.push(event); - } else { - eventDict.set(date, [event]); - } - }); - - const currentUserEvents = allEvents.filter( - (event) => event.userCreated.userId === user.userId && event.status !== EventStatus.DONE - ); - - // Generate calendar dates - const firstDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 1); - const lastDayOfMonth = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, 0); - - const paddingStart = firstDayOfMonth.getDay(); - const totalDays = lastDayOfMonth.getDate(); - const totalCells = Math.ceil((paddingStart + totalDays) / 7) * 7; - - const calendarDates: Date[] = []; - - // Add padding days from previous month - const prevMonthLastDay = new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), 0); - const prevMonthDays = prevMonthLastDay.getDate(); - for (let i = paddingStart - 1; i >= 0; i--) { - calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() - 1, prevMonthDays - i)); - } - - // Add current month days - for (let day = 1; day <= totalDays; day++) { - calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth(), day)); - } - - // Add padding days from next month - const remainingCells = totalCells - calendarDates.length; - for (let day = 1; day <= remainingCells; day++) { - calendarDates.push(new Date(displayMonthYear.getFullYear(), displayMonthYear.getMonth() + 1, day)); - } - - const eventButtons = (events: Event[]) => { - return events.map((event) => { - // Get team type name directly from event - const teamTypeName = event.teamType?.name || 'Default'; - - // Get title from work packages or event title - const title = - event.workPackages.length > 0 ? event.workPackages.map((wp) => wp.wbsElement.name).join(', ') : event.title; - - return { - icon: getTeamTypeIcon(teamTypeName), - title, - onClick: () => { - setSelectedEvent(event); - }, - disabled: false - }; - }); - }; - - const NoEventsButton = () => { - return [ - { - title: 'No Events', - disabled: true, - onClick: () => {} - } - ]; - }; - - const unconfirmedEventsDropdown = ( - - My Unconfirmed DRs - - ); - - if (!allTeamTypes || allTeamTypesLoading) return ; - if (allTeamTypesIsError) return ; - - return ( - <> - {selectedEvent && ( - { - setSelectedEvent(undefined); - }} - event={selectedEvent} - teamTypes={allTeamTypes} - /> - )} - - - Calendar - - - - - {unconfirmedEventsDropdown} - - - - - - {enumToArray(DAY_NAMES).map((day, index) => ( - - - {isLargerView ? day : isExtraSmallView ? day.charAt(0) : day.substring(0, 3)} - - - ))} - - - - {Array.from({ length: Math.ceil(calendarDates.length / 7) }, (_, weekIndex) => ( - - {calendarDates.slice(weekIndex * 7, weekIndex * 7 + 7).map((cardDate, dayIndex) => ( - - - - - - ))} - - ))} - - - - - - - - - - ); -}; - -export default CalendarPage; diff --git a/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx b/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx deleted file mode 100644 index 3d3a5f54e8..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventSummaryModal.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { Event, EventStatus, TeamType, isAdmin, wbsPipe } from 'shared'; -import NERModal from '../../components/NERModal'; -import { Box, Chip, IconButton, Link, Typography } from '@mui/material'; -import EditIcon from '@mui/icons-material/Edit'; -import { useState } from 'react'; -import { getTeamTypeIcon } from '../NewCalendarPage/CalendarDayCard'; -import { Link as RouterLink, useHistory } from 'react-router-dom'; -import { routes } from '../../utils/routes'; -import { useCurrentUser } from '../../hooks/users.hooks'; -import DeleteIcon from '@mui/icons-material/Delete'; -import { useToast } from '../../hooks/toasts.hooks'; -import { eventStatusColor, eventStatusPipe } from '../../utils/design-review.utils'; -import NERSuccessButton from '../../components/NERSuccessButton'; -import { CheckCircle } from '@mui/icons-material'; -import { useDeleteEvent } from '../../hooks/calendar.hooks'; -import EventSummaryModalDetails from './SummaryComponents/EventSummaryModalDetails'; -import EventSummaryModalAttendees from './SummaryComponents/EventSummaryModalAttendees'; -import { EventAvailabilityInfo } from './EventAvailabilityInfo'; - -interface EventSummaryModalProps { - open: boolean; - onHide: () => void; - event: Event; - teamTypes: TeamType[]; - markedStatus?: EventStatus; - setMarkedStatus?: (_: EventStatus) => void; -} - -const EventSummaryModal: React.FC = ({ - open, - onHide, - event, - teamTypes, - markedStatus = EventStatus.UNCONFIRMED, - setMarkedStatus = () => {} -}: EventSummaryModalProps) => { - const user = useCurrentUser(); - const toast = useToast(); - const history = useHistory(); - const [showDeleteModal, setShowDeleteModal] = useState(false); - - const { mutateAsync: deleteEvent } = useDeleteEvent(event.eventId); - - const isEventCreator = user.userId === event.userCreated.userId; - - const isScheduled = event.status === EventStatus.SCHEDULED || event.status === EventStatus.DONE; - - const handleDelete = async () => { - try { - await deleteEvent(); - history.push(routes.CALENDAR); - } catch (e: unknown) { - if (e instanceof Error) { - toast.error(e.message, 3000); - } - } - }; - - const DeleteModal = () => { - return ( - setShowDeleteModal(false)} - title="Warning!" - cancelText="No" - submitText="Yes" - onSubmit={handleDelete} - > - Are you sure you want to delete this event? - - ); - }; - - const [firstWorkPackage] = event.workPackages; - - const wbsNum = firstWorkPackage - ? { - carNumber: firstWorkPackage.wbsElement.carNumber, - projectNumber: firstWorkPackage.wbsElement.projectNumber, - workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber - } - : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; - - const eventName = firstWorkPackage?.wbsElement?.name - ? `${firstWorkPackage.wbsElement.carNumber}.${firstWorkPackage.wbsElement.projectNumber}.${firstWorkPackage.wbsElement.workPackageNumber} - ${firstWorkPackage.wbsElement.name}` - : event.title; - - return ( - - {(isEventCreator || isAdmin(user.role)) && ( - <> - setShowDeleteModal(true)}> - - - - - - - )} - attendee.userId === user.userId) || - isScheduled - } - > - - - - } - > - - - - - - - - {`${eventName}`} - - - - - {isScheduled && ( - - )} - {event.status === EventStatus.CONFIRMED && ( - - - {isEventCreator && ( - - - Schedule Event - - - )} - - )} - {event.status === EventStatus.UNCONFIRMED && } - - - - ); -}; - -export default EventSummaryModal; diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventDelayModal.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventDelayModal.tsx deleted file mode 100644 index 61f04e31ee..0000000000 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventDelayModal.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { TextField, Link, FormLabel, FormControl } from '@mui/material'; -import { useState, ChangeEvent } from 'react'; -import { Event, wbsPipe } from 'shared'; -import { Link as RouterLink } from 'react-router-dom'; -import NERModal from '../../../components/NERModal'; -import NERSuccessButton from '../../../components/NERSuccessButton'; -import { useToast } from '../../../hooks/toasts.hooks'; -import { routes } from '../../../utils/routes'; - -export const EventDelayModal: React.FC<{ open: boolean; onHide: () => void; event: Event }> = ({ open, onHide, event }) => { - const toast = useToast(); - const [weeks, setWeeks] = useState(1); - const onChange = (e: ChangeEvent) => { - if (e.target.value === '' || parseInt(e.target.value) >= 1) { - setWeeks(parseInt(e.target.value)); - } else { - toast.error('If delaying, it must be by at least 1 week'); - } - }; - - const [firstWorkPackage] = event.workPackages; - - const wbsNumber = firstWorkPackage - ? { - carNumber: firstWorkPackage.wbsElement.carNumber, - projectNumber: firstWorkPackage.wbsElement.projectNumber, - workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber - } - : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; - - return ( - - - Enter number of weeks - - - - = 1 ? weeks : 1}`} - > - Delay - - - - ); -}; diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventPill.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventPill.tsx deleted file mode 100644 index f111a2b677..0000000000 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventPill.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Typography, Box } from '@mui/material'; - -export const EventPill: React.FC<{ - icon: React.ReactNode; - displayText: string; -}> = ({ icon, displayText }) => { - return ( - - {icon} - - {displayText} - - - ); -}; diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalAttendees.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalAttendees.tsx deleted file mode 100644 index 1ba13eb66b..0000000000 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalAttendees.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { Grid, Typography } from '@mui/material'; -import { Box } from '@mui/system'; -import { Event, User } from 'shared'; -import { MemberPill } from '../../../components/MemberPill'; -import { useToast } from '../../../hooks/toasts.hooks'; -import { useCurrentUser } from '../../../hooks/users.hooks'; - -interface EventSummaryModalAttendeesProps { - event: Event; -} - -interface EventEditAttendeesProps { - requiredMembers: User[]; - optionalMembers: User[]; -} - -const EventSummaryModalAttendees: React.FC = ({ event }) => { - const toast = useToast(); - const { requiredMembers } = event; - const { optionalMembers } = event; - const currentUser = useCurrentUser(); - - /* - const { isLoading: editDesignReviewIsLoading, mutateAsync: editDesignReview } = useEditDesignReview( - designReview.designReviewId - ); - */ - - const handleRemoveRequiredMember = (user: User) => { - if (currentUser.userId === event.userCreated.userId) { - const updatedMembers = requiredMembers.filter((member) => member.userId !== user.userId); - saveMembers({ requiredMembers: updatedMembers, optionalMembers }); - } else { - toast.error('Only the creator of the Event can edit attendees'); - } - }; - - const handleRemoveOptionalMember = (user: User) => { - if (currentUser.userId === event.userCreated.userId) { - const updatedMembers = optionalMembers.filter((member) => member.userId !== user.userId); - saveMembers({ requiredMembers, optionalMembers: updatedMembers }); - } else { - toast.error('Only the creator of the Event can edit attendees'); - } - }; - - const saveMembers = async (_payload: EventEditAttendeesProps) => { - /* - try { - await editDesignReview({ - ...designReview, - teamTypeId: designReview.teamType.teamTypeId, - zoomLink: designReview.zoomLink ?? '', - location: designReview.location ?? '', - docTemplateLink: designReview.docTemplateLink ?? '', - attendees: designReview.attendees.map((user) => user.userId), - requiredMembersIds: payload.requiredMembers.map((member) => member.userId), - optionalMembersIds: payload.optionalMembers.map((member) => member.userId) - }); - } catch (e) { - if (e instanceof Error) { - toast.error(e.message); - } - } - */ - }; - - // if (editDesignReviewIsLoading) return ; - - return ( - - - - Required: - - - - {requiredMembers.map((member, index) => ( - - { - handleRemoveRequiredMember(member); - } - : undefined - } - /> - - ))} - - - - Optional: - - - {optionalMembers.map((member, index) => ( - - { - handleRemoveOptionalMember(member); - } - : undefined - } - /> - - ))} - - - - - ); -}; - -export default EventSummaryModalAttendees; diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalButtons.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalButtons.tsx deleted file mode 100644 index 6df0866aa4..0000000000 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalButtons.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { Box } from '@mui/system'; -import { Event, TeamType } from 'shared'; -import { NERButton } from '../../../components/NERButton'; -import NERFailButton from '../../../components/NERFailButton'; -import NERSuccessButton from '../../../components/NERSuccessButton'; -import { useState } from 'react'; - -interface EventSummaryModalButtonsProps { - event: Event; - handleStageGateClick: () => void; - handleDelayClick: () => void; - teamTypes: TeamType[]; -} - -const EventSummaryModalButtons: React.FC = ({ - event: _event, - handleDelayClick, - handleStageGateClick, - teamTypes: _teamTypes -}) => { - const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); - - return ( - - { - isCreateModalOpen && isCreateModalOpen - /* - { - setIsCreateModalOpen(false); - }} - teamTypes={teamTypes} - defaultDate={new Date()} - defaultWbsNum={designReview.wbsNum} - /> - */ - } - - - Request Delay - - - Stage Gate - - - setIsCreateModalOpen(true)} - > - Schedule Another Event - - - ); -}; - -export default EventSummaryModalButtons; diff --git a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx b/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx deleted file mode 100644 index 151b7f8c28..0000000000 --- a/src/frontend/src/pages/CalendarPage/SummaryComponents/EventSummaryModalDetails.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import { Box, Checkbox, FormControlLabel, Link, Typography } from '@mui/material'; -import { Event, EventStatus, TeamType } from 'shared'; -import AccessTimeIcon from '@mui/icons-material/AccessTime'; -import LocationOnIcon from '@mui/icons-material/LocationOn'; -import DescriptionIcon from '@mui/icons-material/Description'; -import VideocamIcon from '@mui/icons-material/Videocam'; -import { EventPill } from './EventPill'; -import { useState } from 'react'; -import StageGateWorkPackageModalContainer from '../../WorkPackageDetailPage/StageGateWorkPackageModalContainer/StageGateWorkPackageModalContainer'; -import NERModal from '../../../components/NERModal'; -import { useSetEventStatus } from '../../../hooks/calendar.hooks'; -import { meetingStartTimePipeScheduleSlot } from '../../../utils/pipes'; -import { EventDelayModal } from './EventDelayModal'; -import EventSummaryModalButtons from './EventSummaryModalButtons'; - -interface EventSummaryModalDetailsProps { - event: Event; - teamTypes: TeamType[]; - markedStatus: EventStatus; - setMarkedStatus: (_: EventStatus) => void; -} - -const EventSummaryModalDetails: React.FC = ({ - event, - teamTypes, - markedStatus, - setMarkedStatus -}) => { - const [showStageGateModal, setShowStageGateModal] = useState(false); - const [showDelayModal, setShowDelayModal] = useState(false); - const [showMarkCompleteModal, setShowMarkCompleteModal] = useState(false); - const [showUnmarkCompleteModal, setShowUnmarkCompleteModal] = useState(false); - const { mutateAsync } = useSetEventStatus(event.eventId); - - const MarkCompleteModal: React.FC = () => { - return ( - setShowMarkCompleteModal(false)} - cancelText="No" - submitText="Yes" - onSubmit={async () => { - setShowMarkCompleteModal(false); - await mutateAsync({ status: EventStatus.DONE }); - setMarkedStatus(EventStatus.DONE); - }} - > - Are you sure you want to mark this event as complete? - - ); - }; - - const UnmarkCompleteModal: React.FC = () => { - return ( - setShowUnmarkCompleteModal(false)} - cancelText="No" - submitText="Yes" - onSubmit={async () => { - setShowUnmarkCompleteModal(false); - await mutateAsync({ status: EventStatus.SCHEDULED }); - setMarkedStatus(EventStatus.SCHEDULED); - }} - > - - Are you sure you want to mark this event as not complete? - - - ); - }; - - const [firstWorkPackage] = event.workPackages; - - const wbsNum = firstWorkPackage - ? { - carNumber: firstWorkPackage.wbsElement.carNumber, - projectNumber: firstWorkPackage.wbsElement.projectNumber, - workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber - } - : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; - - return ( - <> - - setShowStageGateModal(false)} - hideStatus - /> - setShowDelayModal(false)} event={event} /> - - } displayText={meetingStartTimePipeScheduleSlot(event.scheduledTimes)} /> - } displayText={event.location ? event.location : 'Online'} /> - - - - - - - - {event.questionDocumentLink ? 'Question Document' : 'No Question Document'} - - - - - { - if (markedStatus === EventStatus.DONE) setShowUnmarkCompleteModal(true); - else setShowMarkCompleteModal(true); - }} - sx={{ - color: 'inherit', - '&.Mui-checked': { color: 'inherit' } - }} - /> - } - /> - - - - - - {event.zoomLink ? 'Zoom Link' : 'No Zoom'} - - - {markedStatus === EventStatus.DONE && ( - setShowStageGateModal(true)} - handleDelayClick={() => setShowDelayModal(true)} - teamTypes={teamTypes} - /> - )} - - - - - - - ); -}; - -export default EventSummaryModalDetails; diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 43bb7eeefe..b982b833b4 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -24,7 +24,6 @@ import { useConflictingEvents, useFilterEvents, useCreateEvent, useUploadManyDoc import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; -import EventSummaryModal from '../CalendarPage/EventSummaryModal'; import { useAllTeamTypes } from '../../hooks/team-types.hooks'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; import FilterModal from './FilterModal'; @@ -67,7 +66,6 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv const [displayMonthYear, setDisplayMonthYear] = useState(new Date()); const [showInvitedEvents, setShowInvitedEvents] = useState(true); const [showTeamEvents, setShowTeamEvents] = useState(true); - const [selectedEvent, setSelectedEvent] = useState(); const [openFilterModal, setOpenFilterModal] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [additionalMemberIds, setAdditionalMemberIds] = useState([user.userId]); @@ -330,16 +328,6 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv return ( <> - {selectedEvent && ( - { - setSelectedEvent(undefined); - }} - event={selectedEvent as Event} - teamTypes={allTeamTypes} - /> - )} {isCreateModalOpen && ( Date: Thu, 1 Jan 2026 16:58:25 -0500 Subject: [PATCH 444/477] text matches mock --- src/frontend/src/pages/NewCalendarPage/EventsTable.tsx | 2 +- src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx index b3e6411363..cfd7586abf 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx @@ -313,7 +313,7 @@ const EventsTable: React.FC = ({ {event.approved === ConflictStatus.DENIED && ( {}} /> diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index b982b833b4..d604075a34 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -340,7 +340,7 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv Date: Thu, 1 Jan 2026 20:05:19 -0500 Subject: [PATCH 445/477] removal --- src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx | 1 - src/frontend/src/utils/routes.ts | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx index eacbb652a7..bb10d0ae22 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx @@ -10,7 +10,6 @@ import CalendarTab from './CalendarTab'; const NewCalendar: React.FC = () => { return ( - ); diff --git a/src/frontend/src/utils/routes.ts b/src/frontend/src/utils/routes.ts index f096832e30..a70439d003 100644 --- a/src/frontend/src/utils/routes.ts +++ b/src/frontend/src/utils/routes.ts @@ -67,7 +67,6 @@ const PROJECT_TEMPLATE_EDIT = PROJECT_TEMPLATES + '/edit'; /**************** Design Review Calendar ****************/ const CALENDAR = `/design-review-calendar`; const NEW_CALENDAR = `/calendar`; -const DESIGN_REVIEW_BY_ID = CALENDAR + `/:id`; /**************** Organizations ****************/ const ORGANIZATIONS = `/organizations`; @@ -138,7 +137,6 @@ export const routes = { CALENDAR, NEW_CALENDAR, - DESIGN_REVIEW_BY_ID, ORGANIZATIONS, From e4420b25bc534ba896295f722ee9a58b7f94b84b Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 1 Jan 2026 20:07:46 -0500 Subject: [PATCH 446/477] hook up edit + comment --- src/frontend/src/pages/NewCalendarPage/EventsTable.tsx | 2 +- src/frontend/src/utils/calendar.utils.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx index cfd7586abf..b9d9c367af 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx @@ -315,7 +315,7 @@ const EventsTable: React.FC = ({ {}} + onClick={() => handleEdit(event)} /> )} diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 1b5f1df416..42234691a6 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -159,6 +159,7 @@ export const getEventsFlattened = (events: Event[], startPeriod: Date, endPeriod return occurrences.map(({ event }) => event); }; +// converts an Event into Event Form Values export const convertEventToFormValues = (event: Event): Partial => { return { title: event.title, From de5d780c6c4b2f6696596376dc025bf5ceaf5bee Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Thu, 1 Jan 2026 20:23:38 -0500 Subject: [PATCH 447/477] linting --- .../pages/NewCalendarPage/CalendarDayCard.tsx | 24 +------------------ .../src/pages/NewCalendarPage/NewCalendar.tsx | 1 - 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index 291ead9612..d8320a5938 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Box, Card, CardContent, Grid, IconButton, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; +import { Box, Card, CardContent, Grid, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; import ConstructionIcon from '@mui/icons-material/Construction'; import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; @@ -17,7 +17,6 @@ import DescriptionIcon from '@mui/icons-material/Description'; import ArticleIcon from '@mui/icons-material/Article'; import HelpIcon from '@mui/icons-material/Help'; import GroupsIcon from '@mui/icons-material/Groups'; -import EditIcon from '@mui/icons-material/Edit'; import { EventClickPopup } from './EventClickPopup'; import EventPartialInfoView from './EventPartialInfoView'; @@ -129,27 +128,6 @@ const CalendarDayCard: React.FC = ({ > {name} - - - diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx index bb10d0ae22..1157349e31 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendar.tsx @@ -4,7 +4,6 @@ */ import { Route, Switch } from 'react-router-dom'; import { routes } from '../../utils/routes'; -import DesignReviewDetails from '../CalendarPage/EventDetailPage/EventDetails'; import CalendarTab from './CalendarTab'; const NewCalendar: React.FC = () => { From f1a43f9344807300c1addae81d7e65d298b71908 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 3 Jan 2026 11:49:08 -0500 Subject: [PATCH 448/477] easier to remove warnings --- .../src/pages/NewCalendarPage/NewCalendarPage.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index d604075a34..efa352290a 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -353,7 +353,11 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv icon={} variant="filled" severity="error" + onClick={() => setDeniedEvent(false)} onClose={() => setDeniedEvent(false)} + sx={{ + cursor: 'pointer' + }} > @@ -391,7 +395,11 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv icon={} variant="filled" severity="error" + onClick={() => setPendingEvent(false)} onClose={() => setPendingEvent(false)} + sx={{ + cursor: 'pointer' + }} > You have scheduled an event at the same time and location as {yourConflicts[0].title}.{' '} @@ -405,7 +413,11 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv icon={} variant="filled" severity="error" + onClick={() => setReviewEvent(false)} onClose={() => setReviewEvent(false)} + sx={{ + cursor: 'pointer' + }} > From b3bb2ffc5a4d4da8dfc7e3ba7f0f28d4f844d4c4 Mon Sep 17 00:00:00 2001 From: JoshuaGoldberg Date: Sat, 3 Jan 2026 11:50:59 -0500 Subject: [PATCH 449/477] typo --- src/frontend/src/pages/NewCalendarPage/EventsTable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx index b9d9c367af..70af7215c3 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx @@ -173,8 +173,8 @@ const EventsTable: React.FC = ({ const headCells: readonly YourEventsHeadCells[] = [ { - id: 'eventsName', - label: 'Events Name' + id: 'eventName', + label: 'Event Name' }, { id: 'date', From c2e7a7ebca9246e958bf9885cb2be94fc9ac8eae Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sat, 3 Jan 2026 22:59:13 -0500 Subject: [PATCH 450/477] #3818 requested changes + changing edit modal logic --- .../src/controllers/calendar.controllers.ts | 11 ++ .../src/prisma-query-args/event.query-args.ts | 60 ++++++ src/backend/src/routes/calendar.routes.ts | 2 + src/backend/src/services/calendar.services.ts | 34 +++- .../src/transformers/calendar.transformer.ts | 48 ++++- src/backend/src/utils/calendar.utils.ts | 12 +- src/frontend/src/apis/calendar.api.ts | 6 + .../apis/transformers/calendar.transformer.ts | 16 +- src/frontend/src/hooks/calendar.hooks.ts | 17 +- .../pages/NewCalendarPage/CalendarDayCard.tsx | 14 +- .../src/pages/NewCalendarPage/CalendarTab.tsx | 1 + .../Components/EventAvailabilityPage.tsx | 24 ++- .../NewCalendarPage/Components/EventModal.tsx | 15 +- .../pages/NewCalendarPage/EventClickPopup.tsx | 186 ++++++++---------- .../pages/NewCalendarPage/NewCalendarPage.tsx | 29 ++- src/frontend/src/utils/urls.ts | 2 + src/shared/src/types/calendar-types.ts | 42 +++- 17 files changed, 375 insertions(+), 144 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index f87285309f..22fd4dc0b2 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -498,6 +498,17 @@ export default class CalendarController { } } + static async getSingleEventWithMembers(req: Request, res: Response, next: NextFunction) { + try { + const { eventId } = req.params; + + const event = await CalendarService.getSingleEventWithMembers(req.currentUser, eventId, req.organization); + res.status(200).json(event); + } catch (error: unknown) { + next(error); + } + } + static async getConflictingEvent(req: Request, res: Response, next: NextFunction) { try { const { eventId } = req.params; diff --git a/src/backend/src/prisma-query-args/event.query-args.ts b/src/backend/src/prisma-query-args/event.query-args.ts index 62dbf036df..f90cbc6d1f 100644 --- a/src/backend/src/prisma-query-args/event.query-args.ts +++ b/src/backend/src/prisma-query-args/event.query-args.ts @@ -3,7 +3,67 @@ import { getUserQueryArgs, getUserWithSettingsQueryArgs } from './user.query-arg export type EventQueryArgs = ReturnType; +export type EventWithMembersQueryArgs = ReturnType; + export const getEventQueryArgs = (organizationId: string) => + Prisma.validator()({ + include: { + userCreated: getUserWithSettingsQueryArgs(organizationId), + requiredMembers: getUserQueryArgs(organizationId), + optionalMembers: getUserQueryArgs(organizationId), + confirmedMembers: getUserWithSettingsQueryArgs(organizationId), + deniedMembers: getUserQueryArgs(organizationId), + teams: { + select: { + teamName: true, + teamId: true + } + }, + teamType: { + select: { + teamTypeId: true, + name: true + } + }, + shops: { + select: { + name: true, + shopId: true + } + }, + machinery: { + select: { + name: true, + machineryId: true + } + }, + workPackages: { + select: { + wbsElement: { + select: { + name: true, + carNumber: true, + projectNumber: true, + workPackageNumber: true + } + }, + project: { + include: { + wbsElement: true, + teams: true + } + }, + workPackageId: true + } + }, + approvalRequiredBy: getUserQueryArgs(organizationId), + scheduledTimes: true, + notificationSlackThreads: true, + documents: true + } + }); + +export const getEventWithMembersQueryArgs = (organizationId: string) => Prisma.validator()({ include: { userCreated: getUserWithSettingsQueryArgs(organizationId), diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 73d46cf744..1e52e3f3a0 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -199,6 +199,8 @@ calendarRouter.get('/event/:eventId/conflict', CalendarController.getConflicting calendarRouter.get('/event/:eventId', CalendarController.getSingleEvent); +calendarRouter.get('/event-members/:eventId', CalendarController.getSingleEventWithMembers); + calendarRouter.get('/events', CalendarController.getAllEvents); calendarRouter.get('/event-types', CalendarController.getAllEventTypes); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 90b85fd873..a2cf4731a7 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -1,4 +1,9 @@ -import { calendarTransformer, eventTransformer, machineryTransformer } from '../transformers/calendar.transformer'; +import { + calendarTransformer, + eventTransformer, + eventWithMembersTransformer, + machineryTransformer +} from '../transformers/calendar.transformer'; import { getMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { Conflict_Status, Event_Status, Organization } from '@prisma/client'; import { @@ -39,7 +44,7 @@ import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-arg import { shopTransformer } from '../transformers/calendar.transformer'; import { getShopQueryArgs } from '../prisma-query-args/shop.query-args'; import { getCalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; -import { getEventQueryArgs } from '../prisma-query-args/event.query-args'; +import { getEventQueryArgs, getEventWithMembersQueryArgs } from '../prisma-query-args/event.query-args'; import { buildScheduledTimesOverlap, checkEventConflicts, @@ -1144,13 +1149,13 @@ export default class CalendarService { ): Promise { const event = await prisma.event.findUnique({ where: { eventId }, - ...getEventQueryArgs(organization.organizationId) + ...getEventWithMembersQueryArgs(organization.organizationId) }); if (!event) throw new NotFoundException('Event', eventId); if (event.dateDeleted) throw new DeletedException('Event', eventId); - if (!isUserOnEvent(submitter, eventTransformer(event))) + if (!isUserOnEvent(submitter, eventWithMembersTransformer(event))) throw new HttpException(400, 'Current user is not in the list of this events members'); let userSettings = await prisma.schedule_Settings.findUnique({ @@ -2374,6 +2379,27 @@ export default class CalendarService { return eventTransformer(event); } + /** + * Retrieves a single event + * + * @param submitter the user who is trying to retrieve the event + * @param eventId the id of the event to retrieve + * @param organizationId the organization that the user is currently in + * @returns the event + */ + static async getSingleEventWithMembers(_submitter: User, eventId: string, organization: Organization): Promise { + const event = await prisma.event.findUnique({ + where: { eventId }, + ...getEventWithMembersQueryArgs(organization.organizationId) + }); + + if (!event) throw new NotFoundException('Event', eventId); + + if (event.dateDeleted) throw new DeletedException('Event', eventId); + + return eventTransformer(event); + } + /** * Retrieves a potential conflicting event * If no conflict exists, returns the original event diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 06b5f5633d..681bc5d593 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -16,13 +16,14 @@ import { EventPreview, DayOfWeek, ConflictStatus, - Document + Document, + EventWithMembers } from 'shared'; import { MachineryQueryArgs, ShopMachineryQueryArgs } from '../prisma-query-args/machinery.query-args'; import { userTransformer, userWithScheduleSettingsTransformer } from './user.transformer'; import { EventTypeQueryArgs } from '../prisma-query-args/event-type.query-args'; import { CalendarQueryArgs } from '../prisma-query-args/calendar.query-args'; -import { EventQueryArgs } from '../prisma-query-args/event.query-args'; +import { EventQueryArgs, EventWithMembersQueryArgs } from '../prisma-query-args/event.query-args'; import { ShopQueryArgs } from '../prisma-query-args/shop.query-args'; export const documentTransformer = (document: Prisma.DocumentGetPayload): Document => { @@ -140,6 +141,49 @@ export const eventTransformer = (event: Prisma.EventGetPayload): }; }; +export const eventWithMembersTransformer = (event: Prisma.EventGetPayload): EventWithMembers => { + return { + eventId: event.eventId, + title: event.title, + userCreated: userWithScheduleSettingsTransformer(event.userCreated), + dateCreated: event.dateCreated, + eventTypeId: event.eventTypeId, + requiredMembers: event.requiredMembers.map(userTransformer), + optionalMembers: event.optionalMembers.map(userTransformer), + confirmedMembers: event.confirmedMembers.map(userWithScheduleSettingsTransformer), + deniedMembers: event.deniedMembers.map(userTransformer), + teams: event.teams.map((team) => ({ + ...team, + members: team.members.map(userTransformer), + leads: team.leads.map(userTransformer), + head: userTransformer(team.head) + })), + teamType: event.teamType + ? { + teamTypeId: event.teamType.teamTypeId, + name: event.teamType.name, + teams: event.teamType.teams.map((team) => ({ + members: team.members.map(userTransformer), + leads: team.leads.map(userTransformer), + head: userTransformer(team.head) + })) + } + : undefined, + shops: event.shops, + machinery: event.machinery, + workPackages: event.workPackages, + documents: event.documents.filter((document) => !document.dateDeleted).map(documentTransformer), + scheduledTimes: event.scheduledTimes.map(scheduleTimesTransformer), + approved: conflictStatusTransformer(event.approved), + approvalRequiredFrom: event.approvalRequiredBy ?? undefined, + location: event.location ?? undefined, + zoomLink: event.zoomLink ?? undefined, + questionDocumentLink: event.questionDocumentLink ?? undefined, + description: event.description ?? undefined, + status: eventStatusTransformer(event.status) + }; +}; + export const eventPreviewTransformer = (event: Prisma.EventGetPayload, wbsName: string): EventPreview => { // Get the earliest scheduled date from scheduledTimes const dateScheduled = event.scheduledTimes.length > 0 ? event.scheduledTimes[0].initialDateScheduled : new Date(); diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index 6128f8f6ec..fa07f5c4f1 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -1,5 +1,13 @@ import { Prisma, Event_Type, Organization } from '@prisma/client'; -import { User, ScheduleSlotCreateArgs, EventDocumentCreateArgs, Document, ConflictStatus, Event } from 'shared'; +import { + User, + ScheduleSlotCreateArgs, + EventDocumentCreateArgs, + Document, + ConflictStatus, + Event, + EventWithMembers +} from 'shared'; import { InvalidEventTypeConfigurationException } from './errors.utils'; import prisma from '../prisma/prisma'; import { getEventQueryArgs } from '../prisma-query-args/event.query-args'; @@ -15,7 +23,7 @@ export function buildScheduledTimesOverlap(start?: Date, end?: Date): Prisma.Sch return { some: { AND } }; } -export const isUserOnEvent = (user: User, event: Event): boolean => { +export const isUserOnEvent = (user: User, event: EventWithMembers): boolean => { // Check if user is directly a required or optional member const isDirectMember = event.requiredMembers.some((member) => member.userId === user.userId) || diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index da94f0767b..202a2fbeac 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -126,6 +126,12 @@ export const getSingleEvent = async (id: string) => { }); }; +export const getSingleEventWithMembers = async (id: string) => { + return axios.get(apiUrls.calendarGetSingleEventWithMembers(id), { + transformResponse: (data) => eventTransformer(JSON.parse(data)) + }); +}; + export const getConflictingEvent = async (id: string) => { return axios.get(apiUrls.calendarGetConflictingEvent(id), { transformResponse: (data) => eventTransformer(JSON.parse(data)) diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts index 6f75053806..978c5ad74c 100644 --- a/src/frontend/src/apis/transformers/calendar.transformer.ts +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -1,4 +1,4 @@ -import { Shop, Event, EventPreview } from 'shared'; +import { Shop, Event, EventPreview, EventWithMembers } from 'shared'; import { userTransformer } from './users.transformers'; export const shopTransformer = (shop: Shop): Shop => { @@ -27,6 +27,20 @@ export const eventTransformer = (event: Event): Event => { }; }; +export const eventWithMembersTransformer = (event: EventWithMembers): EventWithMembers => { + return { + ...event, + dateCreated: new Date(event.dateCreated), + scheduledTimes: event.scheduledTimes.map((slot: any) => ({ + ...slot, + startTime: slot.startTime ? new Date(slot.startTime) : undefined, + endTime: slot.endTime ? new Date(slot.endTime) : undefined, + initialDateScheduled: new Date(slot.initialDateScheduled), + endDate: new Date(slot.endDate) + })) + }; +}; + export const eventPreviewTransformer = (event: EventPreview): EventPreview => { return { eventId: event.eventId, diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index c39d476e90..605e7bda87 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -9,7 +9,8 @@ import { EventStatus, EventType, FilterArgs, - ScheduleSlotCreateArgs + ScheduleSlotCreateArgs, + EventWithMembers } from 'shared'; import { getAllShops, @@ -41,7 +42,8 @@ import { postCreateEvent, uploadSingleDocument, downloadDocumentPdf, - postEditEvent + postEditEvent, + getSingleEventWithMembers } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; import { PDFDocument } from 'pdf-lib'; @@ -345,6 +347,17 @@ export const useSingleEvent = (id?: string) => { ); }; +export const useSingleEventWithMembers = (id?: string) => { + return useQuery( + ['events', id, 'with-members'], + async () => { + const { data } = await getSingleEventWithMembers(id!); + return data; + }, + { enabled: !!id } + ); +}; + export const useConflictingEvents = (ids: string[]) => { return useQuery(['events', 'conflicting', ids], async () => { const results = await Promise.all( diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx index da952352b9..f806b30ab8 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { JSX, useState } from 'react'; import { Box, Card, CardContent, Grid, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; import ConstructionIcon from '@mui/icons-material/Construction'; @@ -21,6 +21,8 @@ import GroupsIcon from '@mui/icons-material/Groups'; import { EventClickPopup } from './EventClickPopup'; import EventPartialInfoView from './EventPartialInfoView'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; +import { EventRoutePayload } from './Components/EventModal'; +import { EditEventArgs } from '../../hooks/calendar.hooks'; export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { const teamIcons: Map = new Map([ @@ -50,6 +52,12 @@ interface CalendarDayCardProps { eventTypes?: EventType[]; calendars?: Calendar[]; dayOfWeek?: DayOfWeek; + handleEditSubmit: ( + data: EventRoutePayload, + event: Event, + editEvent: (editArgs: EditEventArgs) => Promise, + onClose: () => void + ) => Promise; } const CalendarDayCard: React.FC = ({ @@ -57,7 +65,8 @@ const CalendarDayCard: React.FC = ({ events, eventTypes = [], calendars = [], - dayOfWeek = DayOfWeek.MONDAY + dayOfWeek = DayOfWeek.MONDAY, + handleEditSubmit }) => { const [, setIsCreateModalOpen] = useState(false); const theme = useTheme(); @@ -476,6 +485,7 @@ const CalendarDayCard: React.FC = ({ calendars={calendars} dayOfWeek={dayOfWeek} clickedDate={cardDate} + handleEditSubmit={handleEditSubmit} /> ); diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx index 7e93d3e958..ffda67ec92 100644 --- a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx @@ -169,6 +169,7 @@ const CalendarTab: React.FC = () => { reviewEvents={reviewEvents ?? []} yourEvents={yourEvents ?? []} allCalendars={allCalendars} + handleEditSubmit={handleEditSubmit} /> ) : ( { +const isUserOnEvent = (user: User, event: EventWithMembers): boolean => { const isDirectMember = event.requiredMembers?.some((member: User) => member.userId === user.userId) || event.optionalMembers?.some((member: User) => member.userId === user.userId); @@ -39,7 +32,7 @@ const isUserOnEvent = (user: User, event: Event): boolean => { if (isDirectMember) return true; const isOnEventTeam = event.teams?.some( - (team: TeamCalendarPreview) => + (team) => team.members?.some((member: User) => member.userId === user.userId) || team.leads?.some((lead: User) => lead.userId === user.userId) || team.head?.userId === user.userId @@ -49,7 +42,7 @@ const isUserOnEvent = (user: User, event: Event): boolean => { if (event.teamType?.teams) { const isOnTeamType = event.teamType.teams.some( - (team: TeamCalendarPreview) => + (team) => team.members?.some((member: User) => member.userId === user.userId) || team.leads?.some((lead: User) => lead.userId === user.userId) || team.head?.userId === user.userId @@ -77,7 +70,12 @@ export const EventAvailabilityPage: React.FC = () => { const [currentAvailableUsers, setCurrentAvailableUsers] = useState([]); const [currentUnavailableUsers, setCurrentUnavailableUsers] = useState([]); - const { data: event, isError: eventError, error: eventErrorMsg, isLoading: eventLoading } = useSingleEvent(eventId); + const { + data: event, + isError: eventError, + error: eventErrorMsg, + isLoading: eventLoading + } = useSingleEventWithMembers(eventId); const { data: userScheduleSettings, diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx index 4b2231116b..0c7fc3f15d 100644 --- a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { Box, FormControl, @@ -247,12 +247,8 @@ const EventModal: React.FC = ({ }); }, [machinery, shops, shopIds]); - const hasInitialized = useRef(false); - useEffect(() => { - if (open && !hasInitialized.current) { - hasInitialized.current = true; - + if (open) { reset(defaultFormData); if (initialValues?.requiredMemberIds && users) { @@ -275,11 +271,10 @@ const EventModal: React.FC = ({ .map((t) => ({ id: t.teamId, label: t.teamName })); setSelectedTeams(teamOptions); } - } - // Reset the ref when modal closes - if (!open) { - hasInitialized.current = false; + if (initialValues?.days && initialValues.days.length > 0) { + setShowRecurringOptions(true); + } } }, [open, defaultFormData, initialValues, users, teams, reset]); diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx index 009f7efb0d..eaca76cc17 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { JSX, useState } from 'react'; import { Box, Button, IconButton, Link, Popover, Stack, Typography, useTheme } from '@mui/material'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; @@ -22,21 +22,17 @@ import DescriptionIcon from '@mui/icons-material/Description'; import HelpIcon from '@mui/icons-material/Help'; import EditIcon from '@mui/icons-material/Edit'; import PeopleIcon from '@mui/icons-material/People'; +import DeleteIcon from '@mui/icons-material/Delete'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; import NERSuccessButton from '../../components/NERSuccessButton'; import NERFailButton from '../../components/NERFailButton'; -import { - EditEventArgs, - useApproveEvent, - useDenyEvent, - useEditEvent, - useUploadManyDocuments -} from '../../hooks/calendar.hooks'; -import { convertDayToDayShorthand } from '../../utils/calendar.utils'; +import { EditEventArgs, useApproveEvent, useDeleteEvent, useDenyEvent, useEditEvent } from '../../hooks/calendar.hooks'; +import { convertDayToDayShorthand, convertEventToFormValues } from '../../utils/calendar.utils'; import EditEventModal from './Components/EditEventModal'; -import { EventFormValues, EventRoutePayload } from './Components/EventModal'; import { useToast } from '../../hooks/toasts.hooks'; +import NERDeleteModal from '../../components/NERDeleteModal'; +import { EventRoutePayload } from './Components/EventModal'; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ @@ -61,6 +57,7 @@ interface EventClickContentProps { addApprovalButtons: boolean; onClose: () => void; onEdit: (event: Event) => void; + onDelete: (event: Event) => void; clickedDate?: Date; } @@ -81,6 +78,7 @@ const EventClickContent: React.FC = ({ addApprovalButtons, onClose, onEdit, + onDelete, clickedDate }) => { const { mutateAsync: approveEvent } = useApproveEvent(event.eventId); @@ -133,25 +131,40 @@ const EventClickContent: React.FC = ({ > {!disable && ( - { - stopClick(e); - onEdit(event); - }} - sx={{ - position: 'absolute', - top: 0, - right: 0, - color: theme.palette.grey[500], - '&:hover': { - color: theme.palette.common.white, - bgcolor: 'transparent' - } - }} - > - - + + { + stopClick(e); + onEdit(event); + }} + sx={{ + color: theme.palette.grey[500], + '&:hover': { + color: theme.palette.common.white, + bgcolor: 'transparent' + } + }} + > + + + { + stopClick(e); + onDelete(event); + }} + sx={{ + color: theme.palette.grey[500], + '&:hover': { + color: '#ef5350', + bgcolor: 'transparent' + } + }} + > + + + )} {getTeamTypeIcon(event.teamType?.name ?? '', true)} @@ -418,6 +431,12 @@ export interface EventClickPopupProps { disable?: boolean; addApprovalButtons?: boolean; clickedDate?: Date; + handleEditSubmit: ( + data: EventRoutePayload, + event: Event, + editEvent: (editArgs: EditEventArgs) => Promise, + onClose: () => void + ) => Promise; } export const EventClickPopup: React.FC = ({ @@ -429,91 +448,30 @@ export const EventClickPopup: React.FC = ({ dayOfWeek, disable = false, addApprovalButtons = false, - clickedDate + clickedDate, + handleEditSubmit }) => { const toast = useToast(); const [showEditModal, setShowEditModal] = useState(false); + const [showDeleteModal, setShowDeleteModal] = useState(false); + const { mutateAsync: deleteEvent } = useDeleteEvent(clickedEvent?.eventId ?? ''); const { mutateAsync: editEvent } = useEditEvent(clickedEvent?.eventId ?? ''); - const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); - - const convertEventToFormValues = (event: Event): Partial => { - return { - title: event.title, - eventTypeId: event.eventTypeId, - requiredMemberIds: event.requiredMembers.map((m) => m.userId), - optionalMemberIds: event.optionalMembers.map((m) => m.userId), - teamIds: event.teams.map((t) => t.teamId), - teamTypeId: event.teamType?.teamTypeId, - location: event.location, - zoomLink: event.zoomLink, - shopIds: event.shops.map((s) => s.shopId), - machineryIds: event.machinery.map((m) => m.machineryId), - workPackageIds: event.workPackages.map((wp) => wp.workPackageId), - documentFiles: event.documents.map((doc) => ({ - name: doc.name, - googleFileId: doc.googleFileId - })), - questionDocumentLink: event.questionDocumentLink, - description: event.description, - scheduleDate: event.scheduledTimes[0]?.initialDateScheduled - ? new Date(event.scheduledTimes[0].initialDateScheduled) - : new Date(), - startTime: event.scheduledTimes[0]?.startTime ? new Date(event.scheduledTimes[0].startTime) : undefined, - endTime: event.scheduledTimes[0]?.endTime ? new Date(event.scheduledTimes[0].endTime) : undefined, - allDay: event.scheduledTimes[0]?.allDay ?? false, - recurrenceNumber: event.scheduledTimes[0]?.recurrenceNumber ?? 0, - days: event.scheduledTimes[0]?.days ?? [] - }; - }; const handleEdit = () => { setShowEditModal(true); }; - const handleEditSubmit = async (data: EventRoutePayload) => { - if (!clickedEvent) return; + const handleDelete = () => { + setShowDeleteModal(true); + }; + const handleDeleteConfirm = async () => { try { - const { scheduleSlot, documentFiles, ...eventData } = data; - - if (!scheduleSlot || scheduleSlot.length === 0) { - throw new Error('Missing scheduleSlot'); - } - - // Convert EventRoutePayload to EditEventArgs format - const editArgs: EditEventArgs = { - ...eventData, - status: clickedEvent.status, // Use existing event status - documents: clickedEvent.documents.map((doc) => ({ - name: doc.name, - googleFileId: doc.googleFileId - })), - scheduleSlot: scheduleSlot.map((slot) => ({ - days: slot.days, - startTime: slot.startTime, - endTime: slot.endTime, - recurrenceNumber: slot.recurrenceNumber, - initialDateScheduled: slot.initialDateScheduled, - allDay: slot.allDay - })) - }; - - const editedEvent = await editEvent(editArgs); - - // Upload new documents if any - const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); - - if (filesToUpload.length > 0) { - await uploadDocuments({ - id: editedEvent.eventId, - files: filesToUpload - }); - } - - toast.success('Event updated successfully!'); - setShowEditModal(false); + setShowDeleteModal(false); onClose(); + await deleteEvent(); + toast.success('Event deleted successfully!'); } catch (err) { if (err instanceof Error) { toast.error(err.message); @@ -546,6 +504,7 @@ export const EventClickPopup: React.FC = ({ addApprovalButtons={addApprovalButtons} onClose={onClose} onEdit={handleEdit} + onDelete={handleDelete} clickedDate={clickedDate} /> )} @@ -556,9 +515,32 @@ export const EventClickPopup: React.FC = ({ setShowEditModal(false); onClose(); }} - onSubmit={handleEditSubmit} + onSubmit={(data) => + handleEditSubmit(data, clickedEvent, editEvent, () => { + setShowEditModal(false); + onClose(); + }) + } initialValues={convertEventToFormValues(clickedEvent)} eventTypes={eventTypes} + defaultDate={ + clickedEvent.scheduledTimes[0]?.initialDateScheduled + ? new Date(clickedEvent.scheduledTimes[0].initialDateScheduled) + : new Date() + } + /> + )} + + {clickedEvent && showDeleteModal && ( + { + setShowDeleteModal(false); + onClose(); + }} + formId="delete-event-form" + dataType={clickedEvent.title} + onFormSubmit={handleDeleteConfirm} /> )} diff --git a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx index 4810df76aa..f7f54b9af0 100644 --- a/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/NewCalendarPage/NewCalendarPage.tsx @@ -20,7 +20,13 @@ import PageLayout from '../../components/PageLayout'; import { Calendar, ConflictStatus, DayOfWeek, Event, EventType } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; -import { useConflictingEvents, useFilterEvents, useCreateEvent, useUploadManyDocuments } from '../../hooks/calendar.hooks'; +import { + useConflictingEvents, + useFilterEvents, + useCreateEvent, + useUploadManyDocuments, + EditEventArgs +} from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; @@ -47,9 +53,21 @@ interface NewCalendarPageProps { yourEvents: Event[]; reviewEvents: Event[]; allCalendars: Calendar[]; + handleEditSubmit: ( + data: EventRoutePayload, + event: Event, + editEvent: (editArgs: EditEventArgs) => Promise, + onClose: () => void + ) => Promise; } -const NewCalendarPage: React.FC = ({ allEventTypes, yourEvents, reviewEvents, allCalendars }) => { +const NewCalendarPage: React.FC = ({ + allEventTypes, + yourEvents, + reviewEvents, + allCalendars, + handleEditSubmit +}) => { const toast = useToast(); const theme = useTheme(); const { @@ -348,7 +366,7 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv maxWidth: 600 }} > - {deniedEvent && ( + {deniedEvent && yourConflictsDenied.length > 0 && ( } variant="filled" @@ -390,7 +408,7 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv )} - {pendingEvent && ( + {pendingEvent && yourConflicts.length > 0 && ( } variant="filled" @@ -408,7 +426,7 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv has been notified of this and must allow your event to take place in order to continue. )} - {reviewEvent && ( + {reviewEvent && yourReviewEvents.length > 0 && ( } variant="filled" @@ -535,6 +553,7 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv dayDict.get(datePipe(new Date(cardDate.getTime() + cardDate.getTimezoneOffset() * 60000))) ?? DayOfWeek.SUNDAY } + handleEditSubmit={handleEditSubmit} /> diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 636a86dd88..508ff4fed1 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -462,6 +462,7 @@ const calendarEditEventType = (eventTypeId: string) => `${calendar()}/event-type const calendarDeleteEventType = (eventTypeId: string) => `${calendar()}/event-type/${eventTypeId}/delete`; const calendarEventMarkUserConfirmed = (id: string) => `${calendar()}/event/${id}/confirm-schedule`; const calendarGetSingleEvent = (id: string) => `${calendar()}/event/${id}`; +const calendarGetSingleEventWithMembers = (id: string) => `${calendar()}/event-members/${id}`; const calendarGetConflictingEvent = (id: string) => `${calendar()}/event/${id}/conflict`; const calendarDeleteEvent = (id: string) => `${calendar()}/event/${id}/delete`; const calendarEventSetStatus = (id: string) => `${calendar()}/event/${id}/set-status`; @@ -786,6 +787,7 @@ export const apiUrls = { calendarEditShop, calendarEventMarkUserConfirmed, calendarGetSingleEvent, + calendarGetSingleEventWithMembers, calendarGetConflictingEvent, calendarEvents, calendarEventTypes, diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index cc57c23440..a573ec5718 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -28,6 +28,11 @@ export interface MachineryPreview { export interface TeamCalendarPreview { teamId: string; teamName: string; +} + +export interface TeamWithMembers { + teamId: string; + teamName: string; members: User[]; leads: User[]; head: User; @@ -36,7 +41,16 @@ export interface TeamCalendarPreview { export interface TeamTypeCalendarPreview { teamTypeId: string; name: string; - teams: TeamCalendarPreview[]; +} + +export interface TeamTypeWithMembersCalendarPreview { + teamTypeId: string; + name: string; + teams: { + members: User[]; + leads: User[]; + head: User; + }[]; } export interface WorkPackageCalendarPreview { @@ -215,3 +229,29 @@ export type EventPreview = { userCreated: User; wbsName: string; }; + +export interface EventWithMembers { + eventId: string; + title: string; + approved: ConflictStatus; + userCreated: UserWithScheduleSettings; + dateCreated: Date; + eventTypeId: string; + approvalRequiredFrom?: User; + scheduledTimes: ScheduleSlot[]; + requiredMembers: User[]; + optionalMembers: User[]; + confirmedMembers: UserWithScheduleSettings[]; + deniedMembers: User[]; + teams: TeamWithMembers[]; + teamType?: TeamTypeWithMembersCalendarPreview; + location?: string; + zoomLink?: string; + shops: ShopPreview[]; + machinery: MachineryPreview[]; + workPackages: WorkPackageCalendarPreview[]; + documents: Document[]; + questionDocumentLink?: string; + description?: string; + status: EventStatus; +} From b02f4454595402a3ccf6ef11cadb5cf4ee883b48 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sat, 3 Jan 2026 23:15:57 -0500 Subject: [PATCH 451/477] #3818 files --- .../CalendarDayCard.tsx | 0 .../CalendarTab.tsx | 0 .../Components/CreateEventModal.tsx | 0 .../Components/EditEventModal.tsx | 0 .../Components/EventAvailabilityPage.tsx | 0 .../Components/EventModal.tsx | 0 .../Components/EventTimeSlot.tsx | 0 .../CalendarPage/EventAvailabilityInfo.tsx | 77 ----- .../EventClickPopup.tsx | 0 .../AvailabilityScheduleView.tsx | 134 -------- .../EventDetailPage/AvailabilityView.tsx | 137 -------- .../EventDetailPage/EventDetailPage.tsx | 311 ------------------ .../EventDetailPage/EventDetails.tsx | 21 -- .../FinalizeEventDetailsModal.tsx | 199 ----------- .../EventDetailPage/UserAvailabilitesView.tsx | 152 --------- .../EventPartialInfoView.tsx | 0 .../EventsTable.tsx | 1 + .../FilterModal.tsx | 0 .../NewCalendar.tsx | 0 .../NewCalendarPage.tsx | 0 .../SchedulingConflictsWarning.tsx | 0 .../UpcomingMeetingsCard.tsx | 0 .../YourEventsComponents/TableCellHuge.tsx | 0 .../YourEventsComponents/WarningTooltip.tsx | 0 .../Availability/EditAvailability.tsx | 2 +- .../Availability/SingleAvailabilityView.tsx | 2 +- src/frontend/src/utils/calendar.utils.ts | 2 +- 27 files changed, 4 insertions(+), 1034 deletions(-) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/CalendarDayCard.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/CalendarTab.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/Components/CreateEventModal.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/Components/EditEventModal.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/Components/EventAvailabilityPage.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/Components/EventModal.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/Components/EventTimeSlot.tsx (100%) delete mode 100644 src/frontend/src/pages/CalendarPage/EventAvailabilityInfo.tsx rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/EventClickPopup.tsx (100%) delete mode 100644 src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetails.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx delete mode 100644 src/frontend/src/pages/CalendarPage/EventDetailPage/UserAvailabilitesView.tsx rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/EventPartialInfoView.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/EventsTable.tsx (99%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/FilterModal.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/NewCalendar.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/NewCalendarPage.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/SchedulingConflictsWarning.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/UpcomingMeetingsCard.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/YourEventsComponents/TableCellHuge.tsx (100%) rename src/frontend/src/pages/{NewCalendarPage => CalendarPage}/YourEventsComponents/WarningTooltip.tsx (100%) diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/CalendarDayCard.tsx rename to src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/CalendarTab.tsx rename to src/frontend/src/pages/CalendarPage/CalendarTab.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/Components/CreateEventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/Components/CreateEventModal.tsx rename to src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/Components/EditEventModal.tsx rename to src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx b/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/Components/EventAvailabilityPage.tsx rename to src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/Components/EventModal.tsx rename to src/frontend/src/pages/CalendarPage/Components/EventModal.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx b/src/frontend/src/pages/CalendarPage/Components/EventTimeSlot.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/Components/EventTimeSlot.tsx rename to src/frontend/src/pages/CalendarPage/Components/EventTimeSlot.tsx diff --git a/src/frontend/src/pages/CalendarPage/EventAvailabilityInfo.tsx b/src/frontend/src/pages/CalendarPage/EventAvailabilityInfo.tsx deleted file mode 100644 index 3ed2a75a4b..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventAvailabilityInfo.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { Event } from 'shared'; -import { Grid, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; -import ColumnHeader from '../FinancePage/FinanceComponents/ColumnHeader'; -import { fullNamePipe } from '../../utils/pipes'; - -interface EventAvailabilityInfoProps { - event: Event; -} - -export const EventAvailabilityInfo: React.FC = ({ event }) => { - return ( - - - - - - - Required - - - - - - - - {event.requiredMembers.map((member) => ( - - - {fullNamePipe(member)} - - - - {event.confirmedMembers.some((confirmedMember) => confirmedMember.userId === member.userId) - ? 'Yes' - : 'No'} - - - - ))} - -
-
-
- - - - - - Optional - - - - - - - - {event.optionalMembers.map((member) => ( - - - {fullNamePipe(member)} - - - - {event.confirmedMembers.some((confirmedMember) => confirmedMember.userId === member.userId) - ? 'Yes' - : 'No'} - - - - ))} - -
-
-
-
- ); -}; diff --git a/src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/EventClickPopup.tsx rename to src/frontend/src/pages/CalendarPage/EventClickPopup.tsx diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx deleted file mode 100644 index 37ad0201b0..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityScheduleView.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; -import { Availability, Event, getDayOfWeek, getNextSevenDays, User } from 'shared'; -import { enumToArray, REVIEW_TIMES, getBackgroundColor, NUMBER_OF_TIME_SLOTS } from '../../../utils/design-review.utils'; -import React, { useState } from 'react'; -import { datePipe } from '../../../utils/pipes'; -import EventTimeSlot from '../../NewCalendarPage/Components/EventTimeSlot'; - -interface AvailabilityScheduleViewProps { - availableUsers: Map; - unavailableUsers: Map; - usersToAvailabilities: Map; - setCurrentAvailableUsers: (val: User[]) => void; - setCurrentUnavailableUsers: (val: User[]) => void; - event: Event; - displayDate?: Date; -} - -const AvailabilityScheduleView: React.FC = ({ - availableUsers, - unavailableUsers, - usersToAvailabilities, - setCurrentAvailableUsers, - setCurrentUnavailableUsers, - event, - displayDate -}) => { - const totalUsers = usersToAvailabilities.size; - const [selectedTimeslot, setSelectedTimeslot] = useState(null); - // Use displayDate if provided, otherwise fall back to event's initial date - const initialDate = displayDate || event.scheduledTimes[0]?.initialDateScheduled || new Date(); - const potentialDays = getNextSevenDays(initialDate); - - const handleTimeslotClick = (index: number, _day: Date) => { - if (selectedTimeslot === index) { - setSelectedTimeslot(null); - setCurrentAvailableUsers([]); - setCurrentUnavailableUsers([]); - } else { - setSelectedTimeslot(index); - setCurrentAvailableUsers(availableUsers.get(index) || []); - setCurrentUnavailableUsers(unavailableUsers.get(index) || []); - } - }; - - // Populates the availableUsers map - for (let time = 0; time < NUMBER_OF_TIME_SLOTS; time++) { - availableUsers.set(time, []); - } - usersToAvailabilities.forEach((availabilities, user) => { - let i = 0; - availabilities.forEach((availability) => { - availability.availability.forEach((time) => { - const usersAtTime = availableUsers.get(enumToArray(REVIEW_TIMES).length * i + time) || []; - usersAtTime.push(user); - availableUsers.set(enumToArray(REVIEW_TIMES).length * i + time, usersAtTime); - }); - i++; - }); - }); - - // Populates the unavailableUsers map - const allUsers = [...usersToAvailabilities.keys()]; - for (let time = 0; time < NUMBER_OF_TIME_SLOTS; time++) { - const currentUsers = availableUsers.get(time) || []; - const currentUnavailableUsers = allUsers.filter((user) => !currentUsers.includes(user)); - unavailableUsers.set(time, currentUnavailableUsers); - } - - const stickyLeft = { - position: 'sticky', - left: 0, - zIndex: 2, - bgcolor: 'background.paper' - }; - - return ( - - - - - - {potentialDays.map((day) => ( - - - {getDayOfWeek(day) + ' ' + datePipe(day)} - - - ))} - - - - {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( - - - - {time} - - - {potentialDays.map((day, dayIndex) => { - const index = dayIndex * enumToArray(REVIEW_TIMES).length + timeIndex; - return ( - - handleTimeslotClick(index, day)} - /> - - ); - })} - - ))} - -
-
- ); -}; - -export default AvailabilityScheduleView; diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx deleted file mode 100644 index 12ed72d152..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/AvailabilityView.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { Grid } from '@mui/material'; -import { Availability, Event, EventStatus, getMostRecentAvailabilities, User, UserWithScheduleSettings } from 'shared'; -import { useState } from 'react'; -import AvailabilityScheduleView from './AvailabilityScheduleView'; -import UserAvailabilites from './UserAvailabilitesView'; -import { getWeekDateRange } from '../../../utils/design-review.utils'; -import { FinalizeEventInformation } from './EventDetailPage'; -import { useManyUsersWithScheduleSettings } from '../../../hooks/users.hooks'; -import LoadingIndicator from '../../../components/LoadingIndicator'; -import ErrorPage from '../../ErrorPage'; - -interface AvailabilityViewProps { - event: Event; - allEvents: Event[]; - handleEdit: (data?: FinalizeEventInformation) => void; - selectedDate: Date; - startTime: number; - endTime: number; - requiredUserIds: string[]; - optionalUserIds: string[]; -} - -const AvailabilityView: React.FC = ({ - event, - allEvents, - handleEdit, - selectedDate, - startTime, - endTime, - requiredUserIds, - optionalUserIds -}) => { - const { - data: relevantUsers, - isLoading, - isError, - error - } = useManyUsersWithScheduleSettings([...requiredUserIds, ...optionalUserIds]); - - const availableUsers = new Map(); - const unavailableUsers = new Map(); - const existingMeetingData = new Map(); - const usersToAvailabilities = new Map(); - - const [currentAvailableUsers, setCurrentAvailableUsers] = useState([]); - const [currentUnavailableUsers, setCurrentUnavailableUsers] = useState([]); - const [startDateRange, endDateRange] = getWeekDateRange(selectedDate); - - if (isLoading || !relevantUsers) return ; - if (isError) return ; - - // Get events within the current week - const currentWeekEvents = allEvents.filter((currEvent) => { - const eventDate = currEvent.scheduledTimes[0]?.initialDateScheduled; - if (!eventDate) return false; - - const drDate = new Date(eventDate).getTime(); - const startRange = startDateRange.getTime(); - const endRange = endDateRange.getTime(); - - return drDate >= startRange && drDate <= endRange; - }); - - // Find conflicting events for the selected time - const conflictingEvents = allEvents.filter((currEvent) => { - if (currEvent.eventId === event.eventId) return false; - if (currEvent.status !== EventStatus.SCHEDULED) return false; - - const eventDate = currEvent.scheduledTimes[0]?.initialDateScheduled; - if (!eventDate) return false; - - const cleanDate = new Date(eventDate.getTime() - eventDate.getTimezoneOffset() * -60000); - - // Check if event is on the selected date - if (cleanDate.toLocaleDateString() !== selectedDate.toLocaleDateString()) return false; - - // Check if any scheduled times overlap with selected time range - return currEvent.scheduledTimes.some((slot) => { - if (!slot.startTime) return false; - const slotHour = new Date(slot.startTime).getHours(); - return slotHour >= startTime + 10 && slotHour < endTime + 10; - }); - }); - - // Map existing scheduled events to time slots for visualization - currentWeekEvents.forEach((ev) => { - if (ev.status === EventStatus.SCHEDULED && ev.eventId !== event.eventId) { - ev.scheduledTimes.forEach((slot) => { - if (slot.startTime) { - const hour = new Date(slot.startTime).getHours(); - const timeIndex = hour - 10; // Convert back to 0-11 index - if (timeIndex >= 0 && timeIndex < 12) { - existingMeetingData.set(timeIndex, ev.teamType?.name || 'default'); - } - } - }); - } - }); - - // Get the initial date for availability lookup - const initialDate = event.scheduledTimes[0]?.initialDateScheduled || new Date(); - - relevantUsers.forEach((user: UserWithScheduleSettings) => { - const availability = getMostRecentAvailabilities(user.scheduleSettings?.availabilities ?? [], initialDate); - - usersToAvailabilities.set(user, availability ?? []); - }); - - return ( - - - - - - - - - ); -}; - -export default AvailabilityView; diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx deleted file mode 100644 index ba8c7f0c52..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetailPage.tsx +++ /dev/null @@ -1,311 +0,0 @@ -import { - Autocomplete, - Box, - Checkbox, - Grid, - MenuItem, - Select, - SelectChangeEvent, - TextField, - Typography, - useTheme -} from '@mui/material'; -import PageLayout from '../../../components/PageLayout'; -import AvailabilityView from './AvailabilityView'; -import { useAllMembers } from '../../../hooks/users.hooks'; -import LoadingIndicator from '../../../components/LoadingIndicator'; -import ErrorPage from '../../ErrorPage'; -import { userToAutocompleteOption } from '../../../utils/teams.utils'; -import { useState } from 'react'; -import CheckBoxIcon from '@mui/icons-material/CheckBox'; -import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; -import { DatePicker } from '@mui/x-date-pickers'; -import { Event, meetingStartTimePipeNumbers } from 'shared'; -import { useAllEvents } from '../../../hooks/calendar.hooks'; -import { eventNamePipe } from '../../../utils/pipes'; -import { HOURS } from '../../../utils/design-review.utils'; - -export interface EventEditData { - requiredUserIds: string[]; - optionalUserIds: string[]; - selectedDate: Date; - startTime: number; - endTime: number; -} -interface EventDetailPageProps { - event: Event; -} - -export interface FinalizeEventInformation { - docTemplateLink: string; - zoomLink?: string; - location?: string; - meetingType: string[]; -} - -const EventDetailPage: React.FC = ({ event }) => { - const theme = useTheme(); - const [requiredUsers, setRequiredUsers] = useState(event.requiredMembers.map(userToAutocompleteOption)); - const [optionalUsers, setOptionalUsers] = useState(event.optionalMembers.map(userToAutocompleteOption)); - - const [firstScheduledSlot] = event.scheduledTimes; - const lastScheduledSlot = event.scheduledTimes.at(-1); - - // Convert string dates → real Date objects (defensive) - const parseDate = (dateInput: Date | string | undefined): Date => { - if (!dateInput) return new Date(); - return typeof dateInput === 'string' ? new Date(dateInput) : dateInput; - }; - - const [date, setDate] = useState( - firstScheduledSlot?.initialDateScheduled ? parseDate(firstScheduledSlot.initialDateScheduled) : new Date() - ); - - const [startTime, setStartTime] = useState( - firstScheduledSlot?.startTime ? new Date(firstScheduledSlot.startTime).getHours() - 10 : 0 - ); - - const [endTime, setEndTime] = useState( - lastScheduledSlot?.endTime - ? new Date(lastScheduledSlot.endTime).getHours() - 9 // +1 hour from start - : 1 - ); - - const { isLoading: allUsersIsLoading, isError: allUsersIsError, error: allUsersError, data: allMembers } = useAllMembers(); - const { - data: allEvents, - isError: allEventsIsError, - error: allEventsError, - isLoading: allEventsIsLoading - } = useAllEvents(); - - if (allUsersIsError) return ; - if (allEventsIsError) return ; - if (allUsersIsLoading || !allMembers || allEventsIsLoading || !allEvents) return ; - - const users = allMembers.map(userToAutocompleteOption); - - const handleDateChange = (newDate: Date | null) => { - if (newDate) { - const updatedDateTime = new Date(); - updatedDateTime.setFullYear(newDate.getFullYear(), newDate.getMonth(), newDate.getDate()); - setDate(updatedDateTime); - } - }; - - const handleSelectingRequiredUser = (newValue: { label: string; id: string }[]) => { - const newRequiredUserIds = new Set(newValue.map((user) => user.id)); - const filteredOptionalUsers = optionalUsers.filter((user) => !newRequiredUserIds.has(user.id)); - setOptionalUsers(filteredOptionalUsers); - setRequiredUsers(newValue); - }; - - const handleEdit = async () => { - const times = []; - for (let i = startTime; i < endTime; i++) { - times.push(i % 12); - } - date.setHours(12); - /* - try { - const payload: EditDesignReviewPayload = { - dateScheduled: date, - teamTypeId: designReview.teamType.teamTypeId, - requiredMembersIds: requiredUsers.map((user) => user.id), - optionalMembersIds: optionalUsers.map((user) => user.id), - isOnline: data?.meetingType.includes('virtual') ?? false, - isInPerson: data?.meetingType.includes('inPerson') ?? false, - status: data ? DesignReviewStatus.SCHEDULED : designReview.status, - attendees: [], - meetingTimes: times, - docTemplateLink: data?.docTemplateLink ?? designReview.docTemplateLink, - zoomLink: data?.zoomLink ?? designReview.zoomLink, - location: data?.location ?? designReview.location - }; - await editDesignReview(payload); - history.push(routes.CALENDAR); - } catch (error: unknown) { - if (error instanceof Error) { - toast.error(error.message); - } - } - */ - }; - - const DateField = () => { - return ; - }; - - // styling for the editable fields at the top of the page with light grey backgrounds - const EditableFieldStyle = { - fontSize: '16px', - backgroundColor: 'grey', - borderRadius: 3, - textAlign: 'left', - border: '2px solid', - width: '100%' - }; - - // styling for the non-editable fields at the top of the page with dark backgrounds - const NonEditableFieldStyle = { - padding: 1.5, - paddingTop: 1.5, - paddingBottom: 1.5, - fontSize: '1.2em', - backgroundColor: theme.palette.background.paper, - borderRadius: 3, - textAlign: 'center', - width: '100%', - border: 'none' - }; - - return ( - - - - Name - - - {eventNamePipe(event)} - - - - - - - - to - - - - - - - Required - - - - option.id === value.id} - multiple - disableCloseOnSelect - limitTags={1} - renderTags={() => null} - id="required-users" - options={users} - value={requiredUsers} - onChange={(_event, newValue) => handleSelectingRequiredUser(newValue)} - getOptionLabel={(option) => option.label} - renderOption={(props, option, { selected }) => ( -
  • - } - checkedIcon={} - style={{ marginRight: 8 }} - checked={selected} - /> - {option.label} -
  • - )} - renderInput={(params) => ( - - )} - /> -
    -
    - - Optional - - - - option.id === value.id} - multiple - disableCloseOnSelect - limitTags={1} - renderTags={() => null} - id="optional-users" - options={users.filter((user) => !requiredUsers.some((reqUser) => reqUser.id === user.id))} - value={optionalUsers} - onChange={(_event, newValue) => setOptionalUsers(newValue)} - getOptionLabel={(option) => option.label} - renderOption={(props, option, { selected }) => ( -
  • - } - checkedIcon={} - style={{ marginRight: 8 }} - checked={selected} - /> - {option.label} -
  • - )} - renderInput={(params) => ( - - )} - /> -
    -
    -
    -
    -
    - user.id)} - optionalUserIds={optionalUsers.map((user) => user.id)} - startTime={startTime} - endTime={endTime} - /> -
    - ); -}; - -export default EventDetailPage; diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetails.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetails.tsx deleted file mode 100644 index 05b3adaa27..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/EventDetails.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This file is part of NER's FinishLine and licensed under GNU AGPLv3. - * See the LICENSE file in the repository root folder for details. - */ -import LoadingIndicator from '../../../components/LoadingIndicator'; -import { useParams } from 'react-router-dom'; -import ErrorPage from '../../ErrorPage'; -import { useSingleEvent } from '../../../hooks/calendar.hooks'; -import EventDetailPage from './EventDetailPage'; - -const EventDetails: React.FC = () => { - const { id } = useParams<{ id: string }>(); - const { data: event, isError, error, isLoading } = useSingleEvent(id); - - if (isError) return ; - if (!event || isLoading) return ; - - return ; -}; - -export default EventDetails; diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx deleted file mode 100644 index 454f067898..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/FinalizeEventDetailsModal.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import { Box, Grid, Link, ToggleButton, ToggleButtonGroup, Typography, Tooltip } from '@mui/material'; -import HelpIcon from '@mui/icons-material/Help'; -import React, { useState, useEffect } from 'react'; -import { Event, meetingStartTimePipeNumbers, wbsPipe } from 'shared'; -import NERFormModal from '../../../components/NERFormModal'; -import ReactHookTextField from '../../../components/ReactHookTextField'; -import { useForm } from 'react-hook-form'; -import * as yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { FinalizeEventInformation } from './EventDetailPage'; -import { useCurrentUser, useUserScheduleSettings } from '../../../hooks/users.hooks'; - -interface FinalizeEventProps { - open: boolean; - setOpen: (val: boolean) => void; - event: Event; - conflictingEvents: Event[]; - startTime: number; - selectedDate: Date; - finalizeEvent: (data: FinalizeEventInformation) => void; -} - -const FinalizeEventDetailsModal = ({ - open, - setOpen, - event, - conflictingEvents, - finalizeEvent, - startTime, - selectedDate -}: FinalizeEventProps) => { - const [meetingType, setMeetingType] = useState([]); - const currentUser = useCurrentUser(); - const { data: userScheduleSettings } = useUserScheduleSettings(currentUser.userId); - - const createValidationSchema = () => - yup.object().shape({ - zoomLink: meetingType.includes('virtual') - ? yup.string().required('Meeting link is required for virtual meetings').url('Please enter a valid URL') - : yup.string().optional(), - location: yup.string().optional(), - docTemplateLink: yup.string().required('Question Doc is Required') - }); - - const [firstWorkPackage] = event.workPackages; - - const wbsNum = firstWorkPackage - ? { - carNumber: firstWorkPackage.wbsElement.carNumber, - projectNumber: firstWorkPackage.wbsElement.projectNumber, - workPackageNumber: firstWorkPackage.wbsElement.workPackageNumber - } - : { carNumber: 0, projectNumber: 0, workPackageNumber: 0 }; - - const eventName = firstWorkPackage?.wbsElement?.name - ? `${firstWorkPackage.wbsElement.carNumber}.${firstWorkPackage.wbsElement.projectNumber}.${firstWorkPackage.wbsElement.workPackageNumber} - ${firstWorkPackage.wbsElement.name}` - : event.title; - - const title = `Finalize Event for ${eventName}`; - - const eventConflicts = conflictingEvents.map( - (_event) => `${wbsPipe(wbsNum)} - ${eventName} at ${meetingStartTimePipeNumbers([startTime])}` - ); - - const defaultValues = { - docTemplateLink: event.questionDocumentLink ?? '', - zoomLink: event.zoomLink ?? userScheduleSettings?.personalZoomLink ?? '', - location: event.location ?? undefined - }; - - const { - handleSubmit, - control, - reset, - formState: { errors } - } = useForm({ - resolver: yupResolver(createValidationSchema()), - defaultValues, - mode: 'onChange' - }); - - const handleMeetingTypeChange = (_event: any, newMeetingType: string[]) => { - setMeetingType(newMeetingType); - reset(defaultValues); - }; - - const onSubmit = async (data: { docTemplateLink: string; zoomLink?: string; location?: string }) => { - finalizeEvent({ ...data, zoomLink: data.zoomLink ? data.zoomLink : undefined, meetingType }); - setOpen(false); - }; - - useEffect(() => { - if (userScheduleSettings && !event.zoomLink) { - reset({ - docTemplateLink: event.questionDocumentLink ?? '', - zoomLink: userScheduleSettings.personalZoomLink ?? '', - location: event.location ?? undefined - }); - } - if (event.zoomLink === '') { - reset({ - zoomLink: undefined - }); - } - }, [userScheduleSettings, event, reset]); - - return ( - setOpen(false)} - title={title} - reset={() => reset(defaultValues)} - handleUseFormSubmit={handleSubmit} - onFormSubmit={onSubmit} - submitText="Schedule" - formId="finalize-event-form" - > - - Meeting Time: - {`${meetingStartTimePipeNumbers([ - startTime - ])} - ${selectedDate.toDateString()}`} - - - Meeting Type: - - Virtual - In-person - - - - - Question Doc: - - Doc Template - - - - - {meetingType.includes('virtual') && ( - - - Meeting Link: - - - - - - - )} - {meetingType.includes('inPerson') && ( - - Location: - - - )} - - {eventConflicts && eventConflicts.length > 0 && ( - - - Design Review Conflicts - - - - {eventConflicts.map((conflictDesign, index) => ( - - {conflictDesign} - - ))} - - - - )} - - - ); -}; -export default FinalizeEventDetailsModal; diff --git a/src/frontend/src/pages/CalendarPage/EventDetailPage/UserAvailabilitesView.tsx b/src/frontend/src/pages/CalendarPage/EventDetailPage/UserAvailabilitesView.tsx deleted file mode 100644 index f9d86b4fcc..0000000000 --- a/src/frontend/src/pages/CalendarPage/EventDetailPage/UserAvailabilitesView.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import { Typography } from '@mui/material'; -import { Box, useTheme } from '@mui/system'; -import { Availability, Event, EventStatus, User } from 'shared'; -import { HeatmapColors } from '../../../utils/design-review.utils'; -import { fullNamePipe } from '../../../utils/pipes'; -import NERFailButton from '../../../components/NERFailButton'; -import NERSuccessButton from '../../../components/NERSuccessButton'; -import { useState } from 'react'; -import { FinalizeEventInformation } from './EventDetailPage'; -import { useHistory } from 'react-router-dom'; -import { routes } from '../../../utils/routes'; -import FinalizeEventDetailsModal from './FinalizeEventDetailsModal'; - -interface UserAvailabilitiesProps { - currentAvailableUsers: User[]; - currentUnavailableUsers: User[]; - usersToAvailabilities: Map; - event: Event; - conflictingEvents: Event[]; - selectedDate: Date; - startTime: number; - handleEdit: (data?: FinalizeEventInformation) => void; -} - -const UserAvailabilites: React.FC = ({ - currentAvailableUsers, - currentUnavailableUsers, - usersToAvailabilities, - event, - conflictingEvents, - handleEdit, - selectedDate, - startTime -}) => { - const theme = useTheme(); - const history = useHistory(); - const [showFinalizeEventDetailsModal, setShowFinalizeEventDetailsModal] = useState(false); - const totalUsers = usersToAvailabilities.size; - - const handleCancel = () => { - history.push(routes.CALENDAR); - }; - - return ( - - - - 0/{totalUsers} - {Array.from({ length: 6 }, (_, i) => ( - - ))} - - {totalUsers}/{totalUsers} - - - - - - Available - - - {currentAvailableUsers.map((user) => ( - {fullNamePipe(user)} - ))} - - - - - Unavailable - - - {currentUnavailableUsers.map((user) => ( - {fullNamePipe(user)} - ))} - - - - - Cancel - handleEdit()}> - Save - - setShowFinalizeEventDetailsModal(true)} - > - Finalize - - - - - - ); -}; - -export default UserAvailabilites; diff --git a/src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx b/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx similarity index 100% rename from src/frontend/src/pages/NewCalendarPage/EventPartialInfoView.tsx rename to src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx diff --git a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx b/src/frontend/src/pages/CalendarPage/EventsTable.tsx similarity index 99% rename from src/frontend/src/pages/NewCalendarPage/EventsTable.tsx rename to src/frontend/src/pages/CalendarPage/EventsTable.tsx index 70af7215c3..8405ece2dd 100644 --- a/src/frontend/src/pages/NewCalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/CalendarPage/EventsTable.tsx @@ -402,6 +402,7 @@ const EventsTable: React.FC = ({ calendars={allCalendars} disable={true} addApprovalButtons={true} + handleEditSubmit={handleEditSubmit} /> {clickedEditEvent && showEditModal && ( ; diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx index e060e3859f..638a1820a5 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityView.tsx @@ -4,7 +4,7 @@ import { datePipe } from '../../../../utils/pipes'; import { useState, useEffect } from 'react'; import NERArrows from '../../../../components/NERArrows'; import { enumToArray, REVIEW_TIMES, getBackgroundColor } from '../../../../utils/design-review.utils'; -import EventTimeSlot from '../../../NewCalendarPage/Components/EventTimeSlot'; +import EventTimeSlot from '../../../CalendarPage/Components/EventTimeSlot'; interface SingleAvailabilityViewProps { totalAvailability: Availability[]; diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 42234691a6..debb7fe222 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -1,6 +1,6 @@ import { DayOfWeek, Event } from 'shared'; import { filterEventTransformer } from '../apis/transformers/calendar.transformer'; -import { EventFormValues } from '../pages/NewCalendarPage/Components/EventModal'; +import { EventFormValues } from '../pages/CalendarPage/Components/EventModal'; export const convertDayToInt = (day: DayOfWeek) => { switch (day) { From 080f55136923803cdd660afe5273136bd7bc0fc5 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sat, 3 Jan 2026 23:29:48 -0500 Subject: [PATCH 452/477] #3818 typescript fixes --- src/frontend/src/app/AppAuthenticated.tsx | 2 +- .../CalendarPage/AvailabilityScheduleView.tsx | 120 ++++++++++++++++++ .../pages/CalendarPage/CalendarDayCard.tsx | 2 +- .../Components/EventAvailabilityPage.tsx | 2 +- .../pages/CalendarPage/EventClickPopup.tsx | 2 +- 5 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx diff --git a/src/frontend/src/app/AppAuthenticated.tsx b/src/frontend/src/app/AppAuthenticated.tsx index 300e198b02..d0489867a8 100644 --- a/src/frontend/src/app/AppAuthenticated.tsx +++ b/src/frontend/src/app/AppAuthenticated.tsx @@ -33,7 +33,7 @@ import { useHomePageContext } from './HomePageContext'; import { useCurrentOrganization } from '../hooks/organizations.hooks'; import Statistics from '../pages/StatisticsPage/Statistics'; import RetrospectiveGanttChartPage from '../pages/RetrospectivePage/Retrospective'; -import NewCalendar from '../pages/NewCalendarPage/NewCalendar'; +import NewCalendar from '../pages/CalendarPage/NewCalendar'; interface AppAuthenticatedProps { userId: string; diff --git a/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx b/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx new file mode 100644 index 0000000000..88c405c5c5 --- /dev/null +++ b/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx @@ -0,0 +1,120 @@ +import { Grid } from '@mui/material'; +import { useState } from 'react'; +import { Availability, Event, getDayOfWeek, getNextSevenDays, User } from 'shared'; +import { + enumToArray, + getBackgroundColor, + HeatmapColors, + NUMBER_OF_TIME_SLOTS, + REVIEW_TIMES +} from '../../utils/design-review.utils'; +import TimeSlot from '../../components/TimeSlot'; +import { datePipe } from '../../utils/pipes'; + +interface AvailabilityScheduleViewProps { + availableUsers: Map; + unavailableUsers: Map; + usersToAvailabilities: Map; + existingMeetingData: Map; + setCurrentAvailableUsers: (val: User[]) => void; + setCurrentUnavailableUsers: (val: User[]) => void; + onSelectedTimeslotChanged: (val: number | null, day: Date | null) => void; + dateRangeTitle: string; + event: Event; +} + +const AvailabilityScheduleView: React.FC = ({ + availableUsers, + unavailableUsers, + usersToAvailabilities, + existingMeetingData, + setCurrentAvailableUsers, + setCurrentUnavailableUsers, + dateRangeTitle, + onSelectedTimeslotChanged, + event +}) => { + const totalUsers = usersToAvailabilities.size; + const [selectedTimeslot, setSelectedTimeslot] = useState(null); + const initialDate = event.scheduledTimes[0]?.initialDateScheduled || new Date(); + const potentialDays = getNextSevenDays(initialDate); + + const handleTimeslotClick = (index: number, day: Date) => { + if (selectedTimeslot === index) { + setSelectedTimeslot(null); // unselect + setCurrentAvailableUsers([]); + setCurrentUnavailableUsers([]); + } else { + setSelectedTimeslot(index); // select + setCurrentAvailableUsers(availableUsers.get(index) || []); + setCurrentUnavailableUsers(unavailableUsers.get(index) || []); + } + + onSelectedTimeslotChanged(index, day); + }; + + const handleOnMouseOver = (index: number) => { + setCurrentAvailableUsers(availableUsers.get(index) || []); + setCurrentUnavailableUsers(unavailableUsers.get(index) || []); + }; + + const handleOnMouseLeave = (): void => { + if (selectedTimeslot === null) { + setCurrentAvailableUsers([]); + setCurrentUnavailableUsers([]); + } + }; + + // Populates the availableUsers map + for (let time = 0; time < NUMBER_OF_TIME_SLOTS; time++) { + availableUsers.set(time, []); + } + usersToAvailabilities.forEach((availabilities, user) => { + let i = 0; + availabilities.forEach((availability) => { + availability.availability.forEach((time) => { + const usersAtTime = availableUsers.get(enumToArray(REVIEW_TIMES).length * i + time) || []; + usersAtTime.push(user); + availableUsers.set(enumToArray(REVIEW_TIMES).length * i + time, usersAtTime); + }); + i++; + }); + }); + + // Populates the unavailableUsers map + const allUsers = [...usersToAvailabilities.keys()]; + for (let time = 0; time < NUMBER_OF_TIME_SLOTS; time++) { + const currentUsers = availableUsers.get(time) || []; + const currentUnavailableUsers = allUsers.filter((user) => !currentUsers.includes(user)); + unavailableUsers.set(time, currentUnavailableUsers); + } + + return ( + + + {potentialDays.map((day) => ( + + ))} + {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( + + + {potentialDays.map((day, dayIndex) => { + const index = dayIndex * enumToArray(REVIEW_TIMES).length + timeIndex; + return ( + handleTimeslotClick(index, day)} + onMouseOver={() => handleOnMouseOver(index)} + icon={existingMeetingData.get(index)} + /> + ); + })} + + ))} + + ); +}; + +export default AvailabilityScheduleView; diff --git a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx index f806b30ab8..171defcb9c 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx @@ -1,4 +1,4 @@ -import { JSX, useState } from 'react'; +import { useState } from 'react'; import { Box, Card, CardContent, Grid, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; import ConstructionIcon from '@mui/icons-material/Construction'; diff --git a/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx b/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx index 31fd375bf6..2f1ce8e1b7 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx @@ -20,9 +20,9 @@ import { routes } from '../../../utils/routes'; import { useToast } from '../../../hooks/toasts.hooks'; import { deeplyCopy } from 'shared/src/utils'; import { availabilityTransformer } from '../../../apis/transformers/users.transformers'; -import AvailabilityScheduleView from '../../CalendarPage/EventDetailPage/AvailabilityScheduleView'; import SingleAvailabilityModal from '../../SettingsPage/UserScheduleSettings/Availability/SingleAvailabilityModal'; import AvailabilityEditModal from '../../SettingsPage/UserScheduleSettings/Availability/AvailabilityEditModal'; +import AvailabilityScheduleView from '../AvailabilityScheduleView'; const isUserOnEvent = (user: User, event: EventWithMembers): boolean => { const isDirectMember = diff --git a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx index eaca76cc17..49bf95cd79 100644 --- a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx @@ -1,4 +1,4 @@ -import React, { JSX, useState } from 'react'; +import React, { useState } from 'react'; import { Box, Button, IconButton, Link, Popover, Stack, Typography, useTheme } from '@mui/material'; import { Calendar, DayOfWeek, Event, EventType } from 'shared'; From 94d7b52fb8c2014e1fd5c245670e7d4c19eab841 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sat, 3 Jan 2026 23:40:14 -0500 Subject: [PATCH 453/477] #3818 copied over wrong version of file --- .../CalendarPage/AvailabilityScheduleView.tsx | 132 ++++++++++-------- 1 file changed, 73 insertions(+), 59 deletions(-) diff --git a/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx b/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx index 88c405c5c5..5829cb9ab6 100644 --- a/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx +++ b/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx @@ -1,68 +1,45 @@ -import { Grid } from '@mui/material'; -import { useState } from 'react'; +import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from '@mui/material'; import { Availability, Event, getDayOfWeek, getNextSevenDays, User } from 'shared'; -import { - enumToArray, - getBackgroundColor, - HeatmapColors, - NUMBER_OF_TIME_SLOTS, - REVIEW_TIMES -} from '../../utils/design-review.utils'; -import TimeSlot from '../../components/TimeSlot'; +import React, { useState } from 'react'; +import { enumToArray, getBackgroundColor, NUMBER_OF_TIME_SLOTS, REVIEW_TIMES } from '../../utils/design-review.utils'; import { datePipe } from '../../utils/pipes'; +import EventTimeSlot from './Components/EventTimeSlot'; interface AvailabilityScheduleViewProps { availableUsers: Map; unavailableUsers: Map; usersToAvailabilities: Map; - existingMeetingData: Map; setCurrentAvailableUsers: (val: User[]) => void; setCurrentUnavailableUsers: (val: User[]) => void; - onSelectedTimeslotChanged: (val: number | null, day: Date | null) => void; - dateRangeTitle: string; event: Event; + displayDate?: Date; } const AvailabilityScheduleView: React.FC = ({ availableUsers, unavailableUsers, usersToAvailabilities, - existingMeetingData, setCurrentAvailableUsers, setCurrentUnavailableUsers, - dateRangeTitle, - onSelectedTimeslotChanged, - event + event, + displayDate }) => { const totalUsers = usersToAvailabilities.size; const [selectedTimeslot, setSelectedTimeslot] = useState(null); - const initialDate = event.scheduledTimes[0]?.initialDateScheduled || new Date(); + // Use displayDate if provided, otherwise fall back to event's initial date + const initialDate = displayDate || event.scheduledTimes[0]?.initialDateScheduled || new Date(); const potentialDays = getNextSevenDays(initialDate); - const handleTimeslotClick = (index: number, day: Date) => { + const handleTimeslotClick = (index: number, _day: Date) => { if (selectedTimeslot === index) { - setSelectedTimeslot(null); // unselect + setSelectedTimeslot(null); setCurrentAvailableUsers([]); setCurrentUnavailableUsers([]); } else { - setSelectedTimeslot(index); // select + setSelectedTimeslot(index); setCurrentAvailableUsers(availableUsers.get(index) || []); setCurrentUnavailableUsers(unavailableUsers.get(index) || []); } - - onSelectedTimeslotChanged(index, day); - }; - - const handleOnMouseOver = (index: number) => { - setCurrentAvailableUsers(availableUsers.get(index) || []); - setCurrentUnavailableUsers(unavailableUsers.get(index) || []); - }; - - const handleOnMouseLeave = (): void => { - if (selectedTimeslot === null) { - setCurrentAvailableUsers([]); - setCurrentUnavailableUsers([]); - } }; // Populates the availableUsers map @@ -89,31 +66,68 @@ const AvailabilityScheduleView: React.FC = ({ unavailableUsers.set(time, currentUnavailableUsers); } + const stickyLeft = { + position: 'sticky', + left: 0, + zIndex: 2, + bgcolor: 'background.paper' + }; + return ( - - - {potentialDays.map((day) => ( - - ))} - {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( - - - {potentialDays.map((day, dayIndex) => { - const index = dayIndex * enumToArray(REVIEW_TIMES).length + timeIndex; - return ( - handleTimeslotClick(index, day)} - onMouseOver={() => handleOnMouseOver(index)} - icon={existingMeetingData.get(index)} - /> - ); - })} - - ))} - + + + + + + {potentialDays.map((day) => ( + + + {getDayOfWeek(day) + ' ' + datePipe(day)} + + + ))} + + + + {enumToArray(REVIEW_TIMES).map((time, timeIndex) => ( + + + + {time} + + + {potentialDays.map((day, dayIndex) => { + const index = dayIndex * enumToArray(REVIEW_TIMES).length + timeIndex; + return ( + + handleTimeslotClick(index, day)} + /> + + ); + })} + + ))} + +
    +
    ); }; From 27cb8aa5f242ecad3d32e2c83b05a77b0f483be1 Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Wed, 7 Jan 2026 07:28:58 -0500 Subject: [PATCH 454/477] #3767 onboarding impreovements --- .../src/controllers/onboarding.controllers.ts | 31 +- .../controllers/organizations.controllers.ts | 25 + .../migration.sql | 32 ++ src/backend/src/prisma/schema.prisma | 30 +- src/backend/src/routes/onboarding.routes.ts | 18 + .../src/routes/organizations.routes.ts | 2 + .../src/services/onboarding.services.ts | 143 ++++- .../src/services/organizations.services.ts | 53 +- .../transformers/organizationTransformer.ts | 5 +- src/frontend/src/apis/onboarding.api.ts | 14 + src/frontend/src/apis/organizations.api.ts | 12 + src/frontend/src/components/NERMarkdown.tsx | 9 +- src/frontend/src/hooks/onboarding.hook.ts | 153 ++++- src/frontend/src/hooks/organizations.hooks.ts | 24 +- .../Checklists/AdminChecklist.tsx | 59 +- .../Checklists/AdminSubtaskSection.tsx | 233 +++++--- .../Checklists/CreateChecklistModal.tsx | 533 +++++++++--------- .../Checklists/CreateInfoBlockModal.tsx | 165 ++++++ .../Checklists/EditInfoBlockModal.tsx | 161 ++++++ .../Checklists/SubtaskFormModal.tsx | 5 +- .../OnboardingInfoSection.tsx | 89 ++- .../AdminToolsRecruitmentConfig.tsx | 2 +- .../pages/HomePage/components/Checklist.tsx | 2 +- .../HomePage/components/ChecklistSection.tsx | 46 +- .../pages/HomePage/components/ParentTask.tsx | 28 +- .../HomePage/components/SubtaskSection.tsx | 152 +++-- src/frontend/src/utils/urls.ts | 8 + src/shared/src/types/checklist-types.ts | 9 +- src/shared/src/types/user-types.ts | 3 +- 29 files changed, 1569 insertions(+), 477 deletions(-) create mode 100644 src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql create mode 100644 src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx create mode 100644 src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx diff --git a/src/backend/src/controllers/onboarding.controllers.ts b/src/backend/src/controllers/onboarding.controllers.ts index 9a017ea0b1..9262e734f8 100644 --- a/src/backend/src/controllers/onboarding.controllers.ts +++ b/src/backend/src/controllers/onboarding.controllers.ts @@ -32,7 +32,7 @@ export default class OnboardingController { static async createChecklist(req: Request, res: Response, next: NextFunction) { try { - const { name, descriptions, isOptional, teamId, teamTypeId, parentChecklistId } = req.body; + const { name, descriptions, isOptional, teamId, teamTypeId, parentChecklistId, itemType } = req.body; const checklist = await OnboardingServices.createChecklist( req.currentUser, name, @@ -41,7 +41,8 @@ export default class OnboardingController { teamTypeId, parentChecklistId, req.organization, - isOptional + isOptional, + itemType ); res.status(200).json(checklist); } catch (error: unknown) { @@ -52,7 +53,7 @@ export default class OnboardingController { static async editChecklist(req: Request, res: Response, next: NextFunction) { try { const { checklistId } = req.params; - const { name, descriptions, isOptional, teamId, teamTypeId, parentChecklistId } = req.body; + const { name, descriptions, isOptional, teamId, teamTypeId, parentChecklistId, itemType } = req.body; const checklist = await OnboardingServices.editChecklist( req.currentUser, checklistId, @@ -62,7 +63,8 @@ export default class OnboardingController { teamTypeId, parentChecklistId, req.organization, - isOptional + isOptional, + itemType ); res.status(200).json(checklist); } catch (error: unknown) { @@ -107,4 +109,25 @@ export default class OnboardingController { return next(error); } } + + static async reorderTasks(req: Request, res: Response, next: NextFunction) { + try { + const { taskIds } = req.body; + await OnboardingServices.reorderTasks(req.currentUser, taskIds, req.organization); + res.status(200).json({ message: 'Tasks reordered successfully' }); + } catch (error: unknown) { + return next(error); + } + } + + static async reorderChecklistItems(req: Request, res: Response, next: NextFunction) { + try { + const { parentId } = req.params; + const { itemIds } = req.body; + await OnboardingServices.reorderChecklistItems(req.currentUser, parentId, itemIds, req.organization); + res.status(200).json({ message: 'Checklist items reordered successfully' }); + } catch (error: unknown) { + return next(error); + } + } } diff --git a/src/backend/src/controllers/organizations.controllers.ts b/src/backend/src/controllers/organizations.controllers.ts index aa87584f17..f7aaa8b8dc 100644 --- a/src/backend/src/controllers/organizations.controllers.ts +++ b/src/backend/src/controllers/organizations.controllers.ts @@ -142,6 +142,31 @@ export default class OrganizationsController { } } + static async setNewMemberImage(req: Request, res: Response, next: NextFunction) { + try { + if (!req.file) { + throw new HttpException(400, 'Invalid or undefined image data'); + } + + const updatedOrg = await OrganizationsService.setNewMemberImage(req.file, req.currentUser, req.organization); + + res.status(200).json(updatedOrg); + } catch (error: unknown) { + next(error); + } + } + + static async getOrganizationNewMemberImage(req: Request, res: Response, next: NextFunction) { + try { + const { organization } = req; + + const newMemberImageId = await OrganizationsService.getNewMemberImage(organization.organizationId); + res.status(200).json(newMemberImageId); + } catch (error: unknown) { + next(error); + } + } + static async setOrganizationDescription(req: Request, res: Response, next: NextFunction) { try { const updatedOrg = await OrganizationsService.setOrganizationDescription( diff --git a/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql b/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql new file mode 100644 index 0000000000..6df5cbfa29 --- /dev/null +++ b/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql @@ -0,0 +1,32 @@ +-- CreateEnum +CREATE TYPE "Checklist_Item_Type" AS ENUM ('TASK', 'INFO'); + +-- AlterTable +ALTER TABLE "Checklist" ADD COLUMN "displayOrder" INTEGER, +ADD COLUMN "itemType" "Checklist_Item_Type" NOT NULL DEFAULT 'TASK'; + +-- Backfill displayOrder based on dateCreated for existing records +-- For top-level checklists (parentChecklistId IS NULL) +WITH ranked_parent AS ( + SELECT "checklistId", ROW_NUMBER() OVER (ORDER BY "dateCreated", "checklistId") as rn + FROM "Checklist" + WHERE "parentChecklistId" IS NULL AND "displayOrder" IS NULL +) +UPDATE "Checklist" +SET "displayOrder" = ranked_parent.rn +FROM ranked_parent +WHERE "Checklist"."checklistId" = ranked_parent."checklistId"; + +-- For child checklists (parentChecklistId IS NOT NULL) +WITH ranked_children AS ( + SELECT "checklistId", ROW_NUMBER() OVER (PARTITION BY "parentChecklistId" ORDER BY "dateCreated", "checklistId") as rn + FROM "Checklist" + WHERE "parentChecklistId" IS NOT NULL AND "displayOrder" IS NULL +) +UPDATE "Checklist" +SET "displayOrder" = ranked_children.rn +FROM ranked_children +WHERE "Checklist"."checklistId" = ranked_children."checklistId"; + +-- AlterTable +ALTER TABLE "Organization" ADD COLUMN "newMemberImageId" TEXT; \ No newline at end of file diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 187f5c0a1f..2301404560 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -146,6 +146,11 @@ enum Special_Permission { FINANCE_ONLY } +enum Checklist_Item_Type { + TASK + INFO +} + enum Review_Status { IN_PROGRESS READY_FOR_REVIEW @@ -1307,6 +1312,7 @@ model Organization { description String @default("") applyInterestImageId String? exploreAsGuestImageId String? + newMemberImageId String? logoImageId String? slackWorkspaceId String? applicationLink String? @@ -1461,26 +1467,28 @@ model PopUp { } model Checklist { - checklistId String @id @default(uuid()) + checklistId String @id @default(uuid()) teamTypeId String? - teamType Team_Type? @relation(fields: [teamTypeId], references: [teamTypeId]) + teamType Team_Type? @relation(fields: [teamTypeId], references: [teamTypeId]) teamId String? - team Team? @relation(fields: [teamId], references: [teamId]) + team Team? @relation(fields: [teamId], references: [teamId]) name String descriptions String[] - isOptional Boolean @default(false) - subtasks Checklist[] @relation("subtasks") - parentChecklist Checklist? @relation("subtasks", fields: [parentChecklistId], references: [checklistId]) + isOptional Boolean @default(false) + displayOrder Int? + itemType Checklist_Item_Type @default(TASK) + subtasks Checklist[] @relation("subtasks") + parentChecklist Checklist? @relation("subtasks", fields: [parentChecklistId], references: [checklistId]) parentChecklistId String? - usersChecked User[] @relation(name: "checkedChecklists") - dateCreated DateTime @default(now()) + usersChecked User[] @relation(name: "checkedChecklists") + dateCreated DateTime @default(now()) dateDeleted DateTime? - userCreated User @relation(fields: [userCreatedId], references: [userId], name: "checklistCreator") + userCreated User @relation(fields: [userCreatedId], references: [userId], name: "checklistCreator") userCreatedId String - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "checklistDeleter") + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "checklistDeleter") userDeletedId String? organizationId String - organization Organization @relation(fields: [organizationId], references: [organizationId]) + organization Organization @relation(fields: [organizationId], references: [organizationId]) @@index([organizationId]) @@index([teamId]) diff --git a/src/backend/src/routes/onboarding.routes.ts b/src/backend/src/routes/onboarding.routes.ts index 64e0f8a624..218a4e8788 100644 --- a/src/backend/src/routes/onboarding.routes.ts +++ b/src/backend/src/routes/onboarding.routes.ts @@ -21,6 +21,7 @@ onboardingRouter.post( nonEmptyString(body('teamTypeId').optional()), nonEmptyString(body('parentChecklistId').optional()), body('isOptional').isBoolean().optional(), + body('itemType').isIn(['TASK', 'INFO']).optional(), validateInputs, OnboardingController.createChecklist ); @@ -34,6 +35,7 @@ onboardingRouter.post( nonEmptyString(body('teamTypeId').optional()), nonEmptyString(body('parentChecklistId').optional()), body('isOptional').isBoolean().optional(), + body('itemType').isIn(['TASK', 'INFO']).optional(), validateInputs, OnboardingController.editChecklist ); @@ -42,6 +44,22 @@ onboardingRouter.post('/checklist/delete/:checklistId', OnboardingController.del onboardingRouter.post('/checklists/:checklistId/toggle', OnboardingController.toggleChecklist); +onboardingRouter.post( + '/tasks/reorder', + body('taskIds').isArray(), + nonEmptyString(body('taskIds.*')), + validateInputs, + OnboardingController.reorderTasks +); + +onboardingRouter.post( + '/tasks/:parentId/items/reorder', + body('itemIds').isArray(), + nonEmptyString(body('itemIds.*')), + validateInputs, + OnboardingController.reorderChecklistItems +); + onboardingRouter.get('/image/:fileId', OnboardingController.downloadImage); export default onboardingRouter; diff --git a/src/backend/src/routes/organizations.routes.ts b/src/backend/src/routes/organizations.routes.ts index ade614b35f..bb113192b6 100644 --- a/src/backend/src/routes/organizations.routes.ts +++ b/src/backend/src/routes/organizations.routes.ts @@ -51,6 +51,8 @@ organizationRouter.post( ); organizationRouter.post('/logo/update', upload.single('logo'), OrganizationsController.setLogoImage); organizationRouter.get('/logo', OrganizationsController.getOrganizationLogoImage); +organizationRouter.post('/new-member-image/update', upload.single('newMemberImage'), OrganizationsController.setNewMemberImage); +organizationRouter.get('/new-member-image', OrganizationsController.getOrganizationNewMemberImage); organizationRouter.post( '/description/set', body('description').isString(), diff --git a/src/backend/src/services/onboarding.services.ts b/src/backend/src/services/onboarding.services.ts index 718c8a2d2e..9d8bdd5660 100644 --- a/src/backend/src/services/onboarding.services.ts +++ b/src/backend/src/services/onboarding.services.ts @@ -14,7 +14,8 @@ export default class OnboardingServices { static async getAllChecklists(organization: Organization) { const allChecklists = await prisma.checklist.findMany({ where: { organizationId: organization.organizationId, dateDeleted: null, parentChecklistId: null }, - include: { subtasks: { where: { dateDeleted: null } }, teamType: true, usersChecked: true } + include: { subtasks: { where: { dateDeleted: null }, orderBy: { displayOrder: 'asc' } }, teamType: true, usersChecked: true }, + orderBy: { displayOrder: 'asc' } }); return allChecklists; @@ -29,7 +30,8 @@ export default class OnboardingServices { static async getCheckedChecklists(user: User, organization: Organization) { const allChecklists = await prisma.checklist.findMany({ where: { organizationId: organization.organizationId, dateDeleted: null }, - include: { subtasks: { where: { dateDeleted: null } }, usersChecked: true } + include: { subtasks: { where: { dateDeleted: null }, orderBy: { displayOrder: 'asc' } }, usersChecked: true }, + orderBy: { displayOrder: 'asc' } }); const checkedChecklists = allChecklists.filter((checklist) => @@ -65,10 +67,12 @@ export default class OnboardingServices { where: { dateDeleted: null }, include: { usersChecked: true - } + }, + orderBy: { displayOrder: 'asc' } }, teamType: true - } + }, + orderBy: { displayOrder: 'asc' } }); const generalChecklists = await prisma.checklist.findMany({ @@ -84,10 +88,12 @@ export default class OnboardingServices { where: { dateDeleted: null }, include: { usersChecked: true - } + }, + orderBy: { displayOrder: 'asc' } }, teamType: true - } + }, + orderBy: { displayOrder: 'asc' } }); return [...generalChecklists, ...teamTypeChecklists]; @@ -102,6 +108,7 @@ export default class OnboardingServices { * @param teamTypeId the teamType Id of the checklist * @param parentChecklistId the parent checklist Id of the checklist * @param organization the organization of the checklist + * @param itemType the type of the checklist item (TASK or INFO) * @returns the created checklist */ static async createChecklist( @@ -112,7 +119,8 @@ export default class OnboardingServices { teamTypeId: string | null, parentChecklistId: string | null, organization: Organization, - isOptional?: boolean + isOptional?: boolean, + itemType?: 'TASK' | 'INFO' ) { if (!(await userHasPermission(creator.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('create a checklist'); @@ -166,11 +174,28 @@ export default class OnboardingServices { } } + // Calculate next displayOrder + const existingChecklists = await prisma.checklist.findMany({ + where: { + organizationId: organization.organizationId, + parentChecklistId: parentChecklistId ?? null, + dateDeleted: null + }, + orderBy: { displayOrder: 'desc' }, + take: 1 + }); + + const nextDisplayOrder = existingChecklists.length > 0 && existingChecklists[0].displayOrder !== null + ? existingChecklists[0].displayOrder + 1 + : 1; + const checklist: Checklist = await prisma.checklist.create({ data: { name, descriptions, isOptional, + displayOrder: nextDisplayOrder, + itemType: itemType ?? 'TASK', organizationId: organization.organizationId, teamId, teamTypeId, @@ -192,6 +217,7 @@ export default class OnboardingServices { * @param teamTypeId the teamType Id of the checklist * @param parentChecklistId the parent checklist Id of the checklist * @param organization the organization of the checklist + * @param itemType the type of the checklist item (TASK or INFO) * @returns the edited checklist */ static async editChecklist( @@ -203,7 +229,8 @@ export default class OnboardingServices { teamTypeId: string | null, parentChecklistId: string | null, organization: Organization, - isOptional?: boolean + isOptional?: boolean, + itemType?: 'TASK' | 'INFO' ) { if (!(await userHasPermission(editor.userId, organization.organizationId, isAdmin))) { throw new AccessDeniedAdminOnlyException('edit a checklist'); @@ -273,6 +300,7 @@ export default class OnboardingServices { name, descriptions, isOptional, + itemType: itemType ?? checklist.itemType, teamId, teamTypeId, parentChecklistId @@ -321,7 +349,7 @@ export default class OnboardingServices { static async toggleChecklist(checklistId: string, user: User, organization: Organization) { const checklist = await prisma.checklist.findUnique({ where: { checklistId, organizationId: organization.organizationId }, - include: { usersChecked: true, subtasks: { where: { dateDeleted: null }, include: { usersChecked: true } } } + include: { usersChecked: true, subtasks: { where: { dateDeleted: null }, include: { usersChecked: true }, orderBy: { displayOrder: 'asc' } } } }); if (!checklist) { @@ -335,9 +363,11 @@ export default class OnboardingServices { const { userId } = user; const isChecked = checklist.usersChecked.some((user) => user.userId === userId); + // Only check TASK items (not INFO blocks) when validating subtasks are complete + const taskSubtasks = checklist.subtasks.filter((subtask) => subtask.itemType === 'TASK'); if ( - checklist.subtasks.length > 0 && - !checklist.subtasks.every((subtask) => subtask.usersChecked.some((user) => user.userId === userId)) + taskSubtasks.length > 0 && + !taskSubtasks.every((subtask) => subtask.usersChecked.some((user) => user.userId === userId)) ) { throw new HttpException(400, 'Cannot check off this checklist item because not all of its subtasks are checked.'); } @@ -386,14 +416,15 @@ export default class OnboardingServices { include: { subtasks: { where: { dateDeleted: null }, - include: { usersChecked: true } + include: { usersChecked: true }, + orderBy: { displayOrder: 'asc' } } } }); if (parentChecklist) { const allSubtasksChecked = parentChecklist.subtasks - .filter((subtask) => !subtask.isOptional) + .filter((subtask) => !subtask.isOptional && subtask.itemType === 'TASK') .every((subtask) => subtask.usersChecked.some((user) => user.userId === userId)); if (allSubtasksChecked) { await prisma.checklist.update({ @@ -431,4 +462,90 @@ export default class OnboardingServices { if (!fileData) throw new NotFoundException('Image File', fileId); return fileData; } + + /** + * Reorders top-level tasks + * @param taskIds array of checklist IDs in desired order + * @param organization the organization of the checklists + */ + static async reorderTasks(user: User, taskIds: string[], organization: Organization) { + if (!(await userHasPermission(user.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('reorder tasks'); + } + + // Validate all tasks exist and belong to organization + const tasks = await prisma.checklist.findMany({ + where: { + checklistId: { in: taskIds }, + organizationId: organization.organizationId, + dateDeleted: null, + parentChecklistId: null + } + }); + + if (tasks.length !== taskIds.length) { + throw new HttpException(400, 'One or more task IDs are invalid'); + } + + await prisma.$transaction(async (tx) => { + // Update displayOrder for each task + await Promise.all( + taskIds.map((taskId, index) => + tx.checklist.update({ + where: { checklistId: taskId }, + data: { displayOrder: index + 1 } + }) + ) + ); + }) + + } + + /** + * Reorders subtasks and info blocks within a parent checklist + * @param parentId the parent checklist ID + * @param itemIds array of item IDs in desired order + * @param organization the organization of the checklists + */ + static async reorderChecklistItems(user: User, parentId: string, itemIds: string[], organization: Organization) { + if (!(await userHasPermission(user.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('reorder checklist items'); + } + + // Validate parent exists + const parent = await prisma.checklist.findUnique({ + where: { checklistId: parentId, organizationId: organization.organizationId } + }); + + if (!parent) { + throw new NotFoundException('Checklist', parentId); + } + + // Validate all items exist and belong to parent + const items = await prisma.checklist.findMany({ + where: { + checklistId: { in: itemIds }, + parentChecklistId: parentId, + organizationId: organization.organizationId, + dateDeleted: null + } + }); + + if (items.length !== itemIds.length) { + throw new HttpException(400, 'One or more item IDs are invalid'); + } + + await prisma.$transaction(async (tx) => { + // Update displayOrder for each item + await Promise.all( + itemIds.map((itemId, index) => + tx.checklist.update({ + where: { checklistId: itemId }, + data: { displayOrder: index + 1 } + }) + ) + ); + }) + + } } diff --git a/src/backend/src/services/organizations.services.ts b/src/backend/src/services/organizations.services.ts index 26f3b3782b..be61dba575 100644 --- a/src/backend/src/services/organizations.services.ts +++ b/src/backend/src/services/organizations.services.ts @@ -122,10 +122,9 @@ export default class OrganizationsService { const applyInterestImageData = applyInterestImage ? await uploadFile(applyInterestImage) : null; const exploreAsGuestImageData = exploreAsGuestImage ? await uploadFile(exploreAsGuestImage) : null; - const updateData = { ...(applyInterestImageData && { applyInterestImageId: applyInterestImageData.id }), - ...(exploreAsGuestImageData && { exploreAsGuestImageId: exploreAsGuestImageData.id }) + ...(exploreAsGuestImageData && { exploreAsGuestImageId: exploreAsGuestImageData.id }), }; const newImages = await prisma.organization.update({ @@ -353,6 +352,56 @@ export default class OrganizationsService { return organization.logoImageId; } + /** + * Sets the new member image for an organization, User must be admin + * @param newMemberImage the image which will be uploaded and have its id stored in the org + * @param submitter the user submitting the image + * @param organization the organization whose new member image is being set + * @returns the updated organization + * @throws if the user is not an admin + */ + static async setNewMemberImage( + newMemberImage: Express.Multer.File, + submitter: User, + organization: Organization + ): Promise { + if (!(await userHasPermission(submitter.userId, organization.organizationId, isAdmin))) { + throw new AccessDeniedAdminOnlyException('update new member image'); + } + + const newMemberImageData = await uploadFile(newMemberImage); + + if (!newMemberImageData?.name) { + throw new HttpException(500, 'Image Name not found'); + } + + const updatedOrg = await prisma.organization.update({ + where: { organizationId: organization.organizationId }, + data: { + newMemberImageId: newMemberImageData.id + } + }); + + return updatedOrg; + } + + /** + * Gets the new member image of the organization + * @param organizationId the id of the organization + * @returns the id of the image + */ + static async getNewMemberImage(organizationId: string): Promise { + const organization = await prisma.organization.findUnique({ + where: { organizationId } + }); + + if (!organization) { + throw new NotFoundException('Organization', organizationId); + } + + return organization.newMemberImageId; + } + /** * Sets the description of a given organization. * @param description the new description diff --git a/src/backend/src/transformers/organizationTransformer.ts b/src/backend/src/transformers/organizationTransformer.ts index 64a68b815e..89ddc1981c 100644 --- a/src/backend/src/transformers/organizationTransformer.ts +++ b/src/backend/src/transformers/organizationTransformer.ts @@ -4,6 +4,9 @@ import { OrganizationPreview } from 'shared'; export const organizationTransformer = (organization: Organization): OrganizationPreview => { return { ...organization, - applicationLink: organization.applicationLink ?? undefined + applicationLink: organization.applicationLink ?? undefined, + applyInterestImageId: organization.applyInterestImageId ?? undefined, + exploreAsGuestImageId: organization.exploreAsGuestImageId ?? undefined, + newMemberImageId: organization.newMemberImageId ?? undefined }; }; diff --git a/src/frontend/src/apis/onboarding.api.ts b/src/frontend/src/apis/onboarding.api.ts index 7b46202a0b..ce1699ded3 100644 --- a/src/frontend/src/apis/onboarding.api.ts +++ b/src/frontend/src/apis/onboarding.api.ts @@ -83,3 +83,17 @@ export const downloadGoogleImage = async (fileId: string): Promise => { const imageBlob = new Blob([imageBuffer], { type: response.headers['content-type'] }); return imageBlob; }; + +/** + * API call to reorder tasks + */ +export const reorderTasks = (payload: { taskIds: string[] }) => { + return axios.post(apiUrls.reorderTasks(), payload); +}; + +/** + * API call to reorder checklist items (subtasks/info blocks) + */ +export const reorderChecklistItems = (parentId: string, payload: { itemIds: string[] }) => { + return axios.post(apiUrls.reorderChecklistItems(parentId), payload); +}; diff --git a/src/frontend/src/apis/organizations.api.ts b/src/frontend/src/apis/organizations.api.ts index 79f24ac0c7..6ba806add1 100644 --- a/src/frontend/src/apis/organizations.api.ts +++ b/src/frontend/src/apis/organizations.api.ts @@ -54,6 +54,18 @@ export const setOrganizationLogo = async (file: File) => { return axios.post(apiUrls.organizationsSetLogoImage(), formData); }; +export const setOrganizationNewMemberImage = async (file: File) => { + const formData = new FormData(); + formData.append('newMemberImage', file); + return axios.post(apiUrls.organizationsSetNewMemberImage(), formData); +}; + +export const getOrganizationNewMemberImage = async () => { + return axios.get(apiUrls.organizationsNewMemberImage(), { + transformResponse: (data) => JSON.parse(data) + }); +}; + export const setOrganizationFeaturedProjects = async (featuredProjectIds: string[]) => { return axios.post(apiUrls.organizationsSetFeaturedProjects(), { projectIds: featuredProjectIds diff --git a/src/frontend/src/components/NERMarkdown.tsx b/src/frontend/src/components/NERMarkdown.tsx index 456594fcd4..57b5704225 100644 --- a/src/frontend/src/components/NERMarkdown.tsx +++ b/src/frontend/src/components/NERMarkdown.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import ReactMarkdown from 'react-markdown'; +import ReactMarkdown, { Components } from 'react-markdown'; import { Box } from '@mui/material'; interface NERMarkdownProps { @@ -7,6 +7,11 @@ interface NERMarkdownProps { } const NERMarkdown = ({ markdown }: NERMarkdownProps) => { + // make all links open in new tabs + const components: Components = { + a: ({ node, ...props }) => + }; + return ( { } }} > - {markdown} + {markdown} ); }; diff --git a/src/frontend/src/hooks/onboarding.hook.ts b/src/frontend/src/hooks/onboarding.hook.ts index 9effd1aa25..6938d7c09a 100644 --- a/src/frontend/src/hooks/onboarding.hook.ts +++ b/src/frontend/src/hooks/onboarding.hook.ts @@ -1,5 +1,5 @@ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { Checklist } from 'shared'; +import { Checklist, ChecklistPreview, User } from 'shared'; import { getAllChecklists, getGeneralChecklists, @@ -9,10 +9,13 @@ import { toggleChecklist, createChecklist, editChecklist, - getCheckedChecklists + getCheckedChecklists, + reorderTasks, + reorderChecklistItems } from '../apis/onboarding.api'; import { useEffect, useState } from 'react'; import { isChecklistChecked } from '../utils/onboarding.utils'; +import { useCurrentUser } from './users.hooks'; export interface ToggleChecklistPayload { checklistId: string; @@ -25,6 +28,7 @@ export interface ChecklistCreateArgs { parentChecklistId?: string; teamId?: string; teamTypeId?: string; + itemType?: 'TASK' | 'INFO'; } export interface SubtaskCreateArgs { @@ -78,13 +82,62 @@ export const useDeleteChecklist = () => { export const useToggleChecklist = () => { const queryClient = useQueryClient(); - return useMutation( + const currentUser = useCurrentUser(); + + type MutationContext = { + previousChecklists?: Checklist[]; + previousCheckedChecklists?: Checklist[]; + }; + + return useMutation( ['checklists', 'edit'], async (payload) => { const { data } = await toggleChecklist(payload); return data; }, { + onMutate: async ({ checklistId }) => { + // Cancel outgoing queries + await queryClient.cancelQueries(['checklists']); + + // Snapshot previous values + const previousChecklists = queryClient.getQueryData(['checklists']); + const previousCheckedChecklists = queryClient.getQueryData(['checklists', 'checked']); + + // Optimistically update the checklists cache + if (previousChecklists && currentUser) { + const toggleChecklistInTree = (checklists: Checklist[]): Checklist[] => { + return checklists.map((checklist) => { + // If this is the checklist we're toggling + if (checklist.checklistId === checklistId) { + const isCurrentlyChecked = checklist.usersChecked.some((user) => user.userId === currentUser.userId); + return { + ...checklist, + usersChecked: isCurrentlyChecked + ? checklist.usersChecked.filter((user) => user.userId !== currentUser.userId) + : [...checklist.usersChecked, currentUser as User] + }; + } + + return checklist; + }); + }; + + const updatedChecklists = toggleChecklistInTree(previousChecklists); + queryClient.setQueryData(['checklists'], updatedChecklists); + } + + return { previousChecklists, previousCheckedChecklists }; + }, + onError: (_err, _variables, context) => { + // Rollback on error + if (context?.previousChecklists) { + queryClient.setQueryData(['checklists'], context.previousChecklists); + } + if (context?.previousCheckedChecklists) { + queryClient.setQueryData(['checklists', 'checked'], context.previousCheckedChecklists); + } + }, onSuccess: () => { queryClient.invalidateQueries(['checklists']); } @@ -178,3 +231,97 @@ export const useChecklistProgress = (parentChecklists: Checklist[], checkedCheck return progress; }; + +export const useReorderTasks = () => { + const queryClient = useQueryClient(); + + type MutationContext = { + previousChecklists?: Checklist[]; + }; + + return useMutation( + ['checklists', 'reorder'], + async (payload) => { + await reorderTasks(payload); + }, + { + onMutate: async ({ taskIds }) => { + // Cancel outgoing queries + await queryClient.cancelQueries(['checklists']); + + // Snapshot previous value + const previousChecklists = queryClient.getQueryData(['checklists']); + + // Optimistically update cache with new order + if (previousChecklists) { + const reorderedChecklists = taskIds + .map((id) => previousChecklists.find((c) => c.checklistId === id)) + .filter((c): c is Checklist => c !== undefined); + + queryClient.setQueryData(['checklists'], reorderedChecklists); + } + + return { previousChecklists }; + }, + onError: (_err, _variables, context) => { + // Rollback on error + if (context?.previousChecklists) { + queryClient.setQueryData(['checklists'], context.previousChecklists); + } + }, + onSuccess: () => { + queryClient.invalidateQueries(['checklists']); + } + } + ); +}; + +export const useReorderChecklistItems = (parentId: string) => { + const queryClient = useQueryClient(); + + type MutationContext = { + previousChecklists?: Checklist[]; + }; + + return useMutation( + ['checklists', 'reorder', parentId], + async (payload) => { + await reorderChecklistItems(parentId, payload); + }, + { + onMutate: async ({ itemIds }) => { + // Cancel outgoing queries + await queryClient.cancelQueries(['checklists']); + + // Snapshot previous value + const previousChecklists = queryClient.getQueryData(['checklists']); + + // Optimistically reorder subtasks within the parent + if (previousChecklists) { + const updatedChecklists = previousChecklists.map((checklist) => { + if (checklist.checklistId === parentId && checklist.subtasks) { + const subtasksAsChecklists = checklist.subtasks as unknown as Checklist[]; + const reorderedSubtasks = itemIds + .map((id) => subtasksAsChecklists.find((s) => s.checklistId === id)) + .filter((s): s is Checklist => s !== undefined); + return { ...checklist, subtasks: reorderedSubtasks as unknown as ChecklistPreview[] }; + } + return checklist; + }); + queryClient.setQueryData(['checklists'], updatedChecklists); + } + + return { previousChecklists }; + }, + onError: (_err, _variables, context) => { + // Rollback on error + if (context?.previousChecklists) { + queryClient.setQueryData(['checklists'], context.previousChecklists); + } + }, + onSuccess: () => { + queryClient.invalidateQueries(['checklists']); + } + } + ); +}; diff --git a/src/frontend/src/hooks/organizations.hooks.ts b/src/frontend/src/hooks/organizations.hooks.ts index d07ddf7ce7..cff6cd0f45 100644 --- a/src/frontend/src/hooks/organizations.hooks.ts +++ b/src/frontend/src/hooks/organizations.hooks.ts @@ -18,7 +18,9 @@ import { setPartReviewGuideLink, setSlackSponsorshipNotificationSlackChannelId, getFinanceDelegates, - setFinanceDelegates + setFinanceDelegates, + setOrganizationNewMemberImage, + getOrganizationNewMemberImage } from '../apis/organizations.api'; import { downloadGoogleImage } from '../apis/organizations.api'; @@ -213,6 +215,26 @@ export const useOrganizationLogo = () => { }); }; +export const useOrganizationNewMemberImage = () => { + return useQuery(['organizations', 'new-member-image'], async () => { + const { data: fileId } = await getOrganizationNewMemberImage(); + if (!fileId) { + return; + } + return await downloadGoogleImage(fileId); + }); +}; + +export const useSetOrganizationNewMemberImage = () => { + const queryClient = useQueryClient(); + return useMutation(['organizations', 'new-member-image'], async (file: File) => { + const { data } = await setOrganizationNewMemberImage(file); + queryClient.invalidateQueries(['organizations']); + queryClient.invalidateQueries(['organizations', 'new-member-image']); + return data; + }); +}; + /* * Custom React Hook to fetch confluence guide for current * organization in backend diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx index 173f236d24..52e5fa877e 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx @@ -8,8 +8,9 @@ import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; import CreateChecklistModal from './CreateChecklistModal'; import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; import { useToast } from '../../../../hooks/toasts.hooks'; -import { useDeleteChecklist } from '../../../../hooks/onboarding.hook'; +import { useDeleteChecklist, useReorderTasks } from '../../../../hooks/onboarding.hook'; import NERDeleteModal from '../../../../components/NERDeleteModal'; +import { DragDropContext, Droppable, Draggable, OnDragEndResponder } from '@hello-pangea/dnd'; export const AdminChecklist: React.FC<{ parentChecklists: Checklist[]; checklistName?: string; teamType?: TeamType }> = ({ parentChecklists, @@ -19,6 +20,7 @@ export const AdminChecklist: React.FC<{ parentChecklists: Checklist[]; checklist const [showTasks, setShowTasks] = useState(false); const [showCreateModal, setShowCreateModal] = useState(false); const [tasksToDelete, setTasksToDelete] = useState(null); + const [localTasks, setLocalTasks] = useState(parentChecklists); const toggleShowTasks = () => { setShowTasks((prev) => !prev); @@ -26,6 +28,12 @@ export const AdminChecklist: React.FC<{ parentChecklists: Checklist[]; checklist const toast = useToast(); const { mutateAsync: deleteChecklist } = useDeleteChecklist(); + const { mutate: reorderTasks } = useReorderTasks(); + + // Update local tasks when parentChecklists changes + useState(() => { + setLocalTasks(parentChecklists); + }); const handleDelete = async () => { if (!tasksToDelete) return; @@ -43,6 +51,34 @@ export const AdminChecklist: React.FC<{ parentChecklists: Checklist[]; checklist setTasksToDelete(null); }; + const onDragEnd: OnDragEndResponder = (result) => { + const { destination, source } = result; + + if (!destination) { + return; + } + + if (destination.index === source.index) { + return; + } + + // Reorder locally + const newTasks = Array.from(localTasks); + const [removed] = newTasks.splice(source.index, 1); + newTasks.splice(destination.index, 0, removed); + + setLocalTasks(newTasks); + + // Send to backend + const taskIds = newTasks.map((task) => task.checklistId); + reorderTasks({ taskIds }, { + onError: (error: any) => { + toast.error(error.message || 'Failed to reorder tasks'); + setLocalTasks(parentChecklists); // Revert on error + } + }); + }; + return ( @@ -86,9 +122,24 @@ export const AdminChecklist: React.FC<{ parentChecklists: Checklist[]; checklist borderRadius: '0px 0px 10px 10px' }} > - {parentChecklists.map((parentChecklist) => ( - - ))} + + + {(provided) => ( +
    + {localTasks.map((parentChecklist, index) => ( + + {(provided) => ( +
    + +
    + )} +
    + ))} + {provided.placeholder} +
    + )} +
    +
    setShowCreateModal(true)}> diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx index f25550c4f6..8c004a3203 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx @@ -1,7 +1,7 @@ -import { Typography, useTheme, Grid, IconButton } from '@mui/material'; +import { Typography, useTheme, IconButton } from '@mui/material'; import { Box } from '@mui/system'; import React, { useState } from 'react'; -import { Checklist, ChecklistPreview } from 'shared'; +import { Checklist, ChecklistPreview, ChecklistItemType } from 'shared'; import { GridDragIcon } from '@mui/x-data-grid'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; import CreateSubtaskModal from './CreateSubtaskModal'; @@ -9,9 +9,12 @@ import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; import EditIcon from '@mui/icons-material/Edit'; import NERDeleteModal from '../../../../components/NERDeleteModal'; import { useToast } from '../../../../hooks/toasts.hooks'; -import { useDeleteChecklist } from '../../../../hooks/onboarding.hook'; +import { useDeleteChecklist, useReorderChecklistItems } from '../../../../hooks/onboarding.hook'; import EditSubtaskModal from './EditSubtaskModal'; import NERMarkdown from '../../../../components/NERMarkdown'; +import CreateInfoBlockModal from './CreateInfoBlockModal'; +import EditInfoBlockModal from './EditInfoBlockModal'; +import { DragDropContext, Droppable, Draggable, OnDragEndResponder } from '@hello-pangea/dnd'; interface AdminSubtaskSectionProps { parentTask: Checklist; @@ -20,98 +23,182 @@ interface AdminSubtaskSectionProps { const AdminSubtaskSection: React.FC = ({ parentTask }) => { const theme = useTheme(); const toast = useToast(); - const [showCreateModal, setShowCreateModal] = useState(false); - const [taskToDelete, setTaskToDelete] = useState(null); + const [showCreateTaskModal, setShowCreateTaskModal] = useState(false); + const [showCreateInfoModal, setShowCreateInfoModal] = useState(false); + const [itemToDelete, setItemToDelete] = useState(null); const [taskToEdit, setTaskToEdit] = useState(null); + const [infoToEdit, setInfoToEdit] = useState(null); const { mutateAsync: deleteChecklist } = useDeleteChecklist(); + const { mutate: reorderItems } = useReorderChecklistItems(parentTask.checklistId); - const handleDelete = async (taskId: string) => { + const handleDelete = async (itemId: string) => { try { - await deleteChecklist(taskId); - toast.success('Task deleted successfully'); + await deleteChecklist(itemId); + toast.success('Item deleted successfully'); } catch (error: unknown) { if (error instanceof Error) { toast.error(error.message); } } - setTaskToDelete(null); + setItemToDelete(null); }; const { subtasks } = parentTask; + // All items (tasks and info blocks) are now stored in subtasks with itemType field + const allItems = subtasks + .map((subtask) => ({ + ...subtask, + itemType: subtask.itemType ?? ('TASK' as ChecklistItemType), + displayOrder: subtask.displayOrder ?? 999 + })) + .sort((a, b) => a.displayOrder - b.displayOrder); + + const [localItems, setLocalItems] = useState(allItems); + + // Update local items when allItems changes + useState(() => { + setLocalItems(allItems); + }); + + const onDragEnd: OnDragEndResponder = (result) => { + const { destination, source } = result; + + if (!destination) { + return; + } + + if (destination.index === source.index) { + return; + } + + // Reorder locally + const newItems = Array.from(localItems); + const [removed] = newItems.splice(source.index, 1); + newItems.splice(destination.index, 0, removed); + + setLocalItems(newItems); + + // Send to backend - all items are now real checklist items + const itemIds = newItems.map((item) => item.checklistId); + reorderItems({ itemIds }, { + onError: (error: any) => { + toast.error(error.message || 'Failed to reorder items'); + setLocalItems(allItems); // Revert on error + } + }); + }; + return ( - {subtasks.length > 0 && ( - - - - {subtasks.map((subtask) => ( - - - - - - - {subtask.name} {subtask.isOptional && '(Optional)'} - - - - setTaskToDelete(subtask)}> - - - setTaskToEdit(subtask)}> - - - - - ))} - - - - )} - {parentTask.descriptions.map((description) => ( - - + {localItems.length > 0 && ( + + + + {(provided) => ( +
    + {localItems.map((item, index) => ( + + {(provided) => ( +
    + + {item.itemType === 'TASK' ? ( + <> + + + + + + + + {item.name} {item.isOptional && '(Optional)'} + + + + setItemToDelete(item)}> + + + setTaskToEdit(item)}> + + + + + ) : ( + <> + + + + + + + + + + + setItemToDelete(item)}> + + + setInfoToEdit({ ...item, descriptions: (item as any).descriptions || [item.name] })}> + + + + + + )} + +
    + )} +
    + ))} + {provided.placeholder} +
    + )} +
    +
    - ))} - - setShowCreateModal(true)}> + )} + + setShowCreateTaskModal(true)}> Add Subtask + setShowCreateInfoModal(true)}> + + Add Information + - {showCreateModal && ( + {showCreateTaskModal && ( setShowCreateModal(false)} + open={showCreateTaskModal} + handleClose={() => setShowCreateTaskModal(false)} parentChecklist={parentTask} /> )} - {taskToDelete && ( + {showCreateInfoModal && ( + setShowCreateInfoModal(false)} + parentChecklist={parentTask} + /> + )} + {itemToDelete && ( setTaskToDelete(null)} - formId="delete-task-form" - dataType="Task" - onFormSubmit={() => handleDelete(taskToDelete.checklistId)} + open={!!itemToDelete} + onHide={() => setItemToDelete(null)} + formId="delete-item-form" + dataType={itemToDelete.itemType === 'INFO' ? 'Information Block' : 'Task'} + onFormSubmit={() => handleDelete(itemToDelete.checklistId)} /> )} {taskToEdit && ( @@ -122,6 +209,14 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) defaultValues={taskToEdit} /> )} + {infoToEdit && ( + setInfoToEdit(null)} + parentChecklist={parentTask} + defaultValues={infoToEdit} + /> + )} ); }; diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx index 8a37818604..2c7e79882c 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx @@ -1,6 +1,6 @@ import ErrorPage from '../../../ErrorPage'; import LoadingIndicator from '../../../../components/LoadingIndicator'; -import { ChecklistCreateArgs, useCreateChecklist } from '../../../../hooks/onboarding.hook'; +import { useCreateChecklist } from '../../../../hooks/onboarding.hook'; import { useToast } from '../../../../hooks/toasts.hooks'; import { yupResolver } from '@hookform/resolvers/yup'; import { @@ -15,13 +15,16 @@ import { } from '@mui/material'; import { Box, Stack } from '@mui/system'; import React, { useState } from 'react'; -import { useForm, useFieldArray, Controller } from 'react-hook-form'; -import { CreateChecklistPreview } from 'shared'; +import { useForm, Controller } from 'react-hook-form'; import NERFormModal from '../../../../components/NERFormModal'; import * as yup from 'yup'; import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; import NERMarkdown from '../../../../components/NERMarkdown'; +import { DragDropContext, Droppable, Draggable, OnDragEndResponder } from '@hello-pangea/dnd'; +import { GridDragIcon } from '@mui/x-data-grid'; +import CheckBoxIcon from '@mui/icons-material/CheckBox'; +import InfoIcon from '@mui/icons-material/Info'; interface CreateChecklistModalProps { open: boolean; @@ -30,51 +33,38 @@ interface CreateChecklistModalProps { teamTypeId?: string; } +type ItemType = 'TASK' | 'INFO'; + +interface ChecklistItem { + id: string; + type: ItemType; + name?: string; // For tasks + isOptional?: boolean; // For tasks + content?: string; // For info blocks +} + interface ChecklistFormValues { name: string; - descriptions: { name: string }[]; - subtasks: CreateChecklistPreview[]; } -const schema = yup.object().shape({ - name: yup.string().required('Name is Required'), - descriptions: yup - .array() - .of( - yup.object().shape({ - name: yup.string().required('Description is Required') - }) - ) - .required() - .min(1, 'At least one description is required'), - subtasks: yup - .array() - .of( - yup.object().shape({ - name: yup.string().required('Subtask Name is Required'), - isOptional: yup.boolean().required('Is Optional is Required') - }) - ) - .required() -}); +const schema: yup.ObjectSchema = yup.object().shape({ + name: yup.string().required('Name is Required') +}) as any; const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateChecklistModalProps) => { const theme = useTheme(); const toast = useToast(); const { mutateAsync: createChecklist, isLoading, isError, error } = useCreateChecklist(); - const [subtasks, setSubtasks] = useState([{ name: '', isOptional: false, descriptions: [] }]); + const [items, setItems] = useState([]); const defaultValues = { - name: '', - descriptions: [{ name: '' }], - subtasks: [] + name: '' }; const { handleSubmit, control, - watch, reset, formState: { errors } } = useForm({ @@ -82,67 +72,99 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC defaultValues }); - const { fields, append, remove } = useFieldArray({ - control, - name: 'descriptions' - }); + const addTask = () => { + setItems([...items, { id: `task-${Date.now()}`, type: 'TASK', name: '', isOptional: false }]); + }; + + const addInfoBlock = () => { + setItems([...items, { id: `info-${Date.now()}`, type: 'INFO', content: '' }]); + }; + + const updateItem = (index: number, updates: Partial) => { + const newItems = [...items]; + newItems[index] = { ...newItems[index], ...updates }; + setItems(newItems); + }; + + const removeItem = (index: number) => { + setItems(items.filter((_, i) => i !== index)); + }; + + const onDragEnd: OnDragEndResponder = (result) => { + const { destination, source } = result; + + if (!destination || destination.index === source.index) { + return; + } + + const newItems = Array.from(items); + const [removed] = newItems.splice(source.index, 1); + newItems.splice(destination.index, 0, removed); + setItems(newItems); + }; if (isError) return ; if (isLoading) return ; - const onFormSubmit = async (data: ChecklistCreateArgs) => { + const onFormSubmit = async (data: ChecklistFormValues) => { try { const formattedData = { - ...data, + name: data.name, + descriptions: [], + isOptional: false, teamId, - teamTypeId, - descriptions: (data.descriptions as unknown as { name: string }[]).map((desc) => desc.name) + teamTypeId }; const parentChecklist = await createChecklist(formattedData); - // Handle subtasks - const filteredSubtasks = subtasks.filter((subtask) => subtask.name !== ''); + // Create all items in order with their displayOrder set await Promise.all( - filteredSubtasks.map((subtask) => - createChecklist({ - name: subtask.name, - descriptions: [], - teamId, - teamTypeId, - parentChecklistId: parentChecklist.checklistId, - isOptional: subtask.isOptional - }) - ) + items.map((item) => { + if (item.type === 'TASK' && item.name) { + return createChecklist({ + name: item.name, + descriptions: [], + teamId, + teamTypeId, + parentChecklistId: parentChecklist.checklistId, + isOptional: item.isOptional || false, + itemType: 'TASK' + }); + } else if (item.type === 'INFO' && item.content) { + return createChecklist({ + name: 'Info Block', + descriptions: [item.content], + teamId, + teamTypeId, + parentChecklistId: parentChecklist.checklistId, + isOptional: false, + itemType: 'INFO' + }); + } + return Promise.resolve(); + }) ); + toast.success('Task created successfully'); handleClose(); + reset(); + setItems([]); } catch (error) { toast.error('Failed to create checklist'); console.error('Error in onFormSubmit:', error); } }; - const addSubtask = () => { - setSubtasks([...subtasks, { name: '', isOptional: false, descriptions: [] }]); - }; - - const deleteSubtask = (index: number) => { - const updatedSubtasks = subtasks.filter((_, i) => i !== index); - setSubtasks(updatedSubtasks); - }; - - const handleSubtaskChange = (index: number, key: string, value: any) => { - const updatedSubtasks = subtasks.map((subtask, i) => (i === index ? { ...subtask, [key]: value } : subtask)); - setSubtasks(updatedSubtasks); - }; - return ( reset({ name: '', descriptions: [] })} + reset={() => { + reset({ name: '' }); + setItems([]); + }} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} formId={'create-task-form'} @@ -188,211 +210,206 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC )} /> - - - - Subtasks - - - Optional? - - - - {subtasks.map((subtask, index) => ( - handleSubtaskChange(index, 'name', e.target.value)} - placeholder="Subtask Name" - fullWidth - InputProps={{ - endAdornment: ( - - handleSubtaskChange(index, 'isOptional', e.target.checked)} - /> - deleteSubtask(index)}> - - - - ), - disableUnderline: true, - sx: { - '& fieldset': { border: 'none' } - } - }} - sx={{ - backgroundColor: theme.palette.background.paper, - borderRadius: 5, - mt: 1, - width: '100%' - }} - /> - ))} - + + + Subtasks & Information + + + + {(provided) => ( +
    + {items.map((item, index) => ( + + {(provided) => ( +
    + {item.type === 'TASK' ? ( + + + + + + + + updateItem(index, { name: e.target.value })} + placeholder="Subtask Name" + fullWidth + InputProps={{ + endAdornment: ( + + Optional? + updateItem(index, { isOptional: e.target.checked })} + size="small" + /> + removeItem(index)} size="small"> + + + + ), + disableUnderline: true, + sx: { + '& fieldset': { border: 'none' } + } + }} + sx={{ + backgroundColor: theme.palette.background.paper, + borderRadius: 5 + }} + /> + + ) : ( + + + + + + + + + + + + updateItem(index, { content: e.target.value })} + placeholder="Enter markdown content..." + fullWidth + multiline + variant="outlined" + minRows={8} + maxRows={15} + InputProps={{ + endAdornment: ( + + removeItem(index)} size="small"> + + + + ), + disableUnderline: true, + sx: { + '& fieldset': { border: 'none' }, + fontSize: '1.1rem', + lineHeight: 1.6, + padding: 2 + } + }} + sx={{ + backgroundColor: theme.palette.background.paper, + borderRadius: 3, + '& .MuiInputBase-root': { + alignItems: 'flex-start' + } + }} + /> + + + + Preview: + + + {item.content ? ( + + ) : ( + + Start typing to see formatted markdown... + + )} + + + + + )} +
    + )} +
    + ))} + {provided.placeholder} +
    + )} +
    +
    +
    + Add Subtask + + + Add Information Block + - - - - Descriptions* - - {fields.map((item, index) => ( - - - ( - - remove(index)}> - - - - ), - disableUnderline: true, - sx: { - '& fieldset': { border: 'none' }, - fontSize: '1.1rem', - lineHeight: 1.6, - padding: 2 - } - }} - sx={{ - backgroundColor: theme.palette.background.paper, - borderRadius: 3, - width: '100%', - '& .MuiInputBase-root': { - alignItems: 'flex-start' - } - }} - error={!!errors.descriptions?.[index]?.name} - helperText={errors.descriptions?.[index]?.name?.message} - /> - )} - /> - - - - Preview: - - - {watch(`descriptions.${index}.name`) ? ( - - ) : ( - - Start typing to see formatted markdown... - - )} - - - - ))} - - append({ name: '' })} - sx={{ - backgroundColor: theme.palette.background.paper, - borderRadius: 5, - mt: 1, - fontSize: '1rem', - padding: 1.5, - width: '100%', - justifyContent: 'flex-start' - }} - > - - Add Additional Information - - -
    ); diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx new file mode 100644 index 0000000000..34eb1de4e2 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx @@ -0,0 +1,165 @@ +import { FormControl, FormLabel, TextField, useTheme, Typography, Box } from '@mui/material'; +import React from 'react'; +import { useForm, Controller } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import * as yup from 'yup'; +import NERFormModal from '../../../../components/NERFormModal'; +import { useCreateChecklist } from '../../../../hooks/onboarding.hook'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { Checklist } from 'shared'; +import NERMarkdown from '../../../../components/NERMarkdown'; + +interface CreateInfoBlockModalProps { + open: boolean; + handleClose: () => void; + parentChecklist: Checklist; +} + +interface InfoBlockFormValues { + content: string; +} + +const schema = yup.object().shape({ + content: yup.string().required('Content is required') +}); + +const CreateInfoBlockModal: React.FC = ({ open, handleClose, parentChecklist }) => { + const theme = useTheme(); + const toast = useToast(); + const { mutateAsync: createChecklist } = useCreateChecklist(); + + const { + handleSubmit, + control, + watch, + reset, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { content: '' } + }); + + const contentValue = watch('content'); + + const onFormSubmit = async (data: InfoBlockFormValues) => { + try { + + await createChecklist({ + name: 'Info Block', // Name is required but not used for info blocks + descriptions: [data.content], + isOptional: false, + parentChecklistId: parentChecklist.checklistId, + teamId: parentChecklist.team?.teamId, + teamTypeId: parentChecklist.teamType?.teamTypeId, + itemType: 'INFO' + }); + toast.success('Information block created successfully'); + handleClose(); + reset(); + } catch (error: any) { + toast.error(error.message || 'Failed to create information block'); + } + }; + + return ( + { + handleClose(); + reset(); + }} + title="Create Information Block" + reset={() => reset({ content: '' })} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="create-info-block-form" + showCloseButton + paperProps={{ maxWidth: '90vw', minWidth: '80vw' }} + > + + + + Content (Markdown)* + + ( + + )} + /> + + + + Preview: + + {contentValue ? ( + + ) : ( + + Start typing to see formatted markdown... + + )} + + + + ); +}; + +export default CreateInfoBlockModal; + diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx new file mode 100644 index 0000000000..5498f14d24 --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx @@ -0,0 +1,161 @@ +import { FormControl, FormLabel, TextField, useTheme, Typography, Box } from '@mui/material'; +import React from 'react'; +import { useForm, Controller } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import * as yup from 'yup'; +import NERFormModal from '../../../../components/NERFormModal'; +import { useEditChecklist } from '../../../../hooks/onboarding.hook'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { Checklist, ChecklistPreview } from 'shared'; +import NERMarkdown from '../../../../components/NERMarkdown'; + +interface EditInfoBlockModalProps { + open: boolean; + handleClose: () => void; + parentChecklist: Checklist; + defaultValues: ChecklistPreview & { descriptions?: string[] }; +} + +interface InfoBlockFormValues { + content: string; +} + +const schema = yup.object().shape({ + content: yup.string().required('Content is required') +}); + +const EditInfoBlockModal: React.FC = ({ open, handleClose, parentChecklist, defaultValues }) => { + const theme = useTheme(); + const toast = useToast(); + const { mutateAsync: editChecklist } = useEditChecklist(defaultValues.checklistId); + + const { + handleSubmit, + control, + watch, + reset, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { content: defaultValues.descriptions?.[0] || '' } + }); + + const contentValue = watch('content'); + + const onFormSubmit = async (data: InfoBlockFormValues) => { + try { + await editChecklist({ + name: 'Info Block', // Name is required but not used for info blocks + descriptions: [data.content], + isOptional: false, + parentChecklistId: parentChecklist.checklistId, + teamId: parentChecklist.team?.teamId, + teamTypeId: parentChecklist.teamType?.teamTypeId, + itemType: 'INFO' + }); + toast.success('Information block updated successfully'); + handleClose(); + } catch (error: any) { + toast.error(error.message || 'Failed to update information block'); + } + }; + + return ( + reset({ content: defaultValues.descriptions?.[0] || '' })} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="edit-info-block-form" + showCloseButton + paperProps={{ maxWidth: '90vw', minWidth: '80vw' }} + > + + + + Content (Markdown)* + + ( + + )} + /> + + + + Preview: + + {contentValue ? ( + + ) : ( + + Start typing to see formatted markdown... + + )} + + + + ); +}; + +export default EditInfoBlockModal; + diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx index f5f78d7ecd..dab87421e0 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx @@ -3,7 +3,7 @@ import NERFormModal from '../../../../components/NERFormModal'; import { FormControl, FormLabel, Box, TextField, useTheme, Checkbox, InputAdornment } from '@mui/material'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; -import { Checklist, ChecklistPreview } from 'shared'; +import { Checklist, ChecklistItemType, ChecklistPreview } from 'shared'; import { ChecklistCreateArgs, SubtaskCreateArgs } from '../../../../hooks/onboarding.hook'; import { useToast } from '../../../../hooks/toasts.hooks'; import React from 'react'; @@ -44,7 +44,8 @@ const SubtaskFormModal = ({ open, handleClose, onSubmit, parentChecklist, defaul descriptions: [], parentChecklistId: parentChecklist.checklistId, teamId: parentChecklist.team?.teamId, - teamTypeId: parentChecklist.teamType?.teamTypeId + teamTypeId: parentChecklist.teamType?.teamTypeId, + itemType: ChecklistItemType.TASK }; await onSubmit(formattedData); diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/OnboardingInfoSection.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/OnboardingInfoSection.tsx index 52cc8cb20d..d9ddb0457c 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/OnboardingInfoSection.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/OnboardingInfoSection.tsx @@ -1,17 +1,27 @@ import { Grid, Typography, List, ListItem, useTheme } from '@mui/material'; import { Box } from '@mui/system'; import UsefulLinksTable from './UsefulLinks/UsefulLinksTable'; -import { useCurrentOrganization } from '../../../hooks/organizations.hooks'; +import { + useCurrentOrganization, + useOrganizationNewMemberImage, + useSetOrganizationNewMemberImage +} from '../../../hooks/organizations.hooks'; import ErrorPage from '../../ErrorPage'; import LoadingIndicator from '../../../components/LoadingIndicator'; import EditIcon from '@mui/icons-material/Edit'; import { useState } from 'react'; import UpdateOnboardingContactsModal from './UpdateContactsModal'; import OnboardingBlock from './OnboardingBlock'; +import NERUploadButton from '../../../components/NERUploadButton'; +import { useToast } from '../../../hooks/toasts.hooks'; +import { MAX_FILE_SIZE } from 'shared'; const OnboardingInfoSection: React.FC = () => { const theme = useTheme(); const [showModal, setShowModal] = useState(false); + const [addedImage, setAddedImage] = useState(undefined); + const toast = useToast(); + const { data: organization, isLoading: organizationIsLoading, @@ -19,10 +29,39 @@ const OnboardingInfoSection: React.FC = () => { error: organizationError } = useCurrentOrganization(); + const { + data: newMemberImageBlob, + isLoading: imageIsLoading, + error: imageError, + isError: imageIsError + } = useOrganizationNewMemberImage(); + const { mutateAsync: uploadNewMemberImage, isLoading: isUploading } = useSetOrganizationNewMemberImage(); + + const handleImageUpload = async () => { + if (!addedImage) return; + + if (addedImage.size >= MAX_FILE_SIZE) { + toast.error(`File must be less than ${MAX_FILE_SIZE / 1024 / 1024} MB`, 5000); + return; + } + + try { + await uploadNewMemberImage(addedImage); + setAddedImage(undefined); + toast.success('Image uploaded successfully!'); + } catch (error: any) { + toast.error(error?.message || 'Failed to upload image'); + } + }; + if (organizationIsError) { return ; } + if (imageIsError) { + return ; + } + if (!organization || organizationIsLoading) return ; return ( @@ -38,6 +77,54 @@ const OnboardingInfoSection: React.FC = () => { }} > + + + + New Member Events Image + + {isUploading || imageIsLoading ? ( + + + + ) : ( + <> + {!addedImage && newMemberImageBlob && ( + + )} + { + if (e.target.files) { + setAddedImage(e.target.files[0]); + } + }} + onSubmit={handleImageUpload} + addedImage={addedImage} + setAddedImage={setAddedImage} + /> + + )} + + { )} diff --git a/src/frontend/src/pages/HomePage/components/Checklist.tsx b/src/frontend/src/pages/HomePage/components/Checklist.tsx index fedf5c670e..342a27a586 100644 --- a/src/frontend/src/pages/HomePage/components/Checklist.tsx +++ b/src/frontend/src/pages/HomePage/components/Checklist.tsx @@ -12,7 +12,7 @@ const Checklist: React.FC<{ checklistName?: string; }> = ({ parentChecklists, checkedChecklists, checklistName }) => { const theme = useTheme(); - const [showTasks, setShowTasks] = useState(false); + const [showTasks, setShowTasks] = useState(true); const progress = useChecklistProgress(parentChecklists, checkedChecklists); const toggleShowTasks = () => { diff --git a/src/frontend/src/pages/HomePage/components/ChecklistSection.tsx b/src/frontend/src/pages/HomePage/components/ChecklistSection.tsx index a94d63b6e8..89b7414700 100644 --- a/src/frontend/src/pages/HomePage/components/ChecklistSection.tsx +++ b/src/frontend/src/pages/HomePage/components/ChecklistSection.tsx @@ -1,10 +1,12 @@ -import { Box, Grid, Link, Typography } from '@mui/material'; +import React from 'react'; +import { Box, Grid, Link, Typography, useTheme } from '@mui/material'; import { groupChecklists } from '../../../utils/onboarding.utils'; import Checklist from './Checklist'; import { Checklist as ChecklistType } from 'shared'; import { useCurrentOrganization } from '../../../hooks/organizations.hooks'; import LoadingIndicator from '../../../components/LoadingIndicator'; import ErrorPage from '../../ErrorPage'; +import { useGetImageUrl } from '../../../hooks/onboarding.hook'; interface ChecklistSectionProps { usersChecklists: ChecklistType[]; @@ -13,8 +15,10 @@ interface ChecklistSectionProps { const ChecklistSection: React.FC = ({ usersChecklists, checkedChecklists }) => { const groupedChecklists = groupChecklists(usersChecklists); + const theme = useTheme(); const { data: organization, isLoading, error, isError } = useCurrentOrganization(); + const { data: newMemberImageUrl } = useGetImageUrl(organization?.newMemberImageId ?? null); if (!organization || isLoading) return ; if (isError) return ; @@ -22,7 +26,7 @@ const ChecklistSection: React.FC = ({ usersChecklists, ch return ( - {organization.applicationLink && ( + {/* {organization.applicationLink && ( APPLY{' '} @@ -32,11 +36,41 @@ const ChecklistSection: React.FC = ({ usersChecklists, ch THEN CONTINUE - )} + )} */} {Object.entries(groupedChecklists).map(([checklistName, checklists]) => ( - - - + + + + + {checklistName === 'General' && newMemberImageUrl && ( + + + + New Member Events + + + + + )} + ))} {!usersChecklists.length && ( diff --git a/src/frontend/src/pages/HomePage/components/ParentTask.tsx b/src/frontend/src/pages/HomePage/components/ParentTask.tsx index 6e4e83dbb4..71076b6bfb 100644 --- a/src/frontend/src/pages/HomePage/components/ParentTask.tsx +++ b/src/frontend/src/pages/HomePage/components/ParentTask.tsx @@ -13,22 +13,12 @@ interface ParentTaskProps { } const ParentTask: React.FC = ({ parentTask, checkedChecklists }) => { - const toast = useToast(); - const [showSubtasks, setShowSubtasks] = useState(false); - const { mutateAsync: toggleChecklist } = useToggleChecklist(); + const [showSubtasks, setShowSubtasks] = useState(true); const toggleShowSubtasks = () => { setShowSubtasks((prev) => !prev); }; - const handleToggleChecklist = async () => { - try { - await toggleChecklist({ checklistId: parentTask.checklistId }); - } catch (error: any) { - toast.error(error.message); - } - }; - return ( = ({ parentTask, checkedChecklists } }} > - + - + {parentTask.name} {showSubtasks ? : } diff --git a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx index 27171a868c..97fd911e8f 100644 --- a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx +++ b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx @@ -1,8 +1,8 @@ -import { Typography, useTheme, Grid, IconButton } from '@mui/material'; +import { Typography, useTheme, IconButton } from '@mui/material'; import Checkbox from '@mui/material/Checkbox'; import { Box } from '@mui/system'; import React from 'react'; -import { Checklist } from 'shared'; +import { Checklist, ChecklistItemType } from 'shared'; import { GridDragIcon } from '@mui/x-data-grid'; import { useToggleChecklist } from '../../../hooks/onboarding.hook'; import { useToast } from '../../../hooks/toasts.hooks'; @@ -19,16 +19,36 @@ const SubtaskSection: React.FC = ({ parentTask, checkedChec const theme = useTheme(); const toast = useToast(); const { subtasks } = parentTask; - const { mutateAsync: toggleChecklist } = useToggleChecklist(); + const { mutate: toggleChecklist } = useToggleChecklist(); - const handleToggleChecklist = async (subtaskId: string) => { - try { - await toggleChecklist({ checklistId: subtaskId }); - } catch (error: any) { - toast.error(error.message); - } + const handleToggleChecklist = (subtaskId: string) => { + toggleChecklist({ checklistId: subtaskId }, { + onError: (error: any) => { + toast.error(error.message); + } + }); }; + // All items (tasks and info blocks) are now stored in subtasks with itemType field + // Keep descriptions for backward compatibility with old data + const allItems = [ + ...subtasks.map((subtask) => ({ + ...subtask, + itemType: subtask.itemType ?? 'TASK', + displayOrder: subtask.displayOrder ?? 999 + })), + // Backward compatibility: show old descriptions only if they exist and aren't already in subtasks as info blocks + ...(parentTask.descriptions && parentTask.descriptions.length > 0 + ? parentTask.descriptions.map((description, index) => ({ + checklistId: `info-${index}`, + name: description, + itemType: 'INFO' as const, + displayOrder: 1000 + index, + isOptional: false + })) + : []) + ].sort((a, b) => a.displayOrder - b.displayOrder); + return ( = ({ parentTask, checkedChec } } > - {subtasks.length > 0 ? ( - - - - {subtasks.map((subtask) => ( - - {isAdmin ? ( - - - - ) : ( - handleToggleChecklist(subtask.checklistId)}> - - - )} - - {subtask.name} {subtask.isOptional && '(Optional)'} - - - ))} - - - - - - - ) : ( - - {parentTask.descriptions.map((description) => { + + {allItems.map((item) => { + if (item.itemType === 'TASK') { + return ( + + {isAdmin ? ( + + + + ) : ( + handleToggleChecklist(item.checklistId)}> + + + )} + + {item.name} {item.isOptional && '(Optional)'} + + + ); + } else { + // INFO block - content is in descriptions[0] for new items, or name for backward compatibility + const content = (item as any).descriptions?.[0] || item.name; return ( - - - + + ); - })} - - )} + } + })} + ); }; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 508ff4fed1..5c58780538 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -374,6 +374,8 @@ const organizationsSetDescription = () => `${organizations()}/description/set`; const organizationsFeaturedProjects = () => `${organizations()}/featured-projects`; const organizationsLogoImage = () => `${organizations()}/logo`; const organizationsSetLogoImage = () => `${organizations()}/logo/update`; +const organizationsNewMemberImage = () => `${organizations()}/new-member-image`; +const organizationsSetNewMemberImage = () => `${organizations()}/new-member-image/update`; const organizationsSetFeaturedProjects = () => `${organizationsFeaturedProjects()}/set`; const organizationsSetWorkspaceId = () => `${organizations()}/workspaceId/set`; const organizationsGetPartReviewGuideLink = () => `${organizations()}/part-review-guide-link/get`; @@ -408,6 +410,8 @@ const createChecklist = () => `${onboarding()}/checklist/create`; const editChecklist = (checklistId: string) => `${onboarding()}/checklist/edit/${checklistId}`; const checklistDelete = (id: string) => `${onboarding()}/checklist/delete/${id}`; const imageById = (imageId: string) => `${onboarding()}/image/${imageId}`; +const reorderTasks = () => `${onboarding()}/tasks/reorder`; +const reorderChecklistItems = (parentId: string) => `${onboarding()}/tasks/${parentId}/items/reorder`; /************** Pop Up Endpoints ***************/ const popUps = () => `${API_URL}/pop-ups`; @@ -722,6 +726,8 @@ export const apiUrls = { organizationsSetDescription, organizationsLogoImage, organizationsSetLogoImage, + organizationsNewMemberImage, + organizationsSetNewMemberImage, organizationsSetFeaturedProjects, organizationsSetWorkspaceId, organizationsGetPartReviewGuideLink, @@ -743,6 +749,8 @@ export const apiUrls = { faqEdit, faqDelete, imageById, + reorderTasks, + reorderChecklistItems, popUps, popUpsCurrentUser, diff --git a/src/shared/src/types/checklist-types.ts b/src/shared/src/types/checklist-types.ts index 0e825c9d12..f6a3be6273 100644 --- a/src/shared/src/types/checklist-types.ts +++ b/src/shared/src/types/checklist-types.ts @@ -7,6 +7,11 @@ import { TeamType } from './design-review-types'; import { Team } from './team-types'; import { User } from './user-types'; +export enum ChecklistItemType { + TASK = 'TASK', + INFO = 'INFO' +} + export interface Checklist { checklistId: string; name: string; @@ -14,6 +19,8 @@ export interface Checklist { team?: Team; descriptions: string[]; isOptional: boolean; + displayOrder?: number; + itemType: ChecklistItemType; subtasks: ChecklistPreview[]; parentChecklistId?: string; usersChecked: User[]; @@ -23,6 +30,6 @@ export interface Checklist { dateDeleted?: Date; } -export type ChecklistPreview = Pick; +export type ChecklistPreview = Pick; export type CreateChecklistPreview = Omit; diff --git a/src/shared/src/types/user-types.ts b/src/shared/src/types/user-types.ts index 78667ab53e..3ddbfa08af 100644 --- a/src/shared/src/types/user-types.ts +++ b/src/shared/src/types/user-types.ts @@ -42,7 +42,7 @@ export type ThemeName = 'DARK' | 'LIGHT'; export type OrganizationPreview = Pick< Organization, - 'organizationId' | 'name' | 'dateCreated' | 'dateDeleted' | 'description' | 'applicationLink' + 'organizationId' | 'name' | 'dateCreated' | 'dateDeleted' | 'description' | 'applicationLink' | 'applyInterestImageId' | 'exploreAsGuestImageId' | 'newMemberImageId' >; export interface Organization { @@ -57,6 +57,7 @@ export interface Organization { description: string; applyInterestImageId?: string; exploreAsGuestImageId?: string; + newMemberImageId?: string; applicationLink?: string; onboardingText?: string; contacts: Contact[]; From dacc8ccb91b77e4c929ecc3f73389d3c4cff400b Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Wed, 7 Jan 2026 13:26:11 -0500 Subject: [PATCH 455/477] #3767 migrated away from description blocks --- .../src/controllers/onboarding.controllers.ts | 10 +- .../migration.sql | 82 +++++- src/backend/src/prisma/schema.prisma | 3 +- src/backend/src/prisma/seed.ts | 30 +- src/backend/src/routes/onboarding.routes.ts | 8 +- .../src/routes/organizations.routes.ts | 6 +- .../src/services/onboarding.services.ts | 42 +-- .../src/services/organizations.services.ts | 2 +- src/backend/tests/test-utils.ts | 4 +- src/backend/tests/unmocked/onboarding.test.ts | 56 ++-- src/frontend/src/hooks/onboarding.hook.ts | 3 +- .../Checklists/AdminChecklist.tsx | 15 +- .../Checklists/AdminSubtaskSection.tsx | 27 +- .../OnboardingConfig/Checklists/AdminTask.tsx | 17 +- .../Checklists/CreateChecklistModal.tsx | 25 +- .../Checklists/CreateInfoBlockModal.tsx | 7 +- .../Checklists/EditChecklistModal.tsx | 278 ------------------ .../Checklists/EditInfoBlockModal.tsx | 12 +- .../Checklists/SubtaskFormModal.tsx | 8 +- .../HomePage/components/ChecklistSection.tsx | 2 +- .../pages/HomePage/components/ParentTask.tsx | 4 +- .../HomePage/components/SubtaskSection.tsx | 64 ++-- .../src/pages/HomePage/components/Task.tsx | 2 +- src/shared/src/types/checklist-types.ts | 8 +- src/shared/src/types/user-types.ts | 10 +- 25 files changed, 231 insertions(+), 494 deletions(-) delete mode 100644 src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditChecklistModal.tsx diff --git a/src/backend/src/controllers/onboarding.controllers.ts b/src/backend/src/controllers/onboarding.controllers.ts index 9262e734f8..c7faff2059 100644 --- a/src/backend/src/controllers/onboarding.controllers.ts +++ b/src/backend/src/controllers/onboarding.controllers.ts @@ -32,11 +32,10 @@ export default class OnboardingController { static async createChecklist(req: Request, res: Response, next: NextFunction) { try { - const { name, descriptions, isOptional, teamId, teamTypeId, parentChecklistId, itemType } = req.body; + const { content, isOptional, teamId, teamTypeId, parentChecklistId, itemType } = req.body; const checklist = await OnboardingServices.createChecklist( req.currentUser, - name, - descriptions, + content, teamId, teamTypeId, parentChecklistId, @@ -53,12 +52,11 @@ export default class OnboardingController { static async editChecklist(req: Request, res: Response, next: NextFunction) { try { const { checklistId } = req.params; - const { name, descriptions, isOptional, teamId, teamTypeId, parentChecklistId, itemType } = req.body; + const { content, isOptional, teamId, teamTypeId, parentChecklistId, itemType } = req.body; const checklist = await OnboardingServices.editChecklist( req.currentUser, checklistId, - name, - descriptions, + content, teamId, teamTypeId, parentChecklistId, diff --git a/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql b/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql index 6df5cbfa29..b351fb9995 100644 --- a/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql +++ b/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql @@ -29,4 +29,84 @@ FROM ranked_children WHERE "Checklist"."checklistId" = ranked_children."checklistId"; -- AlterTable -ALTER TABLE "Organization" ADD COLUMN "newMemberImageId" TEXT; \ No newline at end of file +ALTER TABLE "Organization" ADD COLUMN "newMemberImageId" TEXT; + +-- Migrate descriptions array to INFO checklist items +-- For each checklist with non-empty descriptions, create INFO subtasks +DO $$ +DECLARE + checklist_record RECORD; + description_text TEXT; + max_order INTEGER; + current_order INTEGER; + array_index INTEGER; +BEGIN + -- Loop through all checklists that have descriptions + FOR checklist_record IN + SELECT "checklistId", "descriptions", "organizationId", "userCreatedId", "teamId", "teamTypeId", "dateCreated" + FROM "Checklist" + WHERE "descriptions" IS NOT NULL + AND array_length("descriptions", 1) > 0 + AND "dateDeleted" IS NULL + LOOP + -- Get the maximum displayOrder for existing subtasks of this checklist + SELECT COALESCE(MAX("displayOrder"), 0) INTO max_order + FROM "Checklist" + WHERE "parentChecklistId" = checklist_record."checklistId" + AND "dateDeleted" IS NULL; + + current_order := max_order; + + -- Loop through each description in the array + FOR array_index IN 1..array_length(checklist_record."descriptions", 1) + LOOP + description_text := checklist_record."descriptions"[array_index]; + current_order := current_order + 1; + + -- Create an INFO checklist item for this description + INSERT INTO "Checklist" ( + "checklistId", + "name", + "descriptions", + "isOptional", + "displayOrder", + "itemType", + "parentChecklistId", + "organizationId", + "userCreatedId", + "teamId", + "teamTypeId", + "dateCreated" + ) VALUES ( + gen_random_uuid(), + description_text, + ARRAY[]::TEXT[], + true, + current_order, + 'INFO', + checklist_record."checklistId", + checklist_record."organizationId", + checklist_record."userCreatedId", + checklist_record."teamId", + checklist_record."teamTypeId", + checklist_record."dateCreated" + ); + END LOOP; + END LOOP; +END $$; + +-- Now that descriptions have been migrated to INFO items, we can rename name to content +-- and remove descriptions + +-- Add the new content column +ALTER TABLE "Checklist" ADD COLUMN "content" TEXT; + +-- Copy name to content +UPDATE "Checklist" SET "content" = "name"; + +-- Make content NOT NULL +ALTER TABLE "Checklist" ALTER COLUMN "content" SET NOT NULL; + +-- Drop the old columns +ALTER TABLE "Checklist" DROP COLUMN "name"; +ALTER TABLE "Checklist" DROP COLUMN "descriptions"; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 2301404560..428ed6619c 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1472,8 +1472,7 @@ model Checklist { teamType Team_Type? @relation(fields: [teamTypeId], references: [teamTypeId]) teamId String? team Team? @relation(fields: [teamId], references: [teamId]) - name String - descriptions String[] + content String isOptional Boolean @default(false) displayOrder Int? itemType Checklist_Item_Type @default(TASK) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index d2fde791ce..af156a2642 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -2591,23 +2591,11 @@ const performSeed: () => Promise = async () => { ner.organizationId ); - const joinSlackChecklist = await OnboardingServices.createChecklist( - batman, - 'Join Slack', - [ - 'Slack is our primary method of communication outside of meetings and the shop. To join, you must use your @northeastern.edu email (No personal emails!). We do not send email reminders for meetings, so you will need to stay in the loop via Slack and Google Calandar.' - ], - null, - null, - null, - ner, - false - ); + const joinSlackChecklist = await OnboardingServices.createChecklist(batman, 'Join Slack', null, null, null, ner, false); await OnboardingServices.createChecklist( batman, 'Put your name and pronouns', - [], null, null, joinSlackChecklist.checklistId, @@ -2618,7 +2606,6 @@ const performSeed: () => Promise = async () => { await OnboardingServices.createChecklist( batman, 'Include your team and/or subteam', - [], null, null, joinSlackChecklist.checklistId, @@ -2629,7 +2616,6 @@ const performSeed: () => Promise = async () => { await OnboardingServices.createChecklist( batman, 'Include your major and/or year', - [], null, null, joinSlackChecklist.checklistId, @@ -2640,7 +2626,6 @@ const performSeed: () => Promise = async () => { await OnboardingServices.createChecklist( batman, 'Turn on notifications', - [], null, null, joinSlackChecklist.checklistId, @@ -2648,21 +2633,11 @@ const performSeed: () => Promise = async () => { false ); - const engageChecklist = await OnboardingServices.createChecklist( - batman, - 'Engage', - ['Join NER on engage. This is what Northeastern uses to keep track of our roster'], - null, - null, - null, - ner, - false - ); + const engageChecklist = await OnboardingServices.createChecklist(batman, 'Engage', null, null, null, ner, false); const learnGitChecklist = await OnboardingServices.createChecklist( batman, 'Learn how to use git', - ['Go online and learn how to use git'], null, software.teamTypeId, null, @@ -2673,7 +2648,6 @@ const performSeed: () => Promise = async () => { await OnboardingServices.createChecklist( batman, 'Create your first project', - [], null, software.teamTypeId, learnGitChecklist.checklistId, diff --git a/src/backend/src/routes/onboarding.routes.ts b/src/backend/src/routes/onboarding.routes.ts index 218a4e8788..af16bdc4d4 100644 --- a/src/backend/src/routes/onboarding.routes.ts +++ b/src/backend/src/routes/onboarding.routes.ts @@ -14,9 +14,7 @@ onboardingRouter.get('/checklists/usersChecklists', OnboardingController.getUser onboardingRouter.post( '/checklist/create', - nonEmptyString(body('name')), - body('descriptions').isArray(), - nonEmptyString(body('descriptions.*')), + nonEmptyString(body('content')), nonEmptyString(body('teamId').optional()), nonEmptyString(body('teamTypeId').optional()), nonEmptyString(body('parentChecklistId').optional()), @@ -28,9 +26,7 @@ onboardingRouter.post( onboardingRouter.post( '/checklist/edit/:checklistId', - nonEmptyString(body('name')), - body('descriptions').isArray(), - nonEmptyString(body('descriptions.*')), + nonEmptyString(body('content')), nonEmptyString(body('teamId').optional()), nonEmptyString(body('teamTypeId').optional()), nonEmptyString(body('parentChecklistId').optional()), diff --git a/src/backend/src/routes/organizations.routes.ts b/src/backend/src/routes/organizations.routes.ts index bb113192b6..d860479610 100644 --- a/src/backend/src/routes/organizations.routes.ts +++ b/src/backend/src/routes/organizations.routes.ts @@ -51,7 +51,11 @@ organizationRouter.post( ); organizationRouter.post('/logo/update', upload.single('logo'), OrganizationsController.setLogoImage); organizationRouter.get('/logo', OrganizationsController.getOrganizationLogoImage); -organizationRouter.post('/new-member-image/update', upload.single('newMemberImage'), OrganizationsController.setNewMemberImage); +organizationRouter.post( + '/new-member-image/update', + upload.single('newMemberImage'), + OrganizationsController.setNewMemberImage +); organizationRouter.get('/new-member-image', OrganizationsController.getOrganizationNewMemberImage); organizationRouter.post( '/description/set', diff --git a/src/backend/src/services/onboarding.services.ts b/src/backend/src/services/onboarding.services.ts index 9d8bdd5660..9263147e75 100644 --- a/src/backend/src/services/onboarding.services.ts +++ b/src/backend/src/services/onboarding.services.ts @@ -14,7 +14,11 @@ export default class OnboardingServices { static async getAllChecklists(organization: Organization) { const allChecklists = await prisma.checklist.findMany({ where: { organizationId: organization.organizationId, dateDeleted: null, parentChecklistId: null }, - include: { subtasks: { where: { dateDeleted: null }, orderBy: { displayOrder: 'asc' } }, teamType: true, usersChecked: true }, + include: { + subtasks: { where: { dateDeleted: null }, orderBy: { displayOrder: 'asc' } }, + teamType: true, + usersChecked: true + }, orderBy: { displayOrder: 'asc' } }); @@ -101,8 +105,7 @@ export default class OnboardingServices { /** * Creates a new checklist - * @param name the name of the checklist - * @param descriptions the descriptions of the checklist + * @param content the content of the checklist * @param isOptional whether the checklist is optional * @param teamId the team Id of the checklist * @param teamTypeId the teamType Id of the checklist @@ -113,8 +116,7 @@ export default class OnboardingServices { */ static async createChecklist( creator: User, - name: string, - descriptions: string[], + content: string, teamId: string | null, teamTypeId: string | null, parentChecklistId: string | null, @@ -185,14 +187,14 @@ export default class OnboardingServices { take: 1 }); - const nextDisplayOrder = existingChecklists.length > 0 && existingChecklists[0].displayOrder !== null - ? existingChecklists[0].displayOrder + 1 - : 1; + const nextDisplayOrder = + existingChecklists.length > 0 && existingChecklists[0].displayOrder !== null + ? existingChecklists[0].displayOrder + 1 + : 1; const checklist: Checklist = await prisma.checklist.create({ data: { - name, - descriptions, + content, isOptional, displayOrder: nextDisplayOrder, itemType: itemType ?? 'TASK', @@ -210,8 +212,7 @@ export default class OnboardingServices { /** * Edits a checklist * @param checklistId the id of the checklist to edit - * @param name the name of the checklist - * @param descriptions the descriptions of the checklist + * @param content the content of the checklist * @param isOptional whether the checklist is optional * @param teamId the team Id of the checklist * @param teamTypeId the teamType Id of the checklist @@ -223,8 +224,7 @@ export default class OnboardingServices { static async editChecklist( editor: User, checklistId: string, - name: string, - descriptions: string[], + content: string, teamId: string | null, teamTypeId: string | null, parentChecklistId: string | null, @@ -297,8 +297,7 @@ export default class OnboardingServices { const editedChecklist = await prisma.checklist.update({ where: { checklistId }, data: { - name, - descriptions, + content, isOptional, itemType: itemType ?? checklist.itemType, teamId, @@ -349,7 +348,10 @@ export default class OnboardingServices { static async toggleChecklist(checklistId: string, user: User, organization: Organization) { const checklist = await prisma.checklist.findUnique({ where: { checklistId, organizationId: organization.organizationId }, - include: { usersChecked: true, subtasks: { where: { dateDeleted: null }, include: { usersChecked: true }, orderBy: { displayOrder: 'asc' } } } + include: { + usersChecked: true, + subtasks: { where: { dateDeleted: null }, include: { usersChecked: true }, orderBy: { displayOrder: 'asc' } } + } }); if (!checklist) { @@ -497,8 +499,7 @@ export default class OnboardingServices { }) ) ); - }) - + }); } /** @@ -545,7 +546,6 @@ export default class OnboardingServices { }) ) ); - }) - + }); } } diff --git a/src/backend/src/services/organizations.services.ts b/src/backend/src/services/organizations.services.ts index be61dba575..3ed7e40b91 100644 --- a/src/backend/src/services/organizations.services.ts +++ b/src/backend/src/services/organizations.services.ts @@ -124,7 +124,7 @@ export default class OrganizationsService { const exploreAsGuestImageData = exploreAsGuestImage ? await uploadFile(exploreAsGuestImage) : null; const updateData = { ...(applyInterestImageData && { applyInterestImageId: applyInterestImageData.id }), - ...(exploreAsGuestImageData && { exploreAsGuestImageId: exploreAsGuestImageData.id }), + ...(exploreAsGuestImageData && { exploreAsGuestImageId: exploreAsGuestImageData.id }) }; const newImages = await prisma.organization.update({ diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index 5fcb302d02..946de05240 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -345,7 +345,7 @@ export const createTestMilestone = async (user: User, organizationId: string) => export const createTestChecklist = async ( user: User, organizationId: string, - name: string, + content: string, teamTypeId?: string, teamId?: string, parentChecklistId?: string @@ -355,7 +355,7 @@ export const createTestChecklist = async ( const checklist = await prisma.checklist.create({ data: { - name, + content, organizationId, userCreatedId: user.userId, teamTypeId, diff --git a/src/backend/tests/unmocked/onboarding.test.ts b/src/backend/tests/unmocked/onboarding.test.ts index 366880c65f..64f48c475a 100644 --- a/src/backend/tests/unmocked/onboarding.test.ts +++ b/src/backend/tests/unmocked/onboarding.test.ts @@ -100,8 +100,7 @@ describe('Onboarding tests', () => { async () => await OnboardingServices.createChecklist( await createTestUser(wonderwomanGuest, orgId), - 'name', - ['description1', 'description2'], + 'content', null, 'teamTypeId', null, @@ -116,8 +115,7 @@ describe('Onboarding tests', () => { async () => await OnboardingServices.createChecklist( await createTestUser(batmanAppAdmin, orgId), - 'name', - ['description1', 'description2'], + 'content', 'teamId', 'teamTypeId', null, @@ -135,8 +133,7 @@ describe('Onboarding tests', () => { async () => await OnboardingServices.createChecklist( batman, - 'name', - ['description1', 'description2'], + 'content', null, null, parentChecklist.checklistId, @@ -152,8 +149,7 @@ describe('Onboarding tests', () => { async () => await OnboardingServices.createChecklist( batman, - 'name', - ['description1', 'description2'], + 'content', 'invalidTeamId', null, null, @@ -169,8 +165,7 @@ describe('Onboarding tests', () => { async () => await OnboardingServices.createChecklist( batman, - 'name', - ['description1', 'description2'], + 'content', null, 'invalidTeamTypeId', null, @@ -186,8 +181,7 @@ describe('Onboarding tests', () => { async () => await OnboardingServices.createChecklist( batman, - 'name', - ['description1', 'description2'], + 'content', null, null, 'invalidChecklistId', @@ -208,8 +202,7 @@ describe('Onboarding tests', () => { async () => await OnboardingServices.createChecklist( batman, - 'name', - ['description1', 'description2'], + 'content', null, null, parentChecklist.checklistId, @@ -228,8 +221,7 @@ describe('Onboarding tests', () => { async () => await OnboardingServices.createChecklist( batman, - 'name', - ['description1', 'description2'], + 'content', null, teamType2.teamTypeId, parentChecklist.checklistId, @@ -244,15 +236,14 @@ describe('Onboarding tests', () => { const teamType1 = await createTestTeamType('teamtype1', organization.organizationId); const result = await OnboardingServices.createChecklist( batman, - 'name', - ['description1', 'description2'], + 'content', null, teamType1.teamTypeId, null, organization, true ); - expect(result.name).toEqual('name'); + expect(result.content).toEqual('content'); }); }); @@ -263,8 +254,7 @@ describe('Onboarding tests', () => { await OnboardingServices.editChecklist( await createTestUser(wonderwomanGuest, orgId), 'checklidtId', - 'name', - ['description1', 'description2'], + 'content', null, null, null, @@ -280,8 +270,7 @@ describe('Onboarding tests', () => { await OnboardingServices.editChecklist( await createTestUser(batmanAppAdmin, orgId), 'checklistId', - 'name', - ['description1', 'description2'], + 'content', 'teamId', 'teamTypeId', null, @@ -298,8 +287,7 @@ describe('Onboarding tests', () => { await OnboardingServices.editChecklist( batman, 'checklistId', - 'name', - ['description1', 'description2'], + 'content', 'invalidTeamId', null, null, @@ -316,8 +304,7 @@ describe('Onboarding tests', () => { await OnboardingServices.editChecklist( batman, 'checklistId', - 'name', - ['description1', 'description2'], + 'content', null, 'invalidTeamTypeId', null, @@ -334,8 +321,7 @@ describe('Onboarding tests', () => { await OnboardingServices.editChecklist( batman, 'checklistId', - 'name', - ['description1', 'description2'], + 'content', null, null, 'invalidChecklistId', @@ -357,8 +343,7 @@ describe('Onboarding tests', () => { await OnboardingServices.editChecklist( batman, 'checklistId', - 'name', - ['description1', 'description2'], + 'content', null, null, parentChecklist.checklistId, @@ -378,8 +363,7 @@ describe('Onboarding tests', () => { await OnboardingServices.editChecklist( batman, 'checklistId', - 'name', - ['description1', 'description2'], + 'content', null, teamType2.teamTypeId, parentChecklist.checklistId, @@ -396,17 +380,15 @@ describe('Onboarding tests', () => { const result = await OnboardingServices.editChecklist( batman, checklist.checklistId, - 'newName', - ['description1', 'description2'], + 'newContent', null, teamType1.teamTypeId, null, organization, true ); - expect(result.name).toEqual('newName'); + expect(result.content).toEqual('newContent'); expect(result.teamTypeId).toEqual(teamType1.teamTypeId); - expect(result.descriptions).toEqual(['description1', 'description2']); }); }); diff --git a/src/frontend/src/hooks/onboarding.hook.ts b/src/frontend/src/hooks/onboarding.hook.ts index 6938d7c09a..a8e626c873 100644 --- a/src/frontend/src/hooks/onboarding.hook.ts +++ b/src/frontend/src/hooks/onboarding.hook.ts @@ -22,8 +22,7 @@ export interface ToggleChecklistPayload { } export interface ChecklistCreateArgs { - name: string; - descriptions: string[]; + content: string; isOptional: boolean; parentChecklistId?: string; teamId?: string; diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx index 52e5fa877e..85a4e82fb3 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx @@ -66,17 +66,20 @@ export const AdminChecklist: React.FC<{ parentChecklists: Checklist[]; checklist const newTasks = Array.from(localTasks); const [removed] = newTasks.splice(source.index, 1); newTasks.splice(destination.index, 0, removed); - + setLocalTasks(newTasks); // Send to backend const taskIds = newTasks.map((task) => task.checklistId); - reorderTasks({ taskIds }, { - onError: (error: any) => { - toast.error(error.message || 'Failed to reorder tasks'); - setLocalTasks(parentChecklists); // Revert on error + reorderTasks( + { taskIds }, + { + onError: (error: any) => { + toast.error(error.message || 'Failed to reorder tasks'); + setLocalTasks(parentChecklists); // Revert on error + } } - }); + ); }; return ( diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx index 8c004a3203..0c6fa1aad4 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx @@ -25,9 +25,11 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) const toast = useToast(); const [showCreateTaskModal, setShowCreateTaskModal] = useState(false); const [showCreateInfoModal, setShowCreateInfoModal] = useState(false); - const [itemToDelete, setItemToDelete] = useState(null); + const [itemToDelete, setItemToDelete] = useState< + (ChecklistPreview & { descriptions?: string[]; itemType?: ChecklistItemType }) | null + >(null); const [taskToEdit, setTaskToEdit] = useState(null); - const [infoToEdit, setInfoToEdit] = useState(null); + const [infoToEdit, setInfoToEdit] = useState(null); const { mutateAsync: deleteChecklist } = useDeleteChecklist(); const { mutate: reorderItems } = useReorderChecklistItems(parentTask.checklistId); @@ -77,17 +79,20 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) const newItems = Array.from(localItems); const [removed] = newItems.splice(source.index, 1); newItems.splice(destination.index, 0, removed); - + setLocalItems(newItems); // Send to backend - all items are now real checklist items const itemIds = newItems.map((item) => item.checklistId); - reorderItems({ itemIds }, { - onError: (error: any) => { - toast.error(error.message || 'Failed to reorder items'); - setLocalItems(allItems); // Revert on error + reorderItems( + { itemIds }, + { + onError: (error: any) => { + toast.error(error.message || 'Failed to reorder items'); + setLocalItems(allItems); // Revert on error + } } - }); + ); }; return ( @@ -122,7 +127,7 @@ const AdminSubtaskSection: React.FC = ({ parentTask })
    - {item.name} {item.isOptional && '(Optional)'} + {item.content} {item.isOptional && '(Optional)'}
    @@ -143,13 +148,13 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) - + setItemToDelete(item)}> - setInfoToEdit({ ...item, descriptions: (item as any).descriptions || [item.name] })}> + setInfoToEdit(item)}> diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminTask.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminTask.tsx index 24bf1fd336..ade8a88818 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminTask.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminTask.tsx @@ -5,8 +5,6 @@ import { useState } from 'react'; import { Checklist } from 'shared'; import { GridDragIcon } from '@mui/x-data-grid'; import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; -import EditIcon from '@mui/icons-material/Edit'; -import EditChecklistModal from './EditChecklistModal'; import { useToast } from '../../../../hooks/toasts.hooks'; import { useDeleteChecklist } from '../../../../hooks/onboarding.hook'; import NERDeleteModal from '../../../../components/NERDeleteModal'; @@ -18,7 +16,6 @@ interface AdminTaskProps { const AdminTask: React.FC = ({ parentTask }) => { const [showSubtasks, setShowSubtasks] = useState(false); - const [showEdit, setShowEdit] = useState(false); const [taskToDelete, setTaskToDelete] = useState(null); const toast = useToast(); @@ -47,14 +44,11 @@ const AdminTask: React.FC = ({ parentTask }) => { - {parentTask.name} + {parentTask.content} setTaskToDelete(parentTask)}> - setShowEdit(true)}> - - {showSubtasks ? : } @@ -62,15 +56,6 @@ const AdminTask: React.FC = ({ parentTask }) => { {showSubtasks && }
    - {showEdit && ( - setShowEdit(false)} - teamId={parentTask.team?.teamId} - teamTypeId={parentTask.teamType?.teamTypeId} - defaultValues={parentTask} - /> - )} {taskToDelete && ( = yup.object().shape({ - name: yup.string().required('Name is Required') + content: yup.string().required('Task name is required') }) as any; const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateChecklistModalProps) => { @@ -59,7 +59,7 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC const [items, setItems] = useState([]); const defaultValues = { - name: '' + content: '' }; const { @@ -109,8 +109,7 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC const onFormSubmit = async (data: ChecklistFormValues) => { try { const formattedData = { - name: data.name, - descriptions: [], + content: data.content, isOptional: false, teamId, teamTypeId @@ -123,8 +122,7 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC items.map((item) => { if (item.type === 'TASK' && item.name) { return createChecklist({ - name: item.name, - descriptions: [], + content: item.name, teamId, teamTypeId, parentChecklistId: parentChecklist.checklistId, @@ -133,12 +131,11 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC }); } else if (item.type === 'INFO' && item.content) { return createChecklist({ - name: 'Info Block', - descriptions: [item.content], + content: item.content, teamId, teamTypeId, parentChecklistId: parentChecklist.checklistId, - isOptional: false, + isOptional: true, // INFO blocks are always optional itemType: 'INFO' }); } @@ -162,7 +159,7 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC onHide={handleClose} title={'Create Task'} reset={() => { - reset({ name: '' }); + reset({ content: '' }); setItems([]); }} handleUseFormSubmit={handleSubmit} @@ -185,7 +182,7 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC Task Name* ( )} /> diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx index 34eb1de4e2..21820cde41 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx @@ -43,11 +43,9 @@ const CreateInfoBlockModal: React.FC = ({ open, handl const onFormSubmit = async (data: InfoBlockFormValues) => { try { - await createChecklist({ - name: 'Info Block', // Name is required but not used for info blocks - descriptions: [data.content], - isOptional: false, + content: data.content, + isOptional: true, // INFO blocks are always optional parentChecklistId: parentChecklist.checklistId, teamId: parentChecklist.team?.teamId, teamTypeId: parentChecklist.teamType?.teamTypeId, @@ -162,4 +160,3 @@ const CreateInfoBlockModal: React.FC = ({ open, handl }; export default CreateInfoBlockModal; - diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditChecklistModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditChecklistModal.tsx deleted file mode 100644 index 4fe4ae20e5..0000000000 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditChecklistModal.tsx +++ /dev/null @@ -1,278 +0,0 @@ -import ErrorPage from '../../../ErrorPage'; -import LoadingIndicator from '../../../../components/LoadingIndicator'; -import { ChecklistCreateArgs, useEditChecklist } from '../../../../hooks/onboarding.hook'; -import { useToast } from '../../../../hooks/toasts.hooks'; -import { Checklist } from 'shared'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { FormControl, FormLabel, TextField, InputAdornment, IconButton, useTheme, Stack, Typography } from '@mui/material'; -import { Box } from '@mui/system'; -import { useForm, useFieldArray, Controller } from 'react-hook-form'; -import NERFormModal from '../../../../components/NERFormModal'; -import * as yup from 'yup'; -import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; -import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; -import NERMarkdown from '../../../../components/NERMarkdown'; - -interface EditChecklistModalProps { - open: boolean; - handleClose: () => void; - teamId?: string; - teamTypeId?: string; - defaultValues: Checklist; -} - -interface ChecklistFormValues { - name: string; - descriptions: { name: string }[]; -} - -const schema = yup.object().shape({ - name: yup.string().required('Name is Required'), - descriptions: yup - .array() - .of( - yup.object().shape({ - name: yup.string().required('Description is Required').trim() - }) - ) - .min(1, 'At least one description is required') - .required() -}); - -const EditChecklistModal = ({ open, handleClose, defaultValues, teamId, teamTypeId }: EditChecklistModalProps) => { - const theme = useTheme(); - const toast = useToast(); - const { mutateAsync: editChecklist, isLoading, isError, error } = useEditChecklist(defaultValues.checklistId); - - const { - handleSubmit, - control, - watch, - reset, - formState: { errors } - } = useForm({ - resolver: yupResolver(schema), - defaultValues: { - name: defaultValues?.name ?? '', - descriptions: defaultValues?.descriptions?.length - ? defaultValues?.descriptions?.map((desc) => ({ name: desc })) - : [{ name: '' }] - } - }); - - const onFormSubmit = async (data: ChecklistCreateArgs) => { - try { - const formattedData = { - ...data, - teamId, - teamTypeId, - descriptions: (data.descriptions as unknown as { name: string }[]).map((desc) => desc.name) - }; - - await editChecklist(formattedData); - - handleClose(); - } catch (error) { - toast.error('Failed to create checklist'); - console.error('Error in onFormSubmit:', error); - } - }; - - const { fields, append, remove } = useFieldArray({ - control, - name: 'descriptions' - }); - - if (isError) return ; - if (isLoading) return ; - - return ( - reset({ name: '', descriptions: [] })} - handleUseFormSubmit={handleSubmit} - onFormSubmit={onFormSubmit} - formId={!!defaultValues ? 'edit-UsefulLink-form' : 'create-UsefulLink-form'} - showCloseButton - paperProps={{ maxWidth: '80vw' }} - > - - - - Task Name* - - ( - - )} - /> - - - - - Descriptions* - - {fields.map((item, index) => ( - - - ( - - {index !== 0 && ( - remove(index)}> - - - )} - - ), - disableUnderline: true, - sx: { - '& fieldset': { border: 'none' }, - fontSize: '1.1rem', - lineHeight: 1.6, - padding: 2 - } - }} - sx={{ - backgroundColor: theme.palette.background.paper, - borderRadius: 3, - width: '100%', - '& .MuiInputBase-root': { - alignItems: 'flex-start' - } - }} - error={!!errors.descriptions?.[index]?.name} - helperText={errors.descriptions?.[index]?.name?.message} - /> - )} - /> - - - - Preview: - - - {watch(`descriptions.${index}.name`) ? ( - - ) : ( - - Start typing to see formatted markdown... - - )} - - - - ))} - append({ name: '' })} - sx={{ - backgroundColor: theme.palette.background.paper, - borderRadius: 5, - mt: 1, - fontSize: '1rem', - padding: 1.5, - width: '100%', - justifyContent: 'flex-start' - }} - > - - Add Additional Information - - - - - - ); -}; - -export default EditChecklistModal; diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx index 5498f14d24..6f9da97c87 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx @@ -13,7 +13,7 @@ interface EditInfoBlockModalProps { open: boolean; handleClose: () => void; parentChecklist: Checklist; - defaultValues: ChecklistPreview & { descriptions?: string[] }; + defaultValues: ChecklistPreview; } interface InfoBlockFormValues { @@ -37,7 +37,7 @@ const EditInfoBlockModal: React.FC = ({ open, handleClo formState: { errors } } = useForm({ resolver: yupResolver(schema), - defaultValues: { content: defaultValues.descriptions?.[0] || '' } + defaultValues: { content: defaultValues.content || '' } }); const contentValue = watch('content'); @@ -45,9 +45,8 @@ const EditInfoBlockModal: React.FC = ({ open, handleClo const onFormSubmit = async (data: InfoBlockFormValues) => { try { await editChecklist({ - name: 'Info Block', // Name is required but not used for info blocks - descriptions: [data.content], - isOptional: false, + content: data.content, + isOptional: true, // INFO blocks are always optional parentChecklistId: parentChecklist.checklistId, teamId: parentChecklist.team?.teamId, teamTypeId: parentChecklist.teamType?.teamTypeId, @@ -65,7 +64,7 @@ const EditInfoBlockModal: React.FC = ({ open, handleClo open={open} onHide={handleClose} title="Edit Information Block" - reset={() => reset({ content: defaultValues.descriptions?.[0] || '' })} + reset={() => reset({ content: defaultValues.content || '' })} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} formId="edit-info-block-form" @@ -158,4 +157,3 @@ const EditInfoBlockModal: React.FC = ({ open, handleClo }; export default EditInfoBlockModal; - diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx index dab87421e0..aab0896324 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx @@ -32,16 +32,16 @@ const SubtaskFormModal = ({ open, handleClose, onSubmit, parentChecklist, defaul } = useForm({ resolver: yupResolver(schema), defaultValues: { - name: defaultValues?.name ?? '', + name: defaultValues?.content ?? '', isOptional: defaultValues?.isOptional ?? false } }); - const onFormSubmit = async (data: ChecklistCreateArgs) => { + const onFormSubmit = async (data: SubtaskCreateArgs) => { try { const formattedData = { - ...data, - descriptions: [], + content: data.name, + isOptional: data.isOptional, parentChecklistId: parentChecklist.checklistId, teamId: parentChecklist.team?.teamId, teamTypeId: parentChecklist.teamType?.teamTypeId, diff --git a/src/frontend/src/pages/HomePage/components/ChecklistSection.tsx b/src/frontend/src/pages/HomePage/components/ChecklistSection.tsx index 89b7414700..87735abfe1 100644 --- a/src/frontend/src/pages/HomePage/components/ChecklistSection.tsx +++ b/src/frontend/src/pages/HomePage/components/ChecklistSection.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Box, Grid, Link, Typography, useTheme } from '@mui/material'; +import { Box, Grid, Typography, useTheme } from '@mui/material'; import { groupChecklists } from '../../../utils/onboarding.utils'; import Checklist from './Checklist'; import { Checklist as ChecklistType } from 'shared'; diff --git a/src/frontend/src/pages/HomePage/components/ParentTask.tsx b/src/frontend/src/pages/HomePage/components/ParentTask.tsx index 71076b6bfb..c7ee45d706 100644 --- a/src/frontend/src/pages/HomePage/components/ParentTask.tsx +++ b/src/frontend/src/pages/HomePage/components/ParentTask.tsx @@ -3,8 +3,6 @@ import { useState } from 'react'; import { KeyboardArrowRight, KeyboardArrowDown } from '@mui/icons-material'; import SubtaskSection from './SubtaskSection'; import { Checklist } from 'shared'; -import { useToggleChecklist } from '../../../hooks/onboarding.hook'; -import { useToast } from '../../../hooks/toasts.hooks'; import { isChecklistChecked } from '../../../utils/onboarding.utils'; interface ParentTaskProps { @@ -52,7 +50,7 @@ const ParentTask: React.FC = ({ parentTask, checkedChecklists } }} /> - {parentTask.name} + {parentTask.content} {showSubtasks ? : } diff --git a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx index 97fd911e8f..ef29bbd476 100644 --- a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx +++ b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx @@ -22,32 +22,24 @@ const SubtaskSection: React.FC = ({ parentTask, checkedChec const { mutate: toggleChecklist } = useToggleChecklist(); const handleToggleChecklist = (subtaskId: string) => { - toggleChecklist({ checklistId: subtaskId }, { - onError: (error: any) => { - toast.error(error.message); + toggleChecklist( + { checklistId: subtaskId }, + { + onError: (error: any) => { + toast.error(error.message); + } } - }); + ); }; // All items (tasks and info blocks) are now stored in subtasks with itemType field - // Keep descriptions for backward compatibility with old data - const allItems = [ - ...subtasks.map((subtask) => ({ + const allItems = subtasks + .map((subtask) => ({ ...subtask, itemType: subtask.itemType ?? 'TASK', displayOrder: subtask.displayOrder ?? 999 - })), - // Backward compatibility: show old descriptions only if they exist and aren't already in subtasks as info blocks - ...(parentTask.descriptions && parentTask.descriptions.length > 0 - ? parentTask.descriptions.map((description, index) => ({ - checklistId: `info-${index}`, - name: description, - itemType: 'INFO' as const, - displayOrder: 1000 + index, - isOptional: false - })) - : []) - ].sort((a, b) => a.displayOrder - b.displayOrder); + })) + .sort((a, b) => a.displayOrder - b.displayOrder); return ( = ({ parentTask, checkedChec > {allItems.map((item) => { - if (item.itemType === 'TASK') { + if (item.itemType === ChecklistItemType.TASK) { return ( {isAdmin ? ( @@ -93,27 +85,25 @@ const SubtaskSection: React.FC = ({ parentTask, checkedChec )} - {item.name} {item.isOptional && '(Optional)'} + {item.content} {item.isOptional && '(Optional)'} ); - } else { - // INFO block - content is in descriptions[0] for new items, or name for backward compatibility - const content = (item as any).descriptions?.[0] || item.name; - return ( - - - - ); } + // INFO block + return ( + + + + ); })} diff --git a/src/frontend/src/pages/HomePage/components/Task.tsx b/src/frontend/src/pages/HomePage/components/Task.tsx index 3c330b0e84..ba53ec24c1 100644 --- a/src/frontend/src/pages/HomePage/components/Task.tsx +++ b/src/frontend/src/pages/HomePage/components/Task.tsx @@ -71,7 +71,7 @@ const Task: React.FC = ({ parentTask }) => { }} /> - {parentTask.name} + {parentTask.content} {showSubtasks ? : } diff --git a/src/shared/src/types/checklist-types.ts b/src/shared/src/types/checklist-types.ts index f6a3be6273..34543f8100 100644 --- a/src/shared/src/types/checklist-types.ts +++ b/src/shared/src/types/checklist-types.ts @@ -14,10 +14,9 @@ export enum ChecklistItemType { export interface Checklist { checklistId: string; - name: string; + content: string; teamType?: TeamType; team?: Team; - descriptions: string[]; isOptional: boolean; displayOrder?: number; itemType: ChecklistItemType; @@ -30,6 +29,9 @@ export interface Checklist { dateDeleted?: Date; } -export type ChecklistPreview = Pick; +export type ChecklistPreview = Pick< + Checklist, + 'checklistId' | 'content' | 'team' | 'teamType' | 'dateCreated' | 'isOptional' | 'displayOrder' | 'itemType' +>; export type CreateChecklistPreview = Omit; diff --git a/src/shared/src/types/user-types.ts b/src/shared/src/types/user-types.ts index 3ddbfa08af..c129e578d1 100644 --- a/src/shared/src/types/user-types.ts +++ b/src/shared/src/types/user-types.ts @@ -42,7 +42,15 @@ export type ThemeName = 'DARK' | 'LIGHT'; export type OrganizationPreview = Pick< Organization, - 'organizationId' | 'name' | 'dateCreated' | 'dateDeleted' | 'description' | 'applicationLink' | 'applyInterestImageId' | 'exploreAsGuestImageId' | 'newMemberImageId' + | 'organizationId' + | 'name' + | 'dateCreated' + | 'dateDeleted' + | 'description' + | 'applicationLink' + | 'applyInterestImageId' + | 'exploreAsGuestImageId' + | 'newMemberImageId' >; export interface Organization { From 79e155ec653ff8e4f1ee07a36037333df5d837ae Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Wed, 7 Jan 2026 14:10:51 -0500 Subject: [PATCH 456/477] #3767 minor fixes --- src/backend/tests/unmocked/onboarding.test.ts | 30 ++----------------- src/frontend/src/components/NERMarkdown.tsx | 2 +- .../Checklists/AdminChecklist.tsx | 6 ++-- .../Checklists/AdminSubtaskSection.tsx | 6 ++-- .../Checklists/CreateChecklistModal.tsx | 22 +++++++------- .../OnboardingInfoSection.tsx | 2 +- .../HomePage/components/SubtaskSection.tsx | 4 +-- 7 files changed, 24 insertions(+), 48 deletions(-) diff --git a/src/backend/tests/unmocked/onboarding.test.ts b/src/backend/tests/unmocked/onboarding.test.ts index 64f48c475a..245dab3414 100644 --- a/src/backend/tests/unmocked/onboarding.test.ts +++ b/src/backend/tests/unmocked/onboarding.test.ts @@ -147,15 +147,7 @@ describe('Onboarding tests', () => { const batman = await createTestUser(batmanAppAdmin, orgId); await expect( async () => - await OnboardingServices.createChecklist( - batman, - 'content', - 'invalidTeamId', - null, - null, - organization, - true - ) + await OnboardingServices.createChecklist(batman, 'content', 'invalidTeamId', null, null, organization, true) ).rejects.toThrow(new NotFoundException('Team', 'invalidTeamId')); }); @@ -163,15 +155,7 @@ describe('Onboarding tests', () => { const batman = await createTestUser(batmanAppAdmin, orgId); await expect( async () => - await OnboardingServices.createChecklist( - batman, - 'content', - null, - 'invalidTeamTypeId', - null, - organization, - true - ) + await OnboardingServices.createChecklist(batman, 'content', null, 'invalidTeamTypeId', null, organization, true) ).rejects.toThrow(new NotFoundException('Team Type', 'invalidTeamTypeId')); }); @@ -179,15 +163,7 @@ describe('Onboarding tests', () => { const batman = await createTestUser(batmanAppAdmin, orgId); await expect( async () => - await OnboardingServices.createChecklist( - batman, - 'content', - null, - null, - 'invalidChecklistId', - organization, - true - ) + await OnboardingServices.createChecklist(batman, 'content', null, null, 'invalidChecklistId', organization, true) ).rejects.toThrow(new NotFoundException('Checklist', 'invalidChecklistId')); }); diff --git a/src/frontend/src/components/NERMarkdown.tsx b/src/frontend/src/components/NERMarkdown.tsx index 57b5704225..de6acae944 100644 --- a/src/frontend/src/components/NERMarkdown.tsx +++ b/src/frontend/src/components/NERMarkdown.tsx @@ -9,7 +9,7 @@ interface NERMarkdownProps { const NERMarkdown = ({ markdown }: NERMarkdownProps) => { // make all links open in new tabs const components: Components = { - a: ({ node, ...props }) => + a: ({ node, children, ...props }) => {children} }; return ( diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx index 85a4e82fb3..5231aa7119 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminChecklist.tsx @@ -1,7 +1,7 @@ import { KeyboardArrowDown, KeyboardArrowRight } from '@mui/icons-material'; import { Grid, Typography, IconButton } from '@mui/material'; import { Box } from '@mui/system'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { Checklist, TeamType } from 'shared'; import AdminTask from './AdminTask'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; @@ -31,9 +31,9 @@ export const AdminChecklist: React.FC<{ parentChecklists: Checklist[]; checklist const { mutate: reorderTasks } = useReorderTasks(); // Update local tasks when parentChecklists changes - useState(() => { + useEffect(() => { setLocalTasks(parentChecklists); - }); + }, [parentChecklists]); const handleDelete = async () => { if (!tasksToDelete) return; diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx index 0c6fa1aad4..4fffca0b38 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx @@ -1,6 +1,6 @@ import { Typography, useTheme, IconButton } from '@mui/material'; import { Box } from '@mui/system'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { Checklist, ChecklistPreview, ChecklistItemType } from 'shared'; import { GridDragIcon } from '@mui/x-data-grid'; import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; @@ -60,9 +60,9 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) const [localItems, setLocalItems] = useState(allItems); // Update local items when allItems changes - useState(() => { + useEffect(() => { setLocalItems(allItems); - }); + }, [allItems]); const onDragEnd: OnDragEndResponder = (result) => { const { destination, source } = result; diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx index 6b195feb14..4a57e79671 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx @@ -25,6 +25,7 @@ import { DragDropContext, Droppable, Draggable, OnDragEndResponder } from '@hell import { GridDragIcon } from '@mui/x-data-grid'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; import InfoIcon from '@mui/icons-material/Info'; +import { ChecklistItemType } from 'shared'; interface CreateChecklistModalProps { open: boolean; @@ -38,9 +39,8 @@ type ItemType = 'TASK' | 'INFO'; interface ChecklistItem { id: string; type: ItemType; - name?: string; // For tasks + content: string; isOptional?: boolean; // For tasks - content?: string; // For info blocks } interface ChecklistFormValues { @@ -49,7 +49,7 @@ interface ChecklistFormValues { const schema: yup.ObjectSchema = yup.object().shape({ content: yup.string().required('Task name is required') -}) as any; +}); const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateChecklistModalProps) => { const theme = useTheme(); @@ -73,7 +73,7 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC }); const addTask = () => { - setItems([...items, { id: `task-${Date.now()}`, type: 'TASK', name: '', isOptional: false }]); + setItems([...items, { id: `task-${Date.now()}`, type: 'TASK', content: '', isOptional: false }]); }; const addInfoBlock = () => { @@ -120,23 +120,23 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC // Create all items in order with their displayOrder set await Promise.all( items.map((item) => { - if (item.type === 'TASK' && item.name) { + if (item.type === ChecklistItemType.TASK) { return createChecklist({ - content: item.name, + content: item.content, teamId, teamTypeId, parentChecklistId: parentChecklist.checklistId, isOptional: item.isOptional || false, - itemType: 'TASK' + itemType: ChecklistItemType.TASK }); - } else if (item.type === 'INFO' && item.content) { + } else if (item.type === ChecklistItemType.INFO) { return createChecklist({ content: item.content, teamId, teamTypeId, parentChecklistId: parentChecklist.checklistId, isOptional: true, // INFO blocks are always optional - itemType: 'INFO' + itemType: ChecklistItemType.INFO }); } return Promise.resolve(); @@ -243,8 +243,8 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC updateItem(index, { name: e.target.value })} + value={item.content || ''} + onChange={(e) => updateItem(index, { content: e.target.value })} placeholder="Subtask Name" fullWidth InputProps={{ diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/OnboardingInfoSection.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/OnboardingInfoSection.tsx index d9ddb0457c..6a641a6579 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/OnboardingInfoSection.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/OnboardingInfoSection.tsx @@ -107,7 +107,7 @@ const OnboardingInfoSection: React.FC = () => { component="img" sx={{ display: 'block', maxWidth: '100%', maxHeight: '200px', mb: 1, objectFit: 'contain' }} alt="New Member Event" - src={newMemberImageBlob ? URL.createObjectURL(newMemberImageBlob) : undefined} + src={URL.createObjectURL(newMemberImageBlob)} /> )} = ({ parentTask, checkedChec ); }; - // All items (tasks and info blocks) are now stored in subtasks with itemType field + // All items (tasks and info blocks) now stored in subtasks with itemType field const allItems = subtasks .map((subtask) => ({ ...subtask, - itemType: subtask.itemType ?? 'TASK', + itemType: subtask.itemType ?? ChecklistItemType.TASK, displayOrder: subtask.displayOrder ?? 999 })) .sort((a, b) => a.displayOrder - b.displayOrder); From faef6040044cf97da63515e58ea49ac2534d29bd Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Wed, 7 Jan 2026 14:47:18 -0500 Subject: [PATCH 457/477] #3767 more consistent enum usage --- src/backend/src/prisma/seed.ts | 2 - src/frontend/src/components/NERMarkdown.tsx | 6 ++- .../Checklists/AdminSubtaskSection.tsx | 4 +- .../Checklists/CreateChecklistModal.tsx | 10 ++--- .../Checklists/CreateInfoBlockModal.tsx | 4 +- .../Checklists/EditInfoBlockModal.tsx | 4 +- .../pages/HomePage/components/ParentTask.tsx | 44 ++++++++++--------- .../HomePage/components/SubtaskSection.tsx | 2 +- 8 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index af156a2642..73fb3f7315 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -2633,8 +2633,6 @@ const performSeed: () => Promise = async () => { false ); - const engageChecklist = await OnboardingServices.createChecklist(batman, 'Engage', null, null, null, ner, false); - const learnGitChecklist = await OnboardingServices.createChecklist( batman, 'Learn how to use git', diff --git a/src/frontend/src/components/NERMarkdown.tsx b/src/frontend/src/components/NERMarkdown.tsx index de6acae944..32201ee566 100644 --- a/src/frontend/src/components/NERMarkdown.tsx +++ b/src/frontend/src/components/NERMarkdown.tsx @@ -9,7 +9,11 @@ interface NERMarkdownProps { const NERMarkdown = ({ markdown }: NERMarkdownProps) => { // make all links open in new tabs const components: Components = { - a: ({ node, children, ...props }) => {children} + a: ({ children, ...props }) => ( + + {children} + + ) }; return ( diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx index 4fffca0b38..9021faacac 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx @@ -52,7 +52,7 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) const allItems = subtasks .map((subtask) => ({ ...subtask, - itemType: subtask.itemType ?? ('TASK' as ChecklistItemType), + itemType: subtask.itemType, displayOrder: subtask.displayOrder ?? 999 })) .sort((a, b) => a.displayOrder - b.displayOrder); @@ -202,7 +202,7 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) open={!!itemToDelete} onHide={() => setItemToDelete(null)} formId="delete-item-form" - dataType={itemToDelete.itemType === 'INFO' ? 'Information Block' : 'Task'} + dataType={itemToDelete.itemType === ChecklistItemType.INFO ? 'Information Block' : 'Task'} onFormSubmit={() => handleDelete(itemToDelete.checklistId)} /> )} diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx index 4a57e79671..982c4d8fc4 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx @@ -34,11 +34,9 @@ interface CreateChecklistModalProps { teamTypeId?: string; } -type ItemType = 'TASK' | 'INFO'; - interface ChecklistItem { id: string; - type: ItemType; + type: ChecklistItemType; content: string; isOptional?: boolean; // For tasks } @@ -73,11 +71,11 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC }); const addTask = () => { - setItems([...items, { id: `task-${Date.now()}`, type: 'TASK', content: '', isOptional: false }]); + setItems([...items, { id: `task-${Date.now()}`, type: ChecklistItemType.TASK, content: '', isOptional: false }]); }; const addInfoBlock = () => { - setItems([...items, { id: `info-${Date.now()}`, type: 'INFO', content: '' }]); + setItems([...items, { id: `info-${Date.now()}`, type: ChecklistItemType.INFO, content: '' }]); }; const updateItem = (index: number, updates: Partial) => { @@ -139,7 +137,7 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC itemType: ChecklistItemType.INFO }); } - return Promise.resolve(); + throw new Error(`Unexpected checklist item type: ${String(item.type)}`); }) ); diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx index 21820cde41..e46e6c1652 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx @@ -6,7 +6,7 @@ import * as yup from 'yup'; import NERFormModal from '../../../../components/NERFormModal'; import { useCreateChecklist } from '../../../../hooks/onboarding.hook'; import { useToast } from '../../../../hooks/toasts.hooks'; -import { Checklist } from 'shared'; +import { Checklist, ChecklistItemType } from 'shared'; import NERMarkdown from '../../../../components/NERMarkdown'; interface CreateInfoBlockModalProps { @@ -49,7 +49,7 @@ const CreateInfoBlockModal: React.FC = ({ open, handl parentChecklistId: parentChecklist.checklistId, teamId: parentChecklist.team?.teamId, teamTypeId: parentChecklist.teamType?.teamTypeId, - itemType: 'INFO' + itemType: ChecklistItemType.INFO }); toast.success('Information block created successfully'); handleClose(); diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx index 6f9da97c87..84ca94f8cd 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx @@ -6,7 +6,7 @@ import * as yup from 'yup'; import NERFormModal from '../../../../components/NERFormModal'; import { useEditChecklist } from '../../../../hooks/onboarding.hook'; import { useToast } from '../../../../hooks/toasts.hooks'; -import { Checklist, ChecklistPreview } from 'shared'; +import { Checklist, ChecklistItemType, ChecklistPreview } from 'shared'; import NERMarkdown from '../../../../components/NERMarkdown'; interface EditInfoBlockModalProps { @@ -50,7 +50,7 @@ const EditInfoBlockModal: React.FC = ({ open, handleClo parentChecklistId: parentChecklist.checklistId, teamId: parentChecklist.team?.teamId, teamTypeId: parentChecklist.teamType?.teamTypeId, - itemType: 'INFO' + itemType: ChecklistItemType.INFO }); toast.success('Information block updated successfully'); handleClose(); diff --git a/src/frontend/src/pages/HomePage/components/ParentTask.tsx b/src/frontend/src/pages/HomePage/components/ParentTask.tsx index c7ee45d706..26ba2ee46c 100644 --- a/src/frontend/src/pages/HomePage/components/ParentTask.tsx +++ b/src/frontend/src/pages/HomePage/components/ParentTask.tsx @@ -1,4 +1,4 @@ -import { Typography, Box, IconButton, Checkbox } from '@mui/material'; +import { Typography, Box, IconButton, Checkbox, Tooltip } from '@mui/material'; import { useState } from 'react'; import { KeyboardArrowRight, KeyboardArrowDown } from '@mui/icons-material'; import SubtaskSection from './SubtaskSection'; @@ -30,26 +30,28 @@ const ParentTask: React.FC = ({ parentTask, checkedChecklists } }} > - - - + + + + + {parentTask.content} {showSubtasks ? : } diff --git a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx index 6d21b5b733..fd75d8ea7c 100644 --- a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx +++ b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx @@ -36,7 +36,7 @@ const SubtaskSection: React.FC = ({ parentTask, checkedChec const allItems = subtasks .map((subtask) => ({ ...subtask, - itemType: subtask.itemType ?? ChecklistItemType.TASK, + itemType: subtask.itemType, displayOrder: subtask.displayOrder ?? 999 })) .sort((a, b) => a.displayOrder - b.displayOrder); From 290e74407e484be8e234a8522f167a3e6df0275f Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Wed, 7 Jan 2026 14:55:44 -0500 Subject: [PATCH 458/477] #3767 toooltip to tell users they have to complete subtasks --- src/frontend/src/pages/HomePage/components/ParentTask.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/pages/HomePage/components/ParentTask.tsx b/src/frontend/src/pages/HomePage/components/ParentTask.tsx index 26ba2ee46c..0d392d9933 100644 --- a/src/frontend/src/pages/HomePage/components/ParentTask.tsx +++ b/src/frontend/src/pages/HomePage/components/ParentTask.tsx @@ -31,11 +31,12 @@ const ParentTask: React.FC = ({ parentTask, checkedChecklists } > - + Date: Thu, 8 Jan 2026 09:21:25 -0500 Subject: [PATCH 459/477] #3767 displayOrder -> displayIndex --- .../migration.sql | 18 ++++----- src/backend/src/prisma/schema.prisma | 2 +- .../src/services/onboarding.services.ts | 40 +++++++++---------- .../Checklists/AdminSubtaskSection.tsx | 4 +- .../Checklists/CreateChecklistModal.tsx | 2 +- .../HomePage/components/SubtaskSection.tsx | 4 +- src/shared/src/types/checklist-types.ts | 4 +- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql b/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql index b351fb9995..9d9ea84e06 100644 --- a/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql +++ b/src/backend/src/prisma/migrations/20260106000000_add_checklist_ordering_and_type/migration.sql @@ -2,18 +2,18 @@ CREATE TYPE "Checklist_Item_Type" AS ENUM ('TASK', 'INFO'); -- AlterTable -ALTER TABLE "Checklist" ADD COLUMN "displayOrder" INTEGER, +ALTER TABLE "Checklist" ADD COLUMN "displayIndex" INTEGER, ADD COLUMN "itemType" "Checklist_Item_Type" NOT NULL DEFAULT 'TASK'; --- Backfill displayOrder based on dateCreated for existing records +-- Backfill displayIndex based on dateCreated for existing records -- For top-level checklists (parentChecklistId IS NULL) WITH ranked_parent AS ( SELECT "checklistId", ROW_NUMBER() OVER (ORDER BY "dateCreated", "checklistId") as rn FROM "Checklist" - WHERE "parentChecklistId" IS NULL AND "displayOrder" IS NULL + WHERE "parentChecklistId" IS NULL AND "displayIndex" IS NULL ) UPDATE "Checklist" -SET "displayOrder" = ranked_parent.rn +SET "displayIndex" = ranked_parent.rn FROM ranked_parent WHERE "Checklist"."checklistId" = ranked_parent."checklistId"; @@ -21,10 +21,10 @@ WHERE "Checklist"."checklistId" = ranked_parent."checklistId"; WITH ranked_children AS ( SELECT "checklistId", ROW_NUMBER() OVER (PARTITION BY "parentChecklistId" ORDER BY "dateCreated", "checklistId") as rn FROM "Checklist" - WHERE "parentChecklistId" IS NOT NULL AND "displayOrder" IS NULL + WHERE "parentChecklistId" IS NOT NULL AND "displayIndex" IS NULL ) UPDATE "Checklist" -SET "displayOrder" = ranked_children.rn +SET "displayIndex" = ranked_children.rn FROM ranked_children WHERE "Checklist"."checklistId" = ranked_children."checklistId"; @@ -49,8 +49,8 @@ BEGIN AND array_length("descriptions", 1) > 0 AND "dateDeleted" IS NULL LOOP - -- Get the maximum displayOrder for existing subtasks of this checklist - SELECT COALESCE(MAX("displayOrder"), 0) INTO max_order + -- Get the maximum displayIndex for existing subtasks of this checklist + SELECT COALESCE(MAX("displayIndex"), 0) INTO max_order FROM "Checklist" WHERE "parentChecklistId" = checklist_record."checklistId" AND "dateDeleted" IS NULL; @@ -69,7 +69,7 @@ BEGIN "name", "descriptions", "isOptional", - "displayOrder", + "displayIndex", "itemType", "parentChecklistId", "organizationId", diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 428ed6619c..8ec89c89e5 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1474,7 +1474,7 @@ model Checklist { team Team? @relation(fields: [teamId], references: [teamId]) content String isOptional Boolean @default(false) - displayOrder Int? + displayIndex Int? itemType Checklist_Item_Type @default(TASK) subtasks Checklist[] @relation("subtasks") parentChecklist Checklist? @relation("subtasks", fields: [parentChecklistId], references: [checklistId]) diff --git a/src/backend/src/services/onboarding.services.ts b/src/backend/src/services/onboarding.services.ts index 9263147e75..006cf01656 100644 --- a/src/backend/src/services/onboarding.services.ts +++ b/src/backend/src/services/onboarding.services.ts @@ -15,11 +15,11 @@ export default class OnboardingServices { const allChecklists = await prisma.checklist.findMany({ where: { organizationId: organization.organizationId, dateDeleted: null, parentChecklistId: null }, include: { - subtasks: { where: { dateDeleted: null }, orderBy: { displayOrder: 'asc' } }, + subtasks: { where: { dateDeleted: null }, orderBy: { displayIndex: 'asc' } }, teamType: true, usersChecked: true }, - orderBy: { displayOrder: 'asc' } + orderBy: { displayIndex: 'asc' } }); return allChecklists; @@ -34,8 +34,8 @@ export default class OnboardingServices { static async getCheckedChecklists(user: User, organization: Organization) { const allChecklists = await prisma.checklist.findMany({ where: { organizationId: organization.organizationId, dateDeleted: null }, - include: { subtasks: { where: { dateDeleted: null }, orderBy: { displayOrder: 'asc' } }, usersChecked: true }, - orderBy: { displayOrder: 'asc' } + include: { subtasks: { where: { dateDeleted: null }, orderBy: { displayIndex: 'asc' } }, usersChecked: true }, + orderBy: { displayIndex: 'asc' } }); const checkedChecklists = allChecklists.filter((checklist) => @@ -72,11 +72,11 @@ export default class OnboardingServices { include: { usersChecked: true }, - orderBy: { displayOrder: 'asc' } + orderBy: { displayIndex: 'asc' } }, teamType: true }, - orderBy: { displayOrder: 'asc' } + orderBy: { displayIndex: 'asc' } }); const generalChecklists = await prisma.checklist.findMany({ @@ -93,11 +93,11 @@ export default class OnboardingServices { include: { usersChecked: true }, - orderBy: { displayOrder: 'asc' } + orderBy: { displayIndex: 'asc' } }, teamType: true }, - orderBy: { displayOrder: 'asc' } + orderBy: { displayIndex: 'asc' } }); return [...generalChecklists, ...teamTypeChecklists]; @@ -176,27 +176,27 @@ export default class OnboardingServices { } } - // Calculate next displayOrder + // Calculate next displayIndex const existingChecklists = await prisma.checklist.findMany({ where: { organizationId: organization.organizationId, parentChecklistId: parentChecklistId ?? null, dateDeleted: null }, - orderBy: { displayOrder: 'desc' }, + orderBy: { displayIndex: 'desc' }, take: 1 }); - const nextDisplayOrder = - existingChecklists.length > 0 && existingChecklists[0].displayOrder !== null - ? existingChecklists[0].displayOrder + 1 + const nextDisplayIndex = + existingChecklists.length > 0 && existingChecklists[0].displayIndex !== null + ? existingChecklists[0].displayIndex + 1 : 1; const checklist: Checklist = await prisma.checklist.create({ data: { content, isOptional, - displayOrder: nextDisplayOrder, + displayIndex: nextDisplayIndex, itemType: itemType ?? 'TASK', organizationId: organization.organizationId, teamId, @@ -350,7 +350,7 @@ export default class OnboardingServices { where: { checklistId, organizationId: organization.organizationId }, include: { usersChecked: true, - subtasks: { where: { dateDeleted: null }, include: { usersChecked: true }, orderBy: { displayOrder: 'asc' } } + subtasks: { where: { dateDeleted: null }, include: { usersChecked: true }, orderBy: { displayIndex: 'asc' } } } }); @@ -419,7 +419,7 @@ export default class OnboardingServices { subtasks: { where: { dateDeleted: null }, include: { usersChecked: true }, - orderBy: { displayOrder: 'asc' } + orderBy: { displayIndex: 'asc' } } } }); @@ -490,12 +490,12 @@ export default class OnboardingServices { } await prisma.$transaction(async (tx) => { - // Update displayOrder for each task + // Update displayIndex for each task await Promise.all( taskIds.map((taskId, index) => tx.checklist.update({ where: { checklistId: taskId }, - data: { displayOrder: index + 1 } + data: { displayIndex: index + 1 } }) ) ); @@ -537,12 +537,12 @@ export default class OnboardingServices { } await prisma.$transaction(async (tx) => { - // Update displayOrder for each item + // Update displayIndex for each item await Promise.all( itemIds.map((itemId, index) => tx.checklist.update({ where: { checklistId: itemId }, - data: { displayOrder: index + 1 } + data: { displayIndex: index + 1 } }) ) ); diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx index 9021faacac..67d4f787a8 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx @@ -53,9 +53,9 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) .map((subtask) => ({ ...subtask, itemType: subtask.itemType, - displayOrder: subtask.displayOrder ?? 999 + displayIndex: subtask.displayIndex ?? 999 })) - .sort((a, b) => a.displayOrder - b.displayOrder); + .sort((a, b) => a.displayIndex - b.displayIndex); const [localItems, setLocalItems] = useState(allItems); diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx index 982c4d8fc4..004b153ccd 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx @@ -115,7 +115,7 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC const parentChecklist = await createChecklist(formattedData); - // Create all items in order with their displayOrder set + // Create all items in order with their displayIndex set await Promise.all( items.map((item) => { if (item.type === ChecklistItemType.TASK) { diff --git a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx index fd75d8ea7c..86a95279f2 100644 --- a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx +++ b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx @@ -37,9 +37,9 @@ const SubtaskSection: React.FC = ({ parentTask, checkedChec .map((subtask) => ({ ...subtask, itemType: subtask.itemType, - displayOrder: subtask.displayOrder ?? 999 + displayIndex: subtask.displayIndex ?? 999 })) - .sort((a, b) => a.displayOrder - b.displayOrder); + .sort((a, b) => a.displayIndex - b.displayIndex); return ( ; export type CreateChecklistPreview = Omit; From 21399f1b7fc7d9791fdc0164e7609f1b55ecda38 Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Thu, 8 Jan 2026 09:52:23 -0500 Subject: [PATCH 460/477] #3767 misc changes --- .../src/services/onboarding.services.ts | 11 +- .../src/services/organizations.services.ts | 1 + .../Checklists/CreateChecklistModal.tsx | 29 +-- .../Checklists/CreateInfoBlockModal.tsx | 159 ++--------------- .../Checklists/EditInfoBlockModal.tsx | 159 +++-------------- .../Checklists/InfoBlockFormModal.tsx | 167 ++++++++++++++++++ 6 files changed, 229 insertions(+), 297 deletions(-) create mode 100644 src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/InfoBlockFormModal.tsx diff --git a/src/backend/src/services/onboarding.services.ts b/src/backend/src/services/onboarding.services.ts index 006cf01656..9fa47d9a16 100644 --- a/src/backend/src/services/onboarding.services.ts +++ b/src/backend/src/services/onboarding.services.ts @@ -177,20 +177,17 @@ export default class OnboardingServices { } // Calculate next displayIndex - const existingChecklists = await prisma.checklist.findMany({ + const lastChecklist = await prisma.checklist.findFirst({ where: { organizationId: organization.organizationId, parentChecklistId: parentChecklistId ?? null, dateDeleted: null }, - orderBy: { displayIndex: 'desc' }, - take: 1 + orderBy: { displayIndex: 'desc' } }); - const nextDisplayIndex = - existingChecklists.length > 0 && existingChecklists[0].displayIndex !== null - ? existingChecklists[0].displayIndex + 1 - : 1; + // 1 indexed because 0 can be easily confused with null + const nextDisplayIndex = lastChecklist && lastChecklist.displayIndex !== null ? lastChecklist.displayIndex + 1 : 1; const checklist: Checklist = await prisma.checklist.create({ data: { diff --git a/src/backend/src/services/organizations.services.ts b/src/backend/src/services/organizations.services.ts index 3ed7e40b91..c6ed95bd8a 100644 --- a/src/backend/src/services/organizations.services.ts +++ b/src/backend/src/services/organizations.services.ts @@ -371,6 +371,7 @@ export default class OrganizationsService { const newMemberImageData = await uploadFile(newMemberImage); + // Ensure name exists for frontend display purposes if (!newMemberImageData?.name) { throw new HttpException(500, 'Image Name not found'); } diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx index 004b153ccd..857629c15e 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx @@ -46,7 +46,7 @@ interface ChecklistFormValues { } const schema: yup.ObjectSchema = yup.object().shape({ - content: yup.string().required('Task name is required') + content: yup.string().required('Content is required') }); const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateChecklistModalProps) => { @@ -71,21 +71,26 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC }); const addTask = () => { - setItems([...items, { id: `task-${Date.now()}`, type: ChecklistItemType.TASK, content: '', isOptional: false }]); + setItems((prevItems) => [ + ...prevItems, + { id: `task-${Date.now()}`, type: ChecklistItemType.TASK, content: '', isOptional: false } + ]); }; const addInfoBlock = () => { - setItems([...items, { id: `info-${Date.now()}`, type: ChecklistItemType.INFO, content: '' }]); + setItems((prevItems) => [...prevItems, { id: `info-${Date.now()}`, type: ChecklistItemType.INFO, content: '' }]); }; const updateItem = (index: number, updates: Partial) => { - const newItems = [...items]; - newItems[index] = { ...newItems[index], ...updates }; - setItems(newItems); + setItems((prevItems) => { + const newItems = [...prevItems]; + newItems[index] = { ...newItems[index], ...updates }; + return newItems; + }); }; const removeItem = (index: number) => { - setItems(items.filter((_, i) => i !== index)); + setItems((prevItems) => prevItems.filter((_, i) => i !== index)); }; const onDragEnd: OnDragEndResponder = (result) => { @@ -95,10 +100,12 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC return; } - const newItems = Array.from(items); - const [removed] = newItems.splice(source.index, 1); - newItems.splice(destination.index, 0, removed); - setItems(newItems); + setItems((prevItems) => { + const newItems = Array.from(prevItems); + const [removed] = newItems.splice(source.index, 1); + newItems.splice(destination.index, 0, removed); + return newItems; + }); }; if (isError) return ; diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx index e46e6c1652..4882b275ac 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx @@ -1,13 +1,9 @@ -import { FormControl, FormLabel, TextField, useTheme, Typography, Box } from '@mui/material'; -import React from 'react'; -import { useForm, Controller } from 'react-hook-form'; -import { yupResolver } from '@hookform/resolvers/yup'; -import * as yup from 'yup'; -import NERFormModal from '../../../../components/NERFormModal'; -import { useCreateChecklist } from '../../../../hooks/onboarding.hook'; +import ErrorPage from '../../../ErrorPage'; +import LoadingIndicator from '../../../../components/LoadingIndicator'; +import { ChecklistCreateArgs, useCreateChecklist } from '../../../../hooks/onboarding.hook'; import { useToast } from '../../../../hooks/toasts.hooks'; -import { Checklist, ChecklistItemType } from 'shared'; -import NERMarkdown from '../../../../components/NERMarkdown'; +import InfoBlockFormModal from './InfoBlockFormModal'; +import { Checklist } from 'shared'; interface CreateInfoBlockModalProps { open: boolean; @@ -15,147 +11,26 @@ interface CreateInfoBlockModalProps { parentChecklist: Checklist; } -interface InfoBlockFormValues { - content: string; -} - -const schema = yup.object().shape({ - content: yup.string().required('Content is required') -}); - -const CreateInfoBlockModal: React.FC = ({ open, handleClose, parentChecklist }) => { - const theme = useTheme(); +const CreateInfoBlockModal = ({ open, handleClose, parentChecklist }: CreateInfoBlockModalProps) => { + const { mutateAsync: createChecklist, isLoading, isError, error } = useCreateChecklist(); const toast = useToast(); - const { mutateAsync: createChecklist } = useCreateChecklist(); - const { - handleSubmit, - control, - watch, - reset, - formState: { errors } - } = useForm({ - resolver: yupResolver(schema), - defaultValues: { content: '' } - }); - - const contentValue = watch('content'); - - const onFormSubmit = async (data: InfoBlockFormValues) => { + const handleFormSubmit = async (data: ChecklistCreateArgs) => { try { - await createChecklist({ - content: data.content, - isOptional: true, // INFO blocks are always optional - parentChecklistId: parentChecklist.checklistId, - teamId: parentChecklist.team?.teamId, - teamTypeId: parentChecklist.teamType?.teamTypeId, - itemType: ChecklistItemType.INFO - }); + const response = await createChecklist(data); toast.success('Information block created successfully'); - handleClose(); - reset(); - } catch (error: any) { - toast.error(error.message || 'Failed to create information block'); + return response; + } catch (err) { + toast.error('Failed to create information block'); + throw err; } }; + if (isError) return ; + if (isLoading) return ; + return ( - { - handleClose(); - reset(); - }} - title="Create Information Block" - reset={() => reset({ content: '' })} - handleUseFormSubmit={handleSubmit} - onFormSubmit={onFormSubmit} - formId="create-info-block-form" - showCloseButton - paperProps={{ maxWidth: '90vw', minWidth: '80vw' }} - > - - - - Content (Markdown)* - - ( - - )} - /> - - - - Preview: - - {contentValue ? ( - - ) : ( - - Start typing to see formatted markdown... - - )} - - - + ); }; diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx index 84ca94f8cd..b0cfdf4c04 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/EditInfoBlockModal.tsx @@ -1,13 +1,9 @@ -import { FormControl, FormLabel, TextField, useTheme, Typography, Box } from '@mui/material'; -import React from 'react'; -import { useForm, Controller } from 'react-hook-form'; -import { yupResolver } from '@hookform/resolvers/yup'; -import * as yup from 'yup'; -import NERFormModal from '../../../../components/NERFormModal'; -import { useEditChecklist } from '../../../../hooks/onboarding.hook'; +import ErrorPage from '../../../ErrorPage'; +import LoadingIndicator from '../../../../components/LoadingIndicator'; +import { ChecklistCreateArgs, useEditChecklist } from '../../../../hooks/onboarding.hook'; import { useToast } from '../../../../hooks/toasts.hooks'; -import { Checklist, ChecklistItemType, ChecklistPreview } from 'shared'; -import NERMarkdown from '../../../../components/NERMarkdown'; +import InfoBlockFormModal from './InfoBlockFormModal'; +import { Checklist, ChecklistPreview } from 'shared'; interface EditInfoBlockModalProps { open: boolean; @@ -16,143 +12,32 @@ interface EditInfoBlockModalProps { defaultValues: ChecklistPreview; } -interface InfoBlockFormValues { - content: string; -} - -const schema = yup.object().shape({ - content: yup.string().required('Content is required') -}); - -const EditInfoBlockModal: React.FC = ({ open, handleClose, parentChecklist, defaultValues }) => { - const theme = useTheme(); +const EditInfoBlockModal = ({ open, handleClose, parentChecklist, defaultValues }: EditInfoBlockModalProps) => { + const { mutateAsync: editChecklist, isLoading, isError, error } = useEditChecklist(defaultValues.checklistId); const toast = useToast(); - const { mutateAsync: editChecklist } = useEditChecklist(defaultValues.checklistId); - const { - handleSubmit, - control, - watch, - reset, - formState: { errors } - } = useForm({ - resolver: yupResolver(schema), - defaultValues: { content: defaultValues.content || '' } - }); - - const contentValue = watch('content'); - - const onFormSubmit = async (data: InfoBlockFormValues) => { + const handleFormSubmit = async (data: ChecklistCreateArgs) => { try { - await editChecklist({ - content: data.content, - isOptional: true, // INFO blocks are always optional - parentChecklistId: parentChecklist.checklistId, - teamId: parentChecklist.team?.teamId, - teamTypeId: parentChecklist.teamType?.teamTypeId, - itemType: ChecklistItemType.INFO - }); + const response = await editChecklist(data); toast.success('Information block updated successfully'); - handleClose(); - } catch (error: any) { - toast.error(error.message || 'Failed to update information block'); + return response; + } catch (err) { + toast.error('Failed to update information block'); + throw err; } }; + if (isError) return ; + if (isLoading) return ; + return ( - reset({ content: defaultValues.content || '' })} - handleUseFormSubmit={handleSubmit} - onFormSubmit={onFormSubmit} - formId="edit-info-block-form" - showCloseButton - paperProps={{ maxWidth: '90vw', minWidth: '80vw' }} - > - - - - Content (Markdown)* - - ( - - )} - /> - - - - Preview: - - {contentValue ? ( - - ) : ( - - Start typing to see formatted markdown... - - )} - - - + handleClose={handleClose} + onSubmit={handleFormSubmit} + parentChecklist={parentChecklist} + defaultValues={defaultValues} + /> ); }; diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/InfoBlockFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/InfoBlockFormModal.tsx new file mode 100644 index 0000000000..dbee1cc79e --- /dev/null +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/InfoBlockFormModal.tsx @@ -0,0 +1,167 @@ +import { FormControl, FormLabel, TextField, useTheme, Typography, Box } from '@mui/material'; +import React from 'react'; +import { useForm, Controller } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import * as yup from 'yup'; +import NERFormModal from '../../../../components/NERFormModal'; +import { ChecklistCreateArgs } from '../../../../hooks/onboarding.hook'; +import { useToast } from '../../../../hooks/toasts.hooks'; +import { Checklist, ChecklistItemType, ChecklistPreview } from 'shared'; +import NERMarkdown from '../../../../components/NERMarkdown'; + +interface InfoBlockFormModalProps { + open: boolean; + handleClose: () => void; + onSubmit: (data: ChecklistCreateArgs) => Promise; + parentChecklist: Checklist; + defaultValues?: ChecklistPreview; +} + +interface InfoBlockFormValues { + content: string; +} + +const schema = yup.object().shape({ + content: yup.string().required('Content is required') +}); + +const InfoBlockFormModal: React.FC = ({ + open, + handleClose, + onSubmit, + parentChecklist, + defaultValues +}) => { + const theme = useTheme(); + const toast = useToast(); + + const { + handleSubmit, + control, + watch, + reset, + formState: { errors } + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { content: defaultValues?.content ?? '' } + }); + + const contentValue = watch('content'); + + const onFormSubmit = async (data: InfoBlockFormValues) => { + try { + const formattedData = { + content: data.content, + isOptional: true, // INFO blocks are always optional + parentChecklistId: parentChecklist.checklistId, + teamId: parentChecklist.team?.teamId, + teamTypeId: parentChecklist.teamType?.teamTypeId, + itemType: ChecklistItemType.INFO + }; + + await onSubmit(formattedData); + handleClose(); + } catch (error) { + toast.error('Failed to save information block'); + console.error('Error in onFormSubmit:', error); + } + }; + + return ( + reset({ content: defaultValues?.content ?? '' })} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId={defaultValues ? 'edit-info-block-form' : 'create-info-block-form'} + showCloseButton + paperProps={{ maxWidth: '90vw', minWidth: '80vw' }} + > + + + + Content (Markdown)* + + ( + + )} + /> + + + + Preview: + + {contentValue ? ( + + ) : ( + + Start typing to see formatted markdown... + + )} + + + + ); +}; + +export default InfoBlockFormModal; From e037e02f78d15075ae3c9eae10cc092162182a40 Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Thu, 8 Jan 2026 10:01:05 -0500 Subject: [PATCH 461/477] #3767 prettier --- .../OnboardingConfig/Checklists/CreateInfoBlockModal.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx index 4882b275ac..d54e8a4f5b 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateInfoBlockModal.tsx @@ -30,7 +30,12 @@ const CreateInfoBlockModal = ({ open, handleClose, parentChecklist }: CreateInfo if (isLoading) return ; return ( - + ); }; From a63bd3215519b178f9a66a7e873a1a5180b21a5d Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Mon, 5 Jan 2026 16:25:35 -0500 Subject: [PATCH 462/477] #3860 don't include assemblies in materials --- .../src/prisma-query-args/bom.query-args.ts | 21 +----------- src/backend/src/services/boms.services.ts | 34 +++++++++++++------ .../src/transformers/material.transformer.ts | 11 +----- .../ProjectViewContainer/BOM/BOMTable.tsx | 2 +- src/shared/src/types/bom-types.ts | 1 - 5 files changed, 27 insertions(+), 42 deletions(-) diff --git a/src/backend/src/prisma-query-args/bom.query-args.ts b/src/backend/src/prisma-query-args/bom.query-args.ts index a2a75e3596..1a81b8eb99 100644 --- a/src/backend/src/prisma-query-args/bom.query-args.ts +++ b/src/backend/src/prisma-query-args/bom.query-args.ts @@ -1,6 +1,5 @@ import { Prisma } from '@prisma/client'; import { getUserQueryArgs } from './user.query-args'; -import { getTeamQueryArgs } from './teams.query-args'; import { getReimbursementRequestQueryArgs } from './reimbursement-requests.query-args'; export type AssemblyQueryArgs = ReturnType; @@ -11,24 +10,7 @@ export const getAssemblyQueryArgs = (organizationId: string) => userCreated: getUserQueryArgs(organizationId), userDeleted: getUserQueryArgs(organizationId), materials: getMaterialPreviewQueryArgs(organizationId), - wbsElement: { - include: { - project: { - include: { - teams: getTeamQueryArgs(organizationId) - } - }, - workPackage: { - include: { - project: { - include: { - teams: getTeamQueryArgs(organizationId) - } - } - } - } - } - } + wbsElement: true } }); @@ -37,7 +19,6 @@ export type MaterialQueryArgs = ReturnType; export const getMaterialQueryArgs = (organizationId: string) => Prisma.validator()({ include: { - assembly: getAssemblyQueryArgs(organizationId), wbsElement: true, userCreated: getUserQueryArgs(organizationId), userDeleted: getUserQueryArgs(organizationId), diff --git a/src/backend/src/services/boms.services.ts b/src/backend/src/services/boms.services.ts index a32d604f8b..0f5747b243 100644 --- a/src/backend/src/services/boms.services.ts +++ b/src/backend/src/services/boms.services.ts @@ -36,6 +36,7 @@ import { } from '../prisma-query-args/bom.query-args'; import { getManufacturerQueryArgs } from '../prisma-query-args/manufacturers.query-args'; import { getMaterialTypeQueryArgs } from '../prisma-query-args/material-type.query-args'; +import { getUserQueryArgs } from '../prisma-query-args/user.query-args'; export default class BillOfMaterialsService { /** @@ -705,7 +706,21 @@ export default class BillOfMaterialsService { ): Promise { const assembly = await BillOfMaterialsService.getSingleAssemblyWithQueryArgs(assemblyId, organization); - const teams = assembly.wbsElement?.project?.teams ?? assembly.wbsElement.workPackage?.project.teams ?? []; + const teams = await prisma.team.findMany({ + where: { + organizationId: organization.organizationId, + projects: { + some: { + wbsElementId: assembly.wbsElementId + } + } + }, + include: { + members: getUserQueryArgs(organization.organizationId), + head: getUserQueryArgs(organization.organizationId), + leads: getUserQueryArgs(organization.organizationId) + } + }); const perms = (await userHasPermission(submitter.userId, assembly.wbsElement.organizationId, isAdmin)) || @@ -807,14 +822,6 @@ export default class BillOfMaterialsService { ...wbsNum, organizationId: organization.organizationId } - }, - include: { - assemblies: { - where: { - dateDeleted: null - }, - ...getAssemblyQueryArgs(organization.organizationId) - } } }); @@ -825,7 +832,14 @@ export default class BillOfMaterialsService { throw new DeletedException('WBS Element', wbsPipe(wbsNum)); } - return wbsElement.assemblies.map(assemblyTransformer); + const assemblies = await prisma.assembly.findMany({ + where: { + wbsElementId: wbsElement.wbsElementId + }, + ...getAssemblyQueryArgs(organization.organizationId) + }); + + return assemblies.map(assemblyTransformer); } static async getMaterialsForWbsElement(wbsNum: WbsNumber, organization: Organization): Promise { diff --git a/src/backend/src/transformers/material.transformer.ts b/src/backend/src/transformers/material.transformer.ts index a629d88525..1a113537c0 100644 --- a/src/backend/src/transformers/material.transformer.ts +++ b/src/backend/src/transformers/material.transformer.ts @@ -1,5 +1,5 @@ import { Prisma } from '@prisma/client'; -import { Assembly, AssemblyPreview, Material, MaterialPreview, MaterialStatus } from 'shared'; +import { Assembly, Material, MaterialPreview, MaterialStatus } from 'shared'; import { AssemblyQueryArgs, MaterialPreviewQueryArgs, MaterialQueryArgs } from '../prisma-query-args/bom.query-args'; import { userTransformer } from './user.transformer'; import { reimbursementRequestTransformer } from './reimbursement-requests.transformer'; @@ -15,19 +15,10 @@ export const assemblyTransformer = (assembly: Prisma.AssemblyGetPayload): AssemblyPreview => { - return { - ...assembly, - dateDeleted: assembly.dateDeleted ?? undefined, - pdmFileName: assembly.pdmFileName ?? undefined - }; -}; - export const materialTransformer = (material: Prisma.MaterialGetPayload): Material => { return { materialId: material.materialId, assemblyId: material.assemblyId ?? undefined, - assembly: material.assembly ? assemblyPreviewTransformer(material.assembly) : undefined, name: material.name, wbsElementId: material.wbsElementId, dateDeleted: material.dateDeleted ?? undefined, diff --git a/src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/BOMTable.tsx b/src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/BOMTable.tsx index c6de1053f1..4633ce9d6e 100644 --- a/src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/BOMTable.tsx +++ b/src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/BOMTable.tsx @@ -23,7 +23,7 @@ const BOMTable: React.FC = ({ setHideColumn, assignMaterial, colu return openRows.includes(rowId) ? '▼' : '▶'; }; - const noAssemblyMaterials = materials.filter((material) => !material.assembly); + const noAssemblyMaterials = materials.filter((material) => !material.assemblyId); const theme = useTheme(); const rows: BomRow[] = noAssemblyMaterials.map((material: Material, idx: number) => materialToRow(material, idx)); diff --git a/src/shared/src/types/bom-types.ts b/src/shared/src/types/bom-types.ts index 1efa18bb40..1a604c6981 100644 --- a/src/shared/src/types/bom-types.ts +++ b/src/shared/src/types/bom-types.ts @@ -52,7 +52,6 @@ export type ManufacturerPreview = Omit Date: Thu, 8 Jan 2026 10:11:19 -0500 Subject: [PATCH 463/477] #3860 add back missing date deleted field --- src/backend/src/services/boms.services.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/src/services/boms.services.ts b/src/backend/src/services/boms.services.ts index 0f5747b243..8850887505 100644 --- a/src/backend/src/services/boms.services.ts +++ b/src/backend/src/services/boms.services.ts @@ -834,7 +834,8 @@ export default class BillOfMaterialsService { const assemblies = await prisma.assembly.findMany({ where: { - wbsElementId: wbsElement.wbsElementId + wbsElementId: wbsElement.wbsElementId, + dateDeleted: null }, ...getAssemblyQueryArgs(organization.organizationId) }); From 06c05a526c6137aef7cf289251ee1740d0a84ca9 Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Thu, 8 Jan 2026 11:04:05 -0500 Subject: [PATCH 464/477] changed from enum to const for compilation hot fix --- src/shared/src/types/checklist-types.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/shared/src/types/checklist-types.ts b/src/shared/src/types/checklist-types.ts index 05c6d0834f..ade9561859 100644 --- a/src/shared/src/types/checklist-types.ts +++ b/src/shared/src/types/checklist-types.ts @@ -7,10 +7,12 @@ import { TeamType } from './design-review-types'; import { Team } from './team-types'; import { User } from './user-types'; -export enum ChecklistItemType { - TASK = 'TASK', - INFO = 'INFO' -} +export const ChecklistItemType = { + TASK: 'TASK', + INFO: 'INFO' +} as const; + +export type ChecklistItemType = (typeof ChecklistItemType)[keyof typeof ChecklistItemType]; export interface Checklist { checklistId: string; From 39f06366264d8b4e9251cbb5a9f427e93389e8b6 Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Thu, 8 Jan 2026 11:16:21 -0500 Subject: [PATCH 465/477] Change to string literals as temporaryt solution --- .../Checklists/AdminSubtaskSection.tsx | 2 +- .../Checklists/CreateChecklistModal.tsx | 12 ++++++------ .../Checklists/InfoBlockFormModal.tsx | 2 +- .../OnboardingConfig/Checklists/SubtaskFormModal.tsx | 2 +- .../src/pages/HomePage/components/SubtaskSection.tsx | 4 ++-- src/shared/src/types/checklist-types.ts | 10 ++++------ 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx index 67d4f787a8..fcca07779b 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/AdminSubtaskSection.tsx @@ -202,7 +202,7 @@ const AdminSubtaskSection: React.FC = ({ parentTask }) open={!!itemToDelete} onHide={() => setItemToDelete(null)} formId="delete-item-form" - dataType={itemToDelete.itemType === ChecklistItemType.INFO ? 'Information Block' : 'Task'} + dataType={itemToDelete.itemType === "INFO" ? 'Information Block' : 'Task'} onFormSubmit={() => handleDelete(itemToDelete.checklistId)} /> )} diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx index 857629c15e..7154c8bdc0 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/CreateChecklistModal.tsx @@ -73,12 +73,12 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC const addTask = () => { setItems((prevItems) => [ ...prevItems, - { id: `task-${Date.now()}`, type: ChecklistItemType.TASK, content: '', isOptional: false } + { id: `task-${Date.now()}`, type: 'TASK' as ChecklistItemType, content: '', isOptional: false } ]); }; const addInfoBlock = () => { - setItems((prevItems) => [...prevItems, { id: `info-${Date.now()}`, type: ChecklistItemType.INFO, content: '' }]); + setItems((prevItems) => [...prevItems, { id: `info-${Date.now()}`, type: 'INFO' as ChecklistItemType, content: '' }]); }; const updateItem = (index: number, updates: Partial) => { @@ -125,23 +125,23 @@ const CreateChecklistModal = ({ open, handleClose, teamId, teamTypeId }: CreateC // Create all items in order with their displayIndex set await Promise.all( items.map((item) => { - if (item.type === ChecklistItemType.TASK) { + if (item.type === 'TASK') { return createChecklist({ content: item.content, teamId, teamTypeId, parentChecklistId: parentChecklist.checklistId, isOptional: item.isOptional || false, - itemType: ChecklistItemType.TASK + itemType: 'TASK' }); - } else if (item.type === ChecklistItemType.INFO) { + } else if (item.type === 'INFO') { return createChecklist({ content: item.content, teamId, teamTypeId, parentChecklistId: parentChecklist.checklistId, isOptional: true, // INFO blocks are always optional - itemType: ChecklistItemType.INFO + itemType: 'INFO' }); } throw new Error(`Unexpected checklist item type: ${String(item.type)}`); diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/InfoBlockFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/InfoBlockFormModal.tsx index dbee1cc79e..1c43f8ed60 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/InfoBlockFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/InfoBlockFormModal.tsx @@ -56,7 +56,7 @@ const InfoBlockFormModal: React.FC = ({ parentChecklistId: parentChecklist.checklistId, teamId: parentChecklist.team?.teamId, teamTypeId: parentChecklist.teamType?.teamTypeId, - itemType: ChecklistItemType.INFO + itemType: "INFO" as ChecklistItemType }; await onSubmit(formattedData); diff --git a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx index aab0896324..74d156ca82 100644 --- a/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/OnboardingConfig/Checklists/SubtaskFormModal.tsx @@ -45,7 +45,7 @@ const SubtaskFormModal = ({ open, handleClose, onSubmit, parentChecklist, defaul parentChecklistId: parentChecklist.checklistId, teamId: parentChecklist.team?.teamId, teamTypeId: parentChecklist.teamType?.teamTypeId, - itemType: ChecklistItemType.TASK + itemType: "TASK" as ChecklistItemType }; await onSubmit(formattedData); diff --git a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx index 86a95279f2..e13b7e4b67 100644 --- a/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx +++ b/src/frontend/src/pages/HomePage/components/SubtaskSection.tsx @@ -2,7 +2,7 @@ import { Typography, useTheme, IconButton } from '@mui/material'; import Checkbox from '@mui/material/Checkbox'; import { Box } from '@mui/system'; import React from 'react'; -import { Checklist, ChecklistItemType } from 'shared'; +import { Checklist } from 'shared'; import { GridDragIcon } from '@mui/x-data-grid'; import { useToggleChecklist } from '../../../hooks/onboarding.hook'; import { useToast } from '../../../hooks/toasts.hooks'; @@ -57,7 +57,7 @@ const SubtaskSection: React.FC = ({ parentTask, checkedChec > {allItems.map((item) => { - if (item.itemType === ChecklistItemType.TASK) { + if (item.itemType === "TASK") { return ( {isAdmin ? ( diff --git a/src/shared/src/types/checklist-types.ts b/src/shared/src/types/checklist-types.ts index ade9561859..05c6d0834f 100644 --- a/src/shared/src/types/checklist-types.ts +++ b/src/shared/src/types/checklist-types.ts @@ -7,12 +7,10 @@ import { TeamType } from './design-review-types'; import { Team } from './team-types'; import { User } from './user-types'; -export const ChecklistItemType = { - TASK: 'TASK', - INFO: 'INFO' -} as const; - -export type ChecklistItemType = (typeof ChecklistItemType)[keyof typeof ChecklistItemType]; +export enum ChecklistItemType { + TASK = 'TASK', + INFO = 'INFO' +} export interface Checklist { checklistId: string; From 8f82952921a987ce7801d8ce00a4a41021a65c56 Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Fri, 16 Jan 2026 10:06:17 -0500 Subject: [PATCH 466/477] Move migration back, show work package events on that work packages team filter --- .../migration.sql | 0 src/backend/src/services/calendar.services.ts | 1 + 2 files changed, 1 insertion(+) rename src/backend/src/prisma/migrations/{20251210001906_calendar => 20260111001906_calendar}/migration.sql (100%) diff --git a/src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql b/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql similarity index 100% rename from src/backend/src/prisma/migrations/20251210001906_calendar/migration.sql rename to src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index cbad94ae40..b9a5f52a2e 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -2239,6 +2239,7 @@ export default class CalendarService { if (teamIds?.length) { memberOrTeamFilter.push({ teams: { some: { teamId: { in: teamIds } } } }); + memberOrTeamFilter.push({ workPackages: { some: { project: { teams: { some: { teamId: { in: teamIds } } } } } } }); } // filters for selected calendars From 7dffbc1ab083ddf2ffdc42e00798848252f3320e Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Fri, 16 Jan 2026 11:40:17 -0500 Subject: [PATCH 467/477] all work package previews endpoint and lazy load create form data --- .../controllers/work-packages.controllers.ts | 16 +++ .../src/routes/work-packages.routes.ts | 10 +- .../src/services/work-packages.services.ts | 27 ++++- src/frontend/src/apis/work-packages.api.ts | 11 +- src/frontend/src/hooks/work-packages.hooks.ts | 15 ++- .../CalendarPage/Components/EventModal.tsx | 104 ++++++++---------- src/frontend/src/utils/urls.ts | 3 + 7 files changed, 122 insertions(+), 64 deletions(-) diff --git a/src/backend/src/controllers/work-packages.controllers.ts b/src/backend/src/controllers/work-packages.controllers.ts index 9b64d5537d..2c0b34ddf9 100644 --- a/src/backend/src/controllers/work-packages.controllers.ts +++ b/src/backend/src/controllers/work-packages.controllers.ts @@ -17,6 +17,22 @@ export default class WorkPackagesController { } } + // Fetch all work packages in preview format (minimal data for dropdowns/lists) + static async getAllWorkPackagesPreview(req: Request, res: Response, next: NextFunction) { + try { + const { status } = req.query as { status?: string }; + + const outputWorkPackages: WorkPackagePreview[] = await WorkPackagesService.getAllWorkPackagesPreview( + status, + req.organization + ); + + res.status(200).json(outputWorkPackages); + } catch (error: unknown) { + next(error); + } + } + // Fetch the work package for the specified WBS number static async getSingleWorkPackage(req: Request, res: Response, next: NextFunction) { try { diff --git a/src/backend/src/routes/work-packages.routes.ts b/src/backend/src/routes/work-packages.routes.ts index dbb2f2abdf..bd072b9a64 100644 --- a/src/backend/src/routes/work-packages.routes.ts +++ b/src/backend/src/routes/work-packages.routes.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { body, param } from 'express-validator'; +import { body, param, query } from 'express-validator'; import WorkPackagesController from '../controllers/work-packages.controllers.js'; import { blockedByValidators, @@ -10,10 +10,16 @@ import { nonEmptyString, validateInputs } from '../utils/validation.utils.js'; -import { WorkPackageSelection } from 'shared'; +import { WorkPackageSelection, WbsElementStatus } from 'shared'; const workPackagesRouter = express.Router(); workPackagesRouter.get('/', WorkPackagesController.getAllWorkPackages); +workPackagesRouter.get( + '/all-preview', + query('status').optional().isIn(Object.values(WbsElementStatus)), + validateInputs, + WorkPackagesController.getAllWorkPackagesPreview +); workPackagesRouter.post( '/get-many', body('wbsNums').isArray(), diff --git a/src/backend/src/services/work-packages.services.ts b/src/backend/src/services/work-packages.services.ts index 9faf820fc5..dc0a3ab262 100644 --- a/src/backend/src/services/work-packages.services.ts +++ b/src/backend/src/services/work-packages.services.ts @@ -24,7 +24,7 @@ import { DeletedException, InvalidOrganizationException } from '../utils/errors.utils.js'; -import { getWorkPackageQueryArgs } from '../prisma-query-args/work-packages.query-args.js'; +import { getWorkPackageQueryArgs, getWorkPackagePreviewQueryArgs } from '../prisma-query-args/work-packages.query-args.js'; import workPackageTransformer, { workPackagePreviewTransformer } from '../transformers/work-packages.transformer.js'; import { updateBlocking, validateChangeRequestAccepted } from '../utils/change-requests.utils.js'; import { sendSlackUpcomingDeadlineNotification } from '../utils/slack.utils.js'; @@ -75,6 +75,31 @@ export default class WorkPackagesService { return outputWorkPackages; } + /** + * Retrieve all work packages in preview format (minimal data for dropdowns/lists). + * + * @param status Optional status filter + * @param organization the organization + * @returns a list of work package previews + */ + static async getAllWorkPackagesPreview( + status: WbsElementStatus | string | undefined, + organization: Organization + ): Promise { + const workPackages = await prisma.work_Package.findMany({ + where: { + wbsElement: { + dateDeleted: null, + organizationId: organization.organizationId, + ...(status ? { status: status as WbsElementStatus } : {}) + } + }, + ...getWorkPackagePreviewQueryArgs() + }); + + return workPackages.map(workPackagePreviewTransformer); + } + /** * Retrieve the work package with the specified WBS number. * @param parsedWbs the WBS number of the desired work package diff --git a/src/frontend/src/apis/work-packages.api.ts b/src/frontend/src/apis/work-packages.api.ts index 55b38ae550..6933d7eb33 100644 --- a/src/frontend/src/apis/work-packages.api.ts +++ b/src/frontend/src/apis/work-packages.api.ts @@ -4,7 +4,7 @@ */ import axios from '../utils/axios'; -import { DescriptionBulletPreview, WbsNumber, WorkPackage, WorkPackageStage } from 'shared'; +import { DescriptionBulletPreview, WbsNumber, WorkPackage, WorkPackagePreview, WorkPackageStage } from 'shared'; import { wbsPipe } from '../utils/pipes'; import { apiUrls } from '../utils/urls'; import { workPackagePreviewTransformer, workPackageTransformer } from './transformers/work-packages.transformers'; @@ -118,3 +118,12 @@ export const getHomePageWorkPackages = (selection: WorkPackageSelection) => { transformResponse: (data) => JSON.parse(data).map(workPackagePreviewTransformer) }); }; + +/** + * Fetch all work packages in preview format (minimal data for dropdowns/lists). + */ +export const getAllWorkPackagesPreview = (status?: string) => { + return axios.get(apiUrls.workPackagesAllPreview(status), { + transformResponse: (data) => JSON.parse(data).map(workPackagePreviewTransformer) + }); +}; diff --git a/src/frontend/src/hooks/work-packages.hooks.ts b/src/frontend/src/hooks/work-packages.hooks.ts index 47b72f0c39..acf0fa7d92 100644 --- a/src/frontend/src/hooks/work-packages.hooks.ts +++ b/src/frontend/src/hooks/work-packages.hooks.ts @@ -4,16 +4,17 @@ */ import { useMutation, useQuery, useQueryClient } from 'react-query'; -import { WorkPackage, WbsNumber, WorkPackageSelection } from 'shared'; +import { WorkPackage, WorkPackagePreview, WbsNumber, WorkPackageSelection } from 'shared'; import { createSingleWorkPackage, deleteWorkPackage, editWorkPackage, getAllBlockingWorkPackages, getAllWorkPackages, + getAllWorkPackagesPreview, + getManyWorkPackages, getSingleWorkPackage, slackUpcomingDeadlines, - getManyWorkPackages, WorkPackageCreateArgs, WorkPackageEditArgs, getHomePageWorkPackages @@ -29,6 +30,16 @@ export const useAllWorkPackages = (queryParams?: { [field: string]: string }) => }); }; +/** + * Custom React Hook to supply all work packages in preview format (minimal data). + */ +export const useAllWorkPackagesPreview = (status?: string) => { + return useQuery(['work packages', 'preview', status], async () => { + const { data } = await getAllWorkPackagesPreview(status); + return data; + }); +}; + /** * Custom React Hook to supply a single work package. * diff --git a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx index 0c7fc3f15d..b49e524698 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx @@ -19,23 +19,13 @@ import { DatePicker, TimePicker } from '@mui/x-date-pickers'; import { Controller, useForm } from 'react-hook-form'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; -import { - DayOfWeek, - EventDocumentUploadArgs, - WbsElementStatus, - wbsNamePipe, - wbsNumComparator, - EventType, - isHead, - MAX_FILE_SIZE -} from 'shared'; +import { DayOfWeek, EventDocumentUploadArgs, WbsElementStatus, wbsNamePipe, EventType, isHead, MAX_FILE_SIZE } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import { useAllUsers, useCurrentUser } from '../../../hooks/users.hooks'; -import { useAllWorkPackages } from '../../../hooks/work-packages.hooks'; +import { useAllWorkPackagesPreview } from '../../../hooks/work-packages.hooks'; import { useAllTeams } from '../../../hooks/teams.hooks'; import { userToAutocompleteOption } from '../../../utils/teams.utils'; import ErrorPage from '../../ErrorPage'; -import LoadingIndicator from '../../../components/LoadingIndicator'; import NERFormModal from '../../../components/NERFormModal'; import CalendarTodayIcon from '@mui/icons-material/CalendarToday'; import PeopleIcon from '@mui/icons-material/People'; @@ -156,27 +146,18 @@ const EventModal: React.FC = ({ const [optionalMembers, setOptionalMembers] = useState>([]); const [selectedTeams, setSelectedTeams] = useState>([]); + // Lazy load all data needed for the form so users can start filling out instantly const { isLoading: usersLoading, isError: usersError, error: usersErrorMsg, data: users } = useAllUsers(); const { isLoading: shopsLoading, isError: shopsError, error: shopsErrorMsg, data: shops } = useAllShops(); - const { - isLoading: machineryLoading, - isError: machineryError, - error: machineryErrorMsg, - data: machinery - } = useAllMachines(); + const { isError: machineryError, error: machineryErrorMsg, data: machinery } = useAllMachines(); const { isLoading: workPackagesLoading, isError: workPackagesError, error: workPackagesErrorMsg, data: allWorkPackages - } = useAllWorkPackages(); + } = useAllWorkPackagesPreview(); const { isLoading: teamsLoading, isError: teamsError, error: teamsErrorMsg, data: teams } = useAllTeams(); - const { - isLoading: teamTypesLoading, - isError: teamTypesError, - error: teamTypesErrorMsg, - data: teamTypes - } = useAllTeamTypes(); + const { isError: teamTypesError, error: teamTypesErrorMsg, data: teamTypes } = useAllTeamTypes(); const defaultFormData = useMemo( () => ({ @@ -440,6 +421,22 @@ const EventModal: React.FC = ({ } }; + // When data loads from endpoint, update the options for the autocomplete fields + const memberOptions = useMemo(() => { + if (usersLoading || !users) return [{ id: 'loading', label: 'Loading users...' }]; + return users.map(userToAutocompleteOption); + }, [users, usersLoading]); + + const teamOptions = useMemo(() => { + if (teamsLoading || !teams) return [{ id: 'loading', label: 'Loading teams...' }]; + return teams.map((t) => ({ id: t.teamId, label: t.teamName })); + }, [teams, teamsLoading]); + + const shopOptions = useMemo(() => { + if (shopsLoading || !shops) return [{ id: 'loading', label: 'Loading shops...' }]; + return shops.map((s) => ({ id: s.shopId, label: s.name })); + }, [shops, shopsLoading]); + if (usersError) return ; if (workPackagesError) return ; if (teamsError) return ; @@ -447,34 +444,20 @@ const EventModal: React.FC = ({ if (shopsError) return ; if (machineryError) return ; - if ( - usersLoading || - workPackagesLoading || - teamsLoading || - teamTypesLoading || - !users || - !allWorkPackages || - !teams || - !teamTypes || - shopsLoading || - machineryLoading || - !shops || - !machinery - ) { - return ; - } - - const memberOptions = users.map(userToAutocompleteOption); - const teamOptions = teams.map((t) => ({ id: t.teamId, label: t.teamName })); - const shopOptions = shops.map((s) => ({ id: s.shopId, label: s.name })); - - const workPackageOptions = allWorkPackages - .filter((wp) => wp.status === WbsElementStatus.Active) - .map((wp) => ({ - label: wbsNamePipe(wp), - id: wp.id - })) - .sort((a, b) => wbsNumComparator(b.id, a.id)); + const workPackageOptions = workPackagesLoading + ? [{ id: 'loading', label: 'Loading work packages...' }] + : (allWorkPackages || []) + .filter((wp) => wp.status === WbsElementStatus.Active) + .map((wp) => ({ + label: wbsNamePipe(wp), + id: wp.id, + wbsNum: wp.wbsNum + })) + .sort((a, b) => { + if (a.wbsNum.carNumber !== b.wbsNum.carNumber) return b.wbsNum.carNumber - a.wbsNum.carNumber; + if (a.wbsNum.projectNumber !== b.wbsNum.projectNumber) return b.wbsNum.projectNumber - a.wbsNum.projectNumber; + return b.wbsNum.workPackageNumber - a.wbsNum.workPackageNumber; + }); return ( = ({ Select Team Type - {teamTypes.map((tt) => ( + {teamTypes?.map((tt) => ( {tt.name} @@ -991,8 +974,8 @@ const EventModal: React.FC = ({ control={control} render={({ field: { onChange, value } }) => ( value?.[0] === s.id) || null} + options={shopOptions ? shopOptions : []} + value={shopOptions?.find((s) => value?.[0] === s.id) || null} onChange={(_, newValue) => onChange(newValue ? [newValue.id] : [])} getOptionLabel={(option) => option.label} renderInput={(params) => } @@ -1004,7 +987,7 @@ const EventModal: React.FC = ({ {shopIds.length > 0 && ( {(() => { - const shop = shops.find((s) => s.shopId === shopIds[0]); + const shop = shops?.find((s) => s.shopId === shopIds[0]); if (!shop || !shop.description) return null; return ( = ({ value?.[0] === wp.id) || null} - onChange={(_, newValue) => onChange(newValue ? [newValue.id] : [])} + onChange={(_, newValue) => { + if (newValue?.id !== 'loading') { + onChange(newValue ? [newValue.id] : []); + } + }} getOptionLabel={(option) => option.label} + getOptionDisabled={(option) => option.id === 'loading'} renderInput={(params) => } sx={{ flex: 1 }} /> diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 5c58780538..da15bfffa1 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -113,6 +113,8 @@ const workPackagesDelete = (wbsNum: string) => `${workPackagesByWbsNum(wbsNum)}/ const workPackagesBlocking = (wbsNum: string) => `${workPackagesByWbsNum(wbsNum)}/blocking`; const workPackagesSlackUpcomingDeadlines = () => `${workPackages()}/slack-upcoming-deadlines`; const workPackagesMany = () => `${workPackages()}/get-many`; +const workPackagesAllPreview = (status?: string) => + `${API_URL}/work-packages/all-preview${status ? `?status=${status}` : ''}`; const homePageWorkPackages = (selection: WorkPackageSelection) => `${workPackages()}/home-page/${selection}`; /**************** Change Requests Endpoints ****************/ @@ -570,6 +572,7 @@ export const apiUrls = { workPackagesBlocking, workPackagesSlackUpcomingDeadlines, workPackagesMany, + workPackagesAllPreview, homePageWorkPackages, changeRequests, From 471ac8d983583157ee132ee0bd4fd3b2dae8cfac Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Fri, 16 Jan 2026 20:38:28 -0500 Subject: [PATCH 468/477] team previews without users for faster dropdowns --- .../src/controllers/teams.controllers.ts | 10 ++++++++++ .../src/prisma-query-args/teams.query-args.ts | 10 +++++++++- src/backend/src/routes/teams.routes.ts | 1 + src/backend/src/services/teams.services.ts | 13 +++++++++++-- .../src/transformers/teams.transformer.ts | 18 +++++++++++++++--- src/frontend/src/apis/teams.api.ts | 8 +++++++- .../apis/transformers/teams.transformers.ts | 1 + src/frontend/src/components/TeamsDropdown.tsx | 4 ++-- src/frontend/src/hooks/teams.hooks.ts | 12 ++++++++++-- .../AdminToolsAttendeeDesignReviewInfo.tsx | 6 +----- .../AdminToolsPage/AdminToolsSlackIds.tsx | 13 +++++++++---- .../TeamConfig/EditTeamSlackIdFormModal.tsx | 4 ++-- .../CalendarPage/Components/EventModal.tsx | 4 ++-- .../src/pages/CalendarPage/FilterModal.tsx | 8 ++++++-- .../ProjectTemplateFormView.tsx | 4 ++-- src/frontend/src/utils/urls.ts | 2 ++ src/shared/src/types/team-types.ts | 16 ++++++++++------ 17 files changed, 100 insertions(+), 34 deletions(-) diff --git a/src/backend/src/controllers/teams.controllers.ts b/src/backend/src/controllers/teams.controllers.ts index aeba300506..4e71f67ffe 100644 --- a/src/backend/src/controllers/teams.controllers.ts +++ b/src/backend/src/controllers/teams.controllers.ts @@ -3,6 +3,16 @@ import TeamsService from '../services/teams.services.js'; import { HttpException } from '../utils/errors.utils.js'; export default class TeamsController { + static async getAllTeamPreviews(req: Request, res: Response, next: NextFunction) { + try { + const teams = await TeamsService.getAllTeamPreviews(req.organization); + + res.status(200).json(teams); + } catch (error: unknown) { + next(error); + } + } + static async getAllTeams(req: Request, res: Response, next: NextFunction) { try { const teams = await TeamsService.getAllTeams(req.organization); diff --git a/src/backend/src/prisma-query-args/teams.query-args.ts b/src/backend/src/prisma-query-args/teams.query-args.ts index e8c80742a9..3c22b23b0c 100644 --- a/src/backend/src/prisma-query-args/teams.query-args.ts +++ b/src/backend/src/prisma-query-args/teams.query-args.ts @@ -3,7 +3,7 @@ import { getUserQueryArgs } from './user.query-args.js'; import { getProjectGanttQueryArgs } from './projects.query-args.js'; export type TeamQueryArgs = ReturnType; - +export type TeamBaseQueryArgs = ReturnType; export type TeamPreviewQueryArgs = ReturnType; export const getTeamQueryArgs = (organizationId: string) => @@ -25,6 +25,14 @@ export const getTeamQueryArgs = (organizationId: string) => } }); +export const getTeamBaseQueryArgs = () => { + return Prisma.validator()({ + include: { + teamType: true + } + }); +}; + export const getTeamPreviewQueryArgs = (organizationId: string) => Prisma.validator()({ include: { diff --git a/src/backend/src/routes/teams.routes.ts b/src/backend/src/routes/teams.routes.ts index 24c134608f..ef67393067 100644 --- a/src/backend/src/routes/teams.routes.ts +++ b/src/backend/src/routes/teams.routes.ts @@ -9,6 +9,7 @@ const teamsRouter = express.Router(); const upload = multer({ limits: { fileSize: MAX_FILE_SIZE }, storage: memoryStorage() }); teamsRouter.get('/', TeamsController.getAllTeams); +teamsRouter.get('/previews/', TeamsController.getAllTeamPreviews); teamsRouter.get('/archive', TeamsController.getAllArchivedTeams); teamsRouter.get('/users-teams', TeamsController.getUsersTeams); teamsRouter.get('/my-team-as-head', TeamsController.getMyTeamAsHead); diff --git a/src/backend/src/services/teams.services.ts b/src/backend/src/services/teams.services.ts index 94403ba8ee..0479d2e734 100644 --- a/src/backend/src/services/teams.services.ts +++ b/src/backend/src/services/teams.services.ts @@ -1,7 +1,7 @@ import { isAdmin, isHead, Team, TeamPreview, TeamType, User } from 'shared'; import { Organization, WBS_Element_Status } from '@prisma/client'; import prisma from '../prisma/prisma.js'; -import teamTransformer, { teamPreviewTransformer } from '../transformers/teams.transformer.js'; +import teamTransformer, { teamBaseTransformer, teamPreviewTransformer } from '../transformers/teams.transformer.js'; import { NotFoundException, AccessDeniedException, @@ -13,11 +13,20 @@ import { import { getPrismaQueryUserIds, getUsers, userHasPermission } from '../utils/users.utils.js'; import { isUnderWordCount } from 'shared'; import { removeUsersFromList } from '../utils/teams.utils.js'; -import { getTeamPreviewQueryArgs, getTeamQueryArgs } from '../prisma-query-args/teams.query-args.js'; +import { getTeamBaseQueryArgs, getTeamPreviewQueryArgs, getTeamQueryArgs } from '../prisma-query-args/teams.query-args.js'; import { uploadFile } from '../utils/google-integration.utils.js'; import { teamTypeTransformer } from '../transformers/team-types.transformer.js'; +import { TeamBase } from '../../../shared/src/types/team-types.js'; export default class TeamsService { + static async getAllTeamPreviews(organization: Organization): Promise { + const teams = await prisma.team.findMany({ + where: { dateArchived: null, organizationId: organization.organizationId }, + ...getTeamBaseQueryArgs() + }); + return teams.map(teamBaseTransformer); + } + /** * Gets all teams (archived teams are not included) * @param organizationId The organization the user is currently in diff --git a/src/backend/src/transformers/teams.transformer.ts b/src/backend/src/transformers/teams.transformer.ts index 5c75bc725f..4b9b9a7d33 100644 --- a/src/backend/src/transformers/teams.transformer.ts +++ b/src/backend/src/transformers/teams.transformer.ts @@ -1,6 +1,6 @@ import { Prisma } from '@prisma/client'; -import { Team, TeamPreview } from 'shared'; -import { TeamPreviewQueryArgs, TeamQueryArgs } from '../prisma-query-args/teams.query-args.js'; +import { Team, TeamPreview, TeamBase } from 'shared'; +import { getTeamBaseQueryArgs, TeamPreviewQueryArgs, TeamQueryArgs } from '../prisma-query-args/teams.query-args.js'; import { userTransformer } from './user.transformer.js'; import { teamTypeTransformer } from './team-types.transformer.js'; import { projectGanttTransformer } from './projects.transformer.js'; @@ -21,12 +21,24 @@ const teamTransformer = (team: Prisma.TeamGetPayload): Team => { }; }; +export const teamBaseTransformer = (team: Prisma.TeamGetPayload>): TeamBase => { + return { + teamId: team.teamId, + teamName: team.teamName, + slackId: team.slackId, + description: team.description, + dateArchived: team.dateArchived ?? undefined, + teamType: team.teamType ? teamTypeTransformer(team.teamType) : undefined + }; +}; + export const teamPreviewTransformer = (team: Prisma.TeamGetPayload): TeamPreview => { return { ...team, leads: team.leads.map(userTransformer), members: team.members.map(userTransformer), - head: userTransformer(team.head) + head: userTransformer(team.head), + dateArchived: team.dateArchived ?? undefined }; }; diff --git a/src/frontend/src/apis/teams.api.ts b/src/frontend/src/apis/teams.api.ts index 239df85b1b..a9065e0174 100644 --- a/src/frontend/src/apis/teams.api.ts +++ b/src/frontend/src/apis/teams.api.ts @@ -4,11 +4,17 @@ */ import axios from '../utils/axios'; -import { Team, TeamPreview } from 'shared'; +import { Team, TeamBase, TeamPreview } from 'shared'; import { apiUrls } from '../utils/urls'; import { CreateTeamPayload } from '../hooks/teams.hooks'; import { teamPreviewTransformer, teamTransformer } from './transformers/teams.transformers'; +export const getAllTeamPreviews = () => { + return axios.get(apiUrls.teamPreviews(), { + transformResponse: (data) => JSON.parse(data).map(teamPreviewTransformer) + }); +}; + export const getAllTeams = () => { return axios.get(apiUrls.teams(), { transformResponse: (data) => JSON.parse(data).map(teamPreviewTransformer) diff --git a/src/frontend/src/apis/transformers/teams.transformers.ts b/src/frontend/src/apis/transformers/teams.transformers.ts index 9c033d252c..1cfb0be051 100644 --- a/src/frontend/src/apis/transformers/teams.transformers.ts +++ b/src/frontend/src/apis/transformers/teams.transformers.ts @@ -17,6 +17,7 @@ export const teamTransformer = (team: Team): Team => { export const teamPreviewTransformer = (team: TeamPreview): TeamPreview => { return { + dateArchived: team.dateArchived ? new Date(team.dateArchived) : undefined, ...team }; }; diff --git a/src/frontend/src/components/TeamsDropdown.tsx b/src/frontend/src/components/TeamsDropdown.tsx index 02a87deaea..fafabfa092 100644 --- a/src/frontend/src/components/TeamsDropdown.tsx +++ b/src/frontend/src/components/TeamsDropdown.tsx @@ -1,7 +1,7 @@ import { Box, FormControl, FormLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material'; import { Control, Controller } from 'react-hook-form'; import LoadingIndicator from './LoadingIndicator'; -import { useAllTeams } from '../hooks/teams.hooks'; +import { useAllTeamPreviews } from '../hooks/teams.hooks'; interface TeamDropdownProps { control: Control; @@ -10,7 +10,7 @@ interface TeamDropdownProps { } const TeamDropdown = ({ control, name, multiselect = false }: TeamDropdownProps) => { - const { isLoading, data: teams } = useAllTeams(); + const { isLoading, data: teams } = useAllTeamPreviews(); if (isLoading || !teams) return ; return ( diff --git a/src/frontend/src/hooks/teams.hooks.ts b/src/frontend/src/hooks/teams.hooks.ts index a68bbf138c..431c4a3cff 100644 --- a/src/frontend/src/hooks/teams.hooks.ts +++ b/src/frontend/src/hooks/teams.hooks.ts @@ -4,7 +4,7 @@ */ import { useQuery, useQueryClient, useMutation } from 'react-query'; -import { Team, TeamPreview } from 'shared'; +import { Team, TeamBase, TeamPreview } from 'shared'; import { getAllTeams, getSingleTeam, @@ -18,7 +18,8 @@ import { getAllArchivedTeams, getUsersTeams, setTeamSlackId, - getMyTeamAsHead + getMyTeamAsHead, + getAllTeamPreviews } from '../apis/teams.api'; export interface CreateTeamPayload { @@ -29,6 +30,13 @@ export interface CreateTeamPayload { isFinanceTeam: boolean; } +export const useAllTeamPreviews = () => { + return useQuery(['teams'], async () => { + const { data } = await getAllTeamPreviews(); + return data; + }); +}; + export const useAllTeams = () => { return useQuery(['teams', false], async () => { const { data } = await getAllTeams(); diff --git a/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx b/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx index 181e386a58..38cd5ab4d2 100644 --- a/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx +++ b/src/frontend/src/pages/AdminToolsPage/AdminToolsAttendeeDesignReviewInfo.tsx @@ -1,7 +1,6 @@ import React, { useState } from 'react'; import { TextField, FormControl, FormLabel, TableCell, TableRow, Grid, Typography } from '@mui/material'; import NERTable from '../../components/NERTable'; -import { useAllTeams } from '../../hooks/teams.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { fullNamePipe } from '../../utils/pipes'; @@ -12,13 +11,10 @@ import { EventStatus } from 'shared'; const AdminToolsAttendeeDesignReviewInfo: React.FC = () => { const [searchQuery, setSearchQuery] = useState(''); - const { data: allTeams, isLoading: teamsIsLoading, isError: teamsIsError, error: teamsError } = useAllTeams(); const { data: allMembers, isLoading: usersIsLoading, isError: usersIsError, error: usersError } = useAllMembers(); const { data: allEvents, isLoading: eventsIsLoading, isError: eventsIsError, error: eventsError } = useAllEvents(); - if (!allTeams || teamsIsLoading || !allMembers || usersIsLoading || !allEvents || eventsIsLoading) - return ; - if (teamsIsError) return ; + if (!allMembers || usersIsLoading || !allEvents || eventsIsLoading) return ; if (usersIsError) return ; if (eventsIsError) return ; diff --git a/src/frontend/src/pages/AdminToolsPage/AdminToolsSlackIds.tsx b/src/frontend/src/pages/AdminToolsPage/AdminToolsSlackIds.tsx index 4c287b0496..e8b5695c71 100644 --- a/src/frontend/src/pages/AdminToolsPage/AdminToolsSlackIds.tsx +++ b/src/frontend/src/pages/AdminToolsPage/AdminToolsSlackIds.tsx @@ -14,9 +14,9 @@ import { } from '../../hooks/organizations.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; -import { Organization, TeamPreview } from 'shared'; +import { Organization, TeamBase } from 'shared'; import HelpIcon from '@mui/icons-material/Help'; -import { useAllTeams } from '../../hooks/teams.hooks'; +import { useAllTeamPreviews } from '../../hooks/teams.hooks'; import NERTable from '../../components/NERTable'; import EditTeamSlackIdFormModal from './TeamConfig/EditTeamSlackIdFormModal'; @@ -40,8 +40,13 @@ const AdminToolsSlackIdsView: React.FC = ({ orga const [sponsorshipChannelId, setSponsorshipChannelId] = useState( organization.sponsorshipNotificationsSlackChannelId ?? '' ); - const { data: allTeams, isLoading: allTeamsIsLoading, isError: allTeamsIsError, error: allTeamsError } = useAllTeams(); - const [clickedTeam, setClickedTeam] = useState(); + const { + data: allTeams, + isLoading: allTeamsIsLoading, + isError: allTeamsIsError, + error: allTeamsError + } = useAllTeamPreviews(); + const [clickedTeam, setClickedTeam] = useState(); if (!allTeams || allTeamsIsLoading) return ; diff --git a/src/frontend/src/pages/AdminToolsPage/TeamConfig/EditTeamSlackIdFormModal.tsx b/src/frontend/src/pages/AdminToolsPage/TeamConfig/EditTeamSlackIdFormModal.tsx index ab3f2bc57b..ec454ba3c1 100644 --- a/src/frontend/src/pages/AdminToolsPage/TeamConfig/EditTeamSlackIdFormModal.tsx +++ b/src/frontend/src/pages/AdminToolsPage/TeamConfig/EditTeamSlackIdFormModal.tsx @@ -4,7 +4,7 @@ import { FormControl, FormLabel, FormHelperText } from '@mui/material'; import ReactHookTextField from '../../../components/ReactHookTextField'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; -import { TeamPreview } from 'shared'; +import { TeamBase } from 'shared'; import { useEffect } from 'react'; import { useEditTeamSlackId } from '../../../hooks/teams.hooks'; import LoadingIndicator from '../../../components/LoadingIndicator'; @@ -13,7 +13,7 @@ import { useToast } from '../../../hooks/toasts.hooks'; interface EditTeamSlackIdFormModalProps { open: boolean; handleClose: () => void; - team: TeamPreview; + team: TeamBase; } const schema = yup.object().shape({ diff --git a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx index b49e524698..298819666b 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx @@ -23,7 +23,7 @@ import { DayOfWeek, EventDocumentUploadArgs, WbsElementStatus, wbsNamePipe, Even import { useToast } from '../../../hooks/toasts.hooks'; import { useAllUsers, useCurrentUser } from '../../../hooks/users.hooks'; import { useAllWorkPackagesPreview } from '../../../hooks/work-packages.hooks'; -import { useAllTeams } from '../../../hooks/teams.hooks'; +import { useAllTeamPreviews } from '../../../hooks/teams.hooks'; import { userToAutocompleteOption } from '../../../utils/teams.utils'; import ErrorPage from '../../ErrorPage'; import NERFormModal from '../../../components/NERFormModal'; @@ -156,7 +156,7 @@ const EventModal: React.FC = ({ error: workPackagesErrorMsg, data: allWorkPackages } = useAllWorkPackagesPreview(); - const { isLoading: teamsLoading, isError: teamsError, error: teamsErrorMsg, data: teams } = useAllTeams(); + const { isLoading: teamsLoading, isError: teamsError, error: teamsErrorMsg, data: teams } = useAllTeamPreviews(); const { isError: teamTypesError, error: teamTypesErrorMsg, data: teamTypes } = useAllTeamTypes(); const defaultFormData = useMemo( diff --git a/src/frontend/src/pages/CalendarPage/FilterModal.tsx b/src/frontend/src/pages/CalendarPage/FilterModal.tsx index 95fb88500e..af5faae1ea 100644 --- a/src/frontend/src/pages/CalendarPage/FilterModal.tsx +++ b/src/frontend/src/pages/CalendarPage/FilterModal.tsx @@ -3,7 +3,8 @@ import { Autocomplete, Box, Button, Checkbox, TextField, Typography } from '@mui import NERModal from '../../components/NERModal'; import PeopleIcon from '@mui/icons-material/People'; import { useAllUsers, useCurrentUser } from '../../hooks/users.hooks'; -import { useAllTeams } from '../../hooks/teams.hooks'; +import { useAllTeamPreviews, useAllTeams } from '../../hooks/teams.hooks'; +import ErrorPage from '../ErrorPage'; export interface FilterArgs { memberIds: string[]; @@ -141,7 +142,10 @@ const FilterModal: React.FC = ({ const TeamDropdown = () => { const teamIds = filterValues?.teamIds ?? []; - const { data: allTeams } = useAllTeams(); + const { data: allTeams, isError: allTeamsIsError, error: allTeamsError } = useAllTeams(); + + if (allTeamsIsError) ; + const teamList = allTeams ?.filter((team) => { diff --git a/src/frontend/src/pages/ProjectTemplateForm/ProjectTemplateFormView.tsx b/src/frontend/src/pages/ProjectTemplateForm/ProjectTemplateFormView.tsx index f2043c5b33..9b3e609a7c 100644 --- a/src/frontend/src/pages/ProjectTemplateForm/ProjectTemplateFormView.tsx +++ b/src/frontend/src/pages/ProjectTemplateForm/ProjectTemplateFormView.tsx @@ -15,7 +15,7 @@ import React from 'react'; import ProjectTemplateWorkPackageSection from './ProjectTemplateWorkPackageSection'; import { generateUUID } from '../../utils/form'; import { AttachMoney } from '@mui/icons-material'; -import { useAllTeams } from '../../hooks/teams.hooks'; +import { useAllTeamPreviews, useAllTeams } from '../../hooks/teams.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { WorkPackageTemplateApiInputs } from 'shared'; @@ -59,7 +59,7 @@ const ProjectTemplateFormView: React.FC = ({ const history = useHistory(); - const { data: teams, isLoading: teamsLoading, isError: teamsIsError, error: teamsError } = useAllTeams(); + const { data: teams, isLoading: teamsLoading, isError: teamsIsError, error: teamsError } = useAllTeamPreviews(); const pageTitle = defaultValues ? 'Edit Project Template' : 'Create Project Template'; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index da15bfffa1..ea9c4d8ef1 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -137,6 +137,7 @@ const changeRequestRequestReviewer = (id: string) => changeRequestsById(id) + '/ /**************** Teams Endpoints ****************/ const teams = () => `${API_URL}/teams`; +const teamPreviews = () => `${API_URL}/teams/previews/`; const teamsById = (id: string) => `${teams()}/${id}`; const teamsDelete = (id: string) => `${teamsById(id)}/delete`; const teamsSetMembers = (id: string) => `${teamsById(id)}/set-members`; @@ -591,6 +592,7 @@ export const apiUrls = { approvedChangeRequests, teams, + teamPreviews, teamsById, teamsDelete, teamsSetMembers, diff --git a/src/shared/src/types/team-types.ts b/src/shared/src/types/team-types.ts index 88eb31190e..d589f162de 100644 --- a/src/shared/src/types/team-types.ts +++ b/src/shared/src/types/team-types.ts @@ -7,18 +7,22 @@ import { TeamType } from './design-review-types.js'; import { ProjectGantt } from './project-types.js'; import { User } from './user-types.js'; -export interface Team { +export interface TeamBase { teamId: string; teamName: string; - head: User; slackId: string; description: string; + dateArchived?: Date; + teamType?: TeamType; +} + +export interface TeamPreview extends TeamBase { members: User[]; - projects: ProjectGantt[]; + head: User; leads: User[]; userArchived?: User; - dateArchived?: Date; - teamType?: TeamType; } -export type TeamPreview = Pick; +export interface Team extends TeamPreview { + projects: ProjectGantt[]; +} From 07f22a7756c782f8287413d0ea231b5055b03c03 Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Tue, 20 Jan 2026 09:09:13 -0500 Subject: [PATCH 469/477] refactor schedule slots to not store recurrances --- .../src/controllers/calendar.controllers.ts | 35 +- .../20260111001906_calendar/migration.sql | 148 +-- src/backend/src/prisma/schema.prisma | 15 +- src/backend/src/prisma/seed.ts | 67 +- src/backend/src/routes/calendar.routes.ts | 26 +- src/backend/src/services/calendar.services.ts | 342 +++--- .../src/services/notifications.services.ts | 5 +- .../src/transformers/calendar.transformer.ts | 17 +- src/backend/src/utils/calendar.utils.ts | 114 +- src/backend/src/utils/errors.utils.ts | 3 +- .../src/utils/google-integration.utils.ts | 124 +- src/backend/src/utils/slack.utils.ts | 6 +- src/backend/tests/test-utils.ts | 7 +- src/backend/tests/unit/calendar.test.ts | 94 +- src/frontend/src/apis/calendar.api.ts | 10 + .../apis/transformers/calendar.transformer.ts | 11 +- src/frontend/src/hooks/calendar.hooks.ts | 27 +- .../CalendarPage/AvailabilityScheduleView.tsx | 2 +- .../src/pages/CalendarPage/CalendarTab.tsx | 28 +- .../Components/EditEventModal.tsx | 2 +- .../Components/EventAvailabilityPage.tsx | 5 +- .../CalendarPage/Components/EventModal.tsx | 1052 ++++++++++------- .../pages/CalendarPage/EventClickPopup.tsx | 31 +- .../pages/CalendarPage/NewCalendarPage.tsx | 20 +- .../pages/HomePage/components/EventCard.tsx | 2 +- .../components/UpcomingDesignReviews.tsx | 2 +- .../UserScheduleSettingsView.tsx | 6 +- .../test-data/design-reviews.stub.ts | 26 +- src/frontend/src/utils/calendar.utils.ts | 79 +- src/frontend/src/utils/datetime.utils.ts | 97 +- src/frontend/src/utils/urls.ts | 3 + src/shared/src/types/calendar-types.ts | 17 +- 32 files changed, 1204 insertions(+), 1219 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 16758d2b64..3a9c29bb89 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -274,6 +274,7 @@ export default class CalendarController { machineryIds, workPackageIds, scheduleSlot, + initialDateScheduled, questionDocumentLink, location, zoomLink, @@ -281,12 +282,13 @@ export default class CalendarController { } = req.body; const parsedScheduleSlot = scheduleSlot.map((slot: any) => ({ - ...slot, startTime: slot.startTime ? new Date(slot.startTime) : undefined, endTime: slot.endTime ? new Date(slot.endTime) : undefined, - initialDateScheduled: new Date(slot.initialDateScheduled) + allDay: slot.allDay })); + const parsedInitialDateScheduled = initialDateScheduled ? new Date(initialDateScheduled) : undefined; + const event = await CalendarService.createEvent( req.currentUser, title, @@ -299,6 +301,7 @@ export default class CalendarController { machineryIds, workPackageIds, parsedScheduleSlot, + parsedInitialDateScheduled, teamTypeId, questionDocumentLink, location, @@ -326,20 +329,12 @@ export default class CalendarController { machineryIds, workPackageIds, documents, - scheduleSlot, questionDocumentLink, location, zoomLink, description } = req.body; - const parsedScheduleSlot = scheduleSlot.map((slot: any) => ({ - ...slot, - startTime: slot.startTime ? new Date(slot.startTime) : undefined, - endTime: slot.endTime ? new Date(slot.endTime) : undefined, - initialDateScheduled: new Date(slot.initialDateScheduled) - })); - const event = await CalendarService.editEvent( req.currentUser, eventId, @@ -353,7 +348,6 @@ export default class CalendarController { machineryIds, workPackageIds, documents, - parsedScheduleSlot, teamTypeId, questionDocumentLink, location, @@ -366,6 +360,25 @@ export default class CalendarController { } } + static async editScheduleSlot(req: Request, res: Response, next: NextFunction) { + try { + const { scheduleSlotId } = req.params as Record; + const { startTime, endTime, allDay } = req.body; + + const event = await CalendarService.editScheduleSlot( + req.currentUser, + scheduleSlotId, + new Date(startTime), + new Date(endTime), + allDay, + req.organization + ); + res.status(200).json(event); + } catch (error: unknown) { + next(error); + } + } + static async uploadDocument(req: Request, res: Response, next: NextFunction) { try { const { file } = req; diff --git a/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql b/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql index 347baf8611..d8bbfc11b1 100644 --- a/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql @@ -44,13 +44,10 @@ CREATE TABLE "public"."Shop_Machinery" ( -- CreateTable CREATE TABLE "public"."Schedule_Slot" ( "scheduleSlotId" TEXT NOT NULL, - "days" "public"."DayOfWeek"[], - "startTime" TIMESTAMP(3), - "endTime" TIMESTAMP(3), - "recurrenceNumber" INTEGER NOT NULL, - "initialDateScheduled" DATE NOT NULL, - "endDate" DATE NOT NULL, + "startTime" TIMESTAMP(3) NOT NULL, + "endTime" TIMESTAMP(3) NOT NULL, "allDay" BOOLEAN NOT NULL DEFAULT false, + "eventId" TEXT NOT NULL, CONSTRAINT "Schedule_Slot_pkey" PRIMARY KEY ("scheduleSlotId") ); @@ -82,6 +79,7 @@ CREATE TABLE "public"."Event" ( "approvalRequiredFromUserId" TEXT, "location" TEXT, "zoomLink" TEXT, + "initialDateScheduled" DATE NOT NULL, "questionDocumentLink" TEXT, "description" TEXT, "teamTypeId" TEXT, @@ -139,14 +137,6 @@ CREATE TYPE "public"."Event_Status" AS ENUM ('UNCONFIRMED', 'CONFIRMED', 'SCHEDU -- AlterTable ALTER TABLE "public"."Event" ADD COLUMN "status" "public"."Event_Status" NOT NULL; --- CreateTable -CREATE TABLE "public"."_EventToSchedule_Slot" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL, - - CONSTRAINT "_EventToSchedule_Slot_AB_pkey" PRIMARY KEY ("A","B") -); - -- CreateTable CREATE TABLE "public"."_affiliatedTeam" ( "A" TEXT NOT NULL, @@ -277,10 +267,10 @@ CREATE INDEX "Shop_Machinery_machineryId_idx" ON "public"."Shop_Machinery"("mach CREATE UNIQUE INDEX "Shop_Machinery_shopId_machineryId_key" ON "public"."Shop_Machinery"("shopId", "machineryId"); -- CreateIndex -CREATE INDEX "Schedule_Slot_initialDateScheduled_endDate_idx" ON "public"."Schedule_Slot"("initialDateScheduled", "endDate"); +CREATE INDEX "Schedule_Slot_endTime_idx" ON "public"."Schedule_Slot"("endTime"); -- CreateIndex -CREATE INDEX "_EventToSchedule_Slot_B_index" ON "public"."_EventToSchedule_Slot"("B"); +CREATE INDEX "Schedule_Slot_startTime_idx" ON "public"."Schedule_Slot"("startTime"); -- CreateIndex CREATE INDEX "_affiliatedTeam_B_index" ON "public"."_affiliatedTeam"("B"); @@ -355,10 +345,7 @@ ALTER TABLE "public"."Event_Type" ADD CONSTRAINT "Event_Type_userDeletedId_fkey" ALTER TABLE "public"."Event_Type" ADD CONSTRAINT "Event_Type_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "public"."Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "public"."_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "public"."_EventToSchedule_Slot" ADD CONSTRAINT "_EventToSchedule_Slot_B_fkey" FOREIGN KEY ("B") REFERENCES "public"."Schedule_Slot"("scheduleSlotId") ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE "public"."Schedule_Slot" ADD CONSTRAINT "Schedule_Slot_EventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("eventId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "public"."_affiliatedTeam" ADD CONSTRAINT "_affiliatedTeam_A_fkey" FOREIGN KEY ("A") REFERENCES "public"."Event"("eventId") ON DELETE CASCADE ON UPDATE CASCADE; @@ -504,6 +491,7 @@ INSERT INTO "public"."Event" ( "zoomLink", "questionDocumentLink", "description", + "initialDateScheduled", "status", "teamTypeId", "calendarEventIds" @@ -526,6 +514,7 @@ SELECT dr."zoomLink", dr."docTemplateLink", -- questionDocument uses docTemplateLink NULL, -- description (not in Design_Review) + dr."initialDateScheduled", dr."status"::"text"::"public"."Event_Status", dr."teamTypeId", CASE WHEN dr."calendarEventId" IS NOT NULL THEN ARRAY[dr."calendarEventId"] ELSE ARRAY[]::TEXT[] END @@ -534,25 +523,12 @@ JOIN "public"."WBS_Element" w ON dr."wbsElementId" = w."wbsElementId"; -- Create Schedule_Slot records for Design Reviews -- This creates one slot per time per design review --- Design Reviews are non-recurring, so endDate = dateScheduled CREATE TEMP TABLE temp_dr_schedule_slots AS SELECT dr."designReviewId" as event_id, gen_random_uuid() as slot_id, - ARRAY[CASE EXTRACT(DOW FROM dr."dateScheduled") - WHEN 0 THEN 'SUNDAY'::public."DayOfWeek" - WHEN 1 THEN 'MONDAY'::public."DayOfWeek" - WHEN 2 THEN 'TUESDAY'::public."DayOfWeek" - WHEN 3 THEN 'WEDNESDAY'::public."DayOfWeek" - WHEN 4 THEN 'THURSDAY'::public."DayOfWeek" - WHEN 5 THEN 'FRIDAY'::public."DayOfWeek" - WHEN 6 THEN 'SATURDAY'::public."DayOfWeek" - END] as days, dr."dateScheduled" + ((10 + time_slot) * INTERVAL '1 hour') as start_time, dr."dateScheduled" + ((11 + time_slot) * INTERVAL '1 hour') as end_time, - 0 as recurrence_number, - dr."initialDateScheduled" as initial_date, - dr."dateScheduled" as end_date, false as all_day FROM "public"."Design_Review" dr CROSS JOIN LATERAL unnest(dr."meetingTimes") AS time_slot; @@ -560,28 +536,17 @@ CROSS JOIN LATERAL unnest(dr."meetingTimes") AS time_slot; -- Insert schedule slots from temp table INSERT INTO "public"."Schedule_Slot" ( "scheduleSlotId", - "days", "startTime", "endTime", - "recurrenceNumber", - "initialDateScheduled", - "endDate", - "allDay" + "allDay", + "eventId" ) SELECT slot_id, - days, start_time, end_time, - recurrence_number, - initial_date, - end_date, - all_day -FROM temp_dr_schedule_slots; - --- Link Schedule_Slots to Events using the temp table -INSERT INTO "public"."_EventToSchedule_Slot" ("A", "B") -SELECT event_id, slot_id + all_day, + event_id FROM temp_dr_schedule_slots; -- Drop temp table @@ -614,92 +579,7 @@ SELECT dr."designReviewId", wp."workPackageId" FROM "public"."Design_Review" dr JOIN "public"."Work_Package" wp ON dr."wbsElementId" = wp."wbsElementId"; --- Migrate Meeting records to Event table -INSERT INTO "public"."Event" ( - "eventId", - "dateCreated", - "title", - "userCreatedId", - "eventTypeId", - "approved", - "status" -) -SELECT - m."meetingId", - NOW(), - m."title", - t."headId", -- Use the team head as the creator - (SELECT et."eventTypeId" - FROM "public"."Event_Type" et - WHERE et."name" = 'Meeting' - AND et."organizationId" = t."organizationId" - LIMIT 1), - 'NO_CONFLICT'::public."Conflict_Status" , - 'UNCONFIRMED'::public."Event_Status" -FROM "public"."Meeting" m -JOIN "public"."Team" t ON m."teamId" = t."teamId"; - --- Create Schedule_Slot records for Meetings --- This creates one slot per time per meeting -CREATE TEMP TABLE temp_meeting_schedule_slots AS -SELECT - m."meetingId" as event_id, - gen_random_uuid() as slot_id, - ARRAY[CASE EXTRACT(DOW FROM m."dateSet") - WHEN 0 THEN 'SUNDAY'::public."DayOfWeek" - WHEN 1 THEN 'MONDAY'::public."DayOfWeek" - WHEN 2 THEN 'TUESDAY'::public."DayOfWeek" - WHEN 3 THEN 'WEDNESDAY'::public."DayOfWeek" - WHEN 4 THEN 'THURSDAY'::public."DayOfWeek" - WHEN 5 THEN 'FRIDAY'::public."DayOfWeek" - WHEN 6 THEN 'SATURDAY'::public."DayOfWeek" - END] as days, - m."dateSet" + ((10 + time_slot) * INTERVAL '1 hour') as start_time, - m."dateSet" + ((11 + time_slot) * INTERVAL '1 hour') as end_time, - CASE WHEN m."recurringInterval" > 0 THEN m."recurringInterval" ELSE 0 END as recurrence_number, - m."dateSet"::DATE as initial_date, - CASE - WHEN m."recurringInterval" > 0 THEN (m."dateSet" + INTERVAL '1 year')::DATE - ELSE m."dateSet"::DATE - END as end_date, - false as all_day -FROM "public"."Meeting" m -CROSS JOIN LATERAL unnest(m."meetingTimes") AS time_slot; - --- Insert schedule slots from temp table -INSERT INTO "public"."Schedule_Slot" ( - "scheduleSlotId", - "days", - "startTime", - "endTime", - "recurrenceNumber", - "initialDateScheduled", - "endDate", - "allDay" -) -SELECT - slot_id, - days, - start_time, - end_time, - recurrence_number, - initial_date, - end_date, - all_day -FROM temp_meeting_schedule_slots; - --- Link Schedule_Slots to Events using the temp table -INSERT INTO "public"."_EventToSchedule_Slot" ("A", "B") -SELECT event_id, slot_id -FROM temp_meeting_schedule_slots; - --- Drop temp table -DROP TABLE temp_meeting_schedule_slots; - --- Link Meetings to Teams -INSERT INTO "public"."_affiliatedTeam" ("A", "B") -SELECT m."meetingId", m."teamId" -FROM "public"."Meeting" m; +-- Skip Meetings migration because there are no existing meetings ALTER TABLE "Message_Info" ADD COLUMN "eventId" TEXT; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 363e2723bd..2a35b18cc1 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -1024,16 +1024,14 @@ enum DayOfWeek { model Schedule_Slot { scheduleSlotId String @id @default(uuid()) - days DayOfWeek[] - startTime DateTime? // time of day (just use a DateTime, ignore the date portion) - endTime DateTime? // time of day (just use a DateTime, ignore the date portion) - recurrenceNumber Int - initialDateScheduled DateTime @db.Date - endDate DateTime @db.Date + startTime DateTime + endTime DateTime allDay Boolean @default(false) - ScheduledEvents Event[] + eventId String + event Event @relation(fields: [eventId], references: [eventId]) - @@index([initialDateScheduled, endDate]) + @@index([endTime]) + @@index([startTime]) } enum Conflict_Status { @@ -1088,6 +1086,7 @@ model Event { workPackages Work_Package[] documents Document[] status Event_Status + initialDateScheduled DateTime? questionDocumentLink String? description String? notificationSlackThreads Message_Info[] diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 28d2eeee50..7831bccd64 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3245,14 +3245,12 @@ const performSeed: () => Promise = async () => { [], [ { - days: [DayOfWeek.MONDAY], - startTime: new Date('2025-10-21T10:00:00.000Z'), - endTime: new Date('2025-10-21T11:00:00.000Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), + startTime: new Date(), + endTime: new Date(new Date().getTime() + 60 * 60 * 1000), allDay: false } ], + undefined, mechanical.teamTypeId, undefined, 'Conference Room A', @@ -3273,14 +3271,27 @@ const performSeed: () => Promise = async () => { [], [ { - days: [DayOfWeek.MONDAY], - startTime: new Date('2025-12-21T10:00:00.000Z'), - endTime: new Date('2025-12-21T11:00:00.000Z'), - recurrenceNumber: 2, - initialDateScheduled: new Date('2025-12-21T00:00:00.000Z'), + startTime: new Date(new Date().getTime() + 105 * 60 * 60 * 1000), + endTime: new Date(new Date().getTime() + 106 * 60 * 60 * 1000), + allDay: false + }, + { + startTime: new Date(new Date().getTime() + 24 * 60 * 60 * 1000), + endTime: new Date(new Date().getTime() + 25 * 60 * 60 * 1000), + allDay: false + }, + { + startTime: new Date(new Date().getTime() + 50 * 60 * 60 * 1000), + endTime: new Date(new Date().getTime() + 51 * 60 * 60 * 1000), + allDay: false + }, + { + startTime: new Date(new Date().getTime() + 85 * 60 * 60 * 1000), + endTime: new Date(new Date().getTime() + 87 * 60 * 60 * 1000), allDay: false } ], + undefined, mechanical.teamTypeId, undefined, 'Conference Room A', @@ -3301,22 +3312,12 @@ const performSeed: () => Promise = async () => { [], [ { - days: [DayOfWeek.MONDAY], startTime: new Date('2025-10-21T10:00:00.000Z'), endTime: new Date('2025-10-21T11:00:00.000Z'), - recurrenceNumber: 2, - initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), - allDay: false - }, - { - days: [DayOfWeek.WEDNESDAY], - startTime: new Date('2025-10-21T10:00:00.000Z'), - endTime: new Date('2025-10-21T11:00:00.000Z'), - recurrenceNumber: 2, - initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), allDay: false } ], + undefined, mechanical.teamTypeId, undefined, 'Conference Room A', @@ -3337,14 +3338,12 @@ const performSeed: () => Promise = async () => { [], [ { - days: [DayOfWeek.MONDAY], startTime: new Date('2025-10-21T10:00:00.000Z'), endTime: new Date('2025-10-21T11:00:00.000Z'), - recurrenceNumber: 2, - initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), allDay: false } ], + undefined, mechanical.teamTypeId, undefined, 'Conference Room A', @@ -3365,14 +3364,12 @@ const performSeed: () => Promise = async () => { [], [ { - days: [DayOfWeek.MONDAY], startTime: new Date('2025-10-21T10:00:00.000Z'), endTime: new Date('2025-10-21T11:00:00.000Z'), - recurrenceNumber: 7, - initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), allDay: false } ], + undefined, mechanical.teamTypeId, undefined, 'Conference Room A', @@ -3393,14 +3390,12 @@ const performSeed: () => Promise = async () => { [], [ { - days: [DayOfWeek.MONDAY], startTime: new Date('2025-10-21T10:00:00.000Z'), endTime: new Date('2025-10-21T11:00:00.000Z'), - recurrenceNumber: 2, - initialDateScheduled: new Date('2025-10-21T00:00:00.000Z'), allDay: false } ], + undefined, mechanical.teamTypeId, undefined, 'Conference Room A', @@ -3421,14 +3416,12 @@ const performSeed: () => Promise = async () => { [workPackage1.id], [ { - days: [DayOfWeek.TUESDAY], startTime: new Date('2025-10-22T14:00:00.000Z'), endTime: new Date('2025-10-22T16:00:00.000Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-22T00:00:00.000Z'), allDay: false } ], + undefined, software.teamTypeId, 'https://docs.google.com/document/d/2_example', 'Conference Room B', @@ -3449,14 +3442,12 @@ const performSeed: () => Promise = async () => { [workPackage3.id], [ { - days: [DayOfWeek.WEDNESDAY], startTime: new Date('2025-10-23T09:00:00.000Z'), endTime: new Date('2025-10-23T12:00:00.000Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-23T00:00:00.000Z'), allDay: false } ], + undefined, electrical.teamTypeId, 'https://docs.google.com/document/d/3_example', undefined, @@ -3477,14 +3468,12 @@ const performSeed: () => Promise = async () => { [], [ { - days: [DayOfWeek.THURSDAY], startTime: new Date('2025-10-24T13:00:00.000Z'), endTime: new Date('2025-10-24T17:00:00.000Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-24T00:00:00.000Z'), allDay: false } ], + undefined, mechanical.teamTypeId, undefined, undefined, diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index ffec8bb695..8c187848a8 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -114,13 +114,10 @@ calendarRouter.post( body('workPackageIds.*').isString(), body('questionDocumentLink').optional().isString(), body('description').optional().isString(), + isDate(body('initialDateScheduled')), body('scheduleSlot').isArray(), - body('scheduleSlot.*.days').isArray(), - isDayOfWeek(body('scheduleSlot.*.days.*')), - isDate(body('scheduleSlot.*.startTime')).optional(), - isDate(body('scheduleSlot.*.endTime')).optional(), - intMinZero(body('scheduleSlot.*.recurrenceNumber')), - isDate(body('scheduleSlot.*.initialDateScheduled')), + isDate(body('scheduleSlot.*.startTime')), + isDate(body('scheduleSlot.*.endTime')), body('scheduleSlot.*.allDay').isBoolean(), validateInputs, CalendarController.createEvent @@ -150,18 +147,19 @@ calendarRouter.post( nonEmptyString(body('documents.*.googleFileId')), body('questionDocumentLink').optional().isString(), body('description').optional().isString(), - body('scheduleSlot').isArray(), - body('scheduleSlot.*.days').isArray(), - isDayOfWeek(body('scheduleSlot.*.days.*')), - isDate(body('scheduleSlot.*.startTime')).optional(), - isDate(body('scheduleSlot.*.endTime')).optional(), - intMinZero(body('scheduleSlot.*.recurrenceNumber')), - isDate(body('scheduleSlot.*.initialDateScheduled')), - body('scheduleSlot.*.allDay').isBoolean(), validateInputs, CalendarController.editEvent ); +calendarRouter.post( + '/event/:eventId/schedule-slot/:scheduleSlotId/edit', + isDate(body('startTime')), + isDate(body('endTime')), + body('allDay').isBoolean(), + validateInputs, + CalendarController.editScheduleSlot +); + calendarRouter.get('/document/:fileId', CalendarController.downloadDocument); calendarRouter.post( diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index b9a5f52a2e..efbfb92408 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -265,7 +265,8 @@ export default class CalendarService { shopIds: string[], machineryIds: string[], workPackageIds: string[], - scheduleSlot: ScheduleSlotCreateArgs[], + scheduleSlots: ScheduleSlotCreateArgs[], + initialDateScheduled: Date | undefined, teamTypeId?: string, questionDocumentLink?: string, location?: string, @@ -299,7 +300,8 @@ export default class CalendarService { machineryIds, workPackageIds, documents: [], - scheduleSlot, + scheduleSlots, + initialDateScheduled, teamTypeId, location, zoomLink, @@ -416,13 +418,8 @@ export default class CalendarService { } } - // Check for conflicts - const { hasConflict, conflictingEvent } = await checkEventConflicts(scheduleSlot, organization, location, undefined); - - const computeEndDate = (initial: Date, recurrenceNumber: number) => { - const weeks = Math.max(1, recurrenceNumber ?? 0); - return new Date(initial.getTime() + weeks * 7 * 24 * 60 * 60 * 1000); - }; + // Check for conflicts using expanded slots + const { hasConflict, conflictingEvent } = await checkEventConflicts(scheduleSlots, organization, location, undefined); const duplicate = await prisma.event.findFirst({ where: { @@ -462,16 +459,13 @@ export default class CalendarService { connect: workPackageIds.map((workPackageId) => ({ workPackageId })) }, scheduledTimes: { - create: scheduleSlot.map((s) => ({ - days: s.days, + create: scheduleSlots.map((s) => ({ startTime: s.startTime ?? null, endTime: s.endTime ?? null, - recurrenceNumber: s.recurrenceNumber, - initialDateScheduled: s.initialDateScheduled, - endDate: computeEndDate(s.initialDateScheduled, s.recurrenceNumber), allDay: s.allDay })) }, + initialDateScheduled, status: foundEventType.requiresConfirmation ? Event_Status.UNCONFIRMED : Event_Status.CONFIRMED, approved: hasConflict ? Conflict_Status.PENDING : Conflict_Status.NO_CONFLICT, approvalRequiredFromUserId: hasConflict ? conflictingEvent?.userCreated.userId : null, @@ -580,7 +574,7 @@ export default class CalendarService { } /** - * Edits an event. + * Edits an event (excluding schedule slots - use editScheduleSlot for that). * * @param submitter The user submitting the request, who must be an admin. * @param eventId The id of the event to edit. @@ -595,7 +589,6 @@ export default class CalendarService { * @param machineryIds An array of machinery associated with the event. * @param workPackageIds An array of work packages associated with the event. * @param documents An array of documents associated with the event. - * @param scheduleSlots An array of schedule slots associated with the event. * @param questionDocumentLink The link to the question document. * @param location Location of the event. * @param zoomLink Zoom Link if the event is online. @@ -619,7 +612,6 @@ export default class CalendarService { machineryIds: string[], workPackageIds: string[], documents: EventDocumentCreateArgs[], - scheduleSlot: ScheduleSlotCreateArgs[], teamTypeId?: string, questionDocumentLink?: string, location?: string, @@ -643,22 +635,8 @@ export default class CalendarService { if (!foundEventType) throw new NotFoundException('Event Type', eventTypeId); if (foundEventType.dateDeleted) throw new DeletedException('Event Type', eventTypeId); - // Validate event follows event type configuration - validateEventTypeConfiguration(foundEventType, { - requiredMemberIds, - optionalMemberIds, - teamIds, - shopIds, - machineryIds, - workPackageIds, - documents, - scheduleSlot, - teamTypeId, - location, - zoomLink, - questionDocumentLink, - description - }); + // Note: Schedule validation is removed since editEvent doesn't modify schedules + // Use editScheduleSlot to modify individual schedule slots // question document is required if the status is scheduled or done if (foundEventType.requiresConfirmation) { @@ -798,180 +776,53 @@ export default class CalendarService { } } - // Use transaction for the update - const updatedEvent = await prisma.$transaction(async (tx) => { - // Fetch existing schedule slots - const [existingSlots] = await Promise.all([ - tx.schedule_Slot.findMany({ - where: { ScheduledEvents: { some: { eventId } } }, - select: { - days: true, - startTime: true, - endTime: true, - recurrenceNumber: true, - initialDateScheduled: true, - allDay: true - } - }) - ]); - - // Checks if all schedule slots are the same (ie no changes) - const haveDifferentSlots = (a: typeof existingSlots, b: typeof scheduleSlot) => { - if (a.length !== b.length) return true; - return a.some((oldSlot, idx) => { - const newSlot = b[idx]; - return ( - oldSlot.days !== newSlot.days || - oldSlot.startTime !== newSlot.startTime || - oldSlot.endTime !== newSlot.endTime || - oldSlot.recurrenceNumber !== newSlot.recurrenceNumber || - oldSlot.initialDateScheduled !== newSlot.initialDateScheduled || - oldSlot.allDay !== newSlot.allDay - ); - }); - }; - - const computeEndDate = (initial: Date, recurrenceNumber: number) => { - const weeks = Math.max(1, recurrenceNumber ?? 0); - return new Date(initial.getTime() + weeks * 7 * 24 * 60 * 60 * 1000); - }; - - const scheduleChanged = haveDifferentSlots(existingSlots, scheduleSlot); - const locationChanged = foundEvent.location !== location; + // throw if a user isn't found, then build prisma queries for connecting userIds + const updatedRequiredMembers = getPrismaQueryUserIds(await getUsers(requiredMemberIds)); + const updatedOptionalMembers = getPrismaQueryUserIds(await getUsers(optionalMemberIds)); - let hasConflict = false; - let approverUserId: string | undefined; - - if (scheduleChanged || locationChanged) { - const { hasConflict: conflict, conflictingEvent } = await checkEventConflicts( - scheduleSlot, - organization, - location, - eventId - ); + let newStatus = status; - hasConflict = conflict; - approverUserId = conflictingEvent?.userCreated.userId; - } - - if (scheduleChanged) { - await tx.schedule_Slot.deleteMany({ - where: { ScheduledEvents: { some: { eventId } } } - }); - await Promise.all( - scheduleSlot.map((s) => - tx.schedule_Slot.create({ - data: { - days: s.days, - startTime: s.startTime ?? null, - endTime: s.endTime ?? null, - endDate: computeEndDate(s.initialDateScheduled, s.recurrenceNumber), - recurrenceNumber: s.recurrenceNumber, - initialDateScheduled: s.initialDateScheduled, - allDay: s.allDay, - ScheduledEvents: { connect: { eventId } } - } - }) - ) - ); - } - - let calendarEventIds = foundEvent.calendarEventIds || []; - - // If schedule changed, update Google Calendar events - if (scheduleChanged && process.env.NODE_ENV === 'production') { - try { - const allMemberIds = [...requiredMemberIds, ...optionalMemberIds]; - const isInPerson = !!location; - - // Get the newly created schedule slots - const updatedSlots = await tx.schedule_Slot.findMany({ - where: { ScheduledEvents: { some: { eventId } } } - }); - - calendarEventIds = await updateCalendarEvent( - process.env.GOOGLE_CALENDAR_ID!, - foundEvent.calendarEventIds || [], - allMemberIds, - updatedSlots, - isInPerson, - zoomLink ?? null, - location ?? null, - title - ); - } catch (error) { - console.error('Failed to update Google Calendar events:', error); - } - } - - // throw if a user isn't found, then build prisma queries for connecting userIds - const updatedRequiredMembers = getPrismaQueryUserIds(await getUsers(requiredMemberIds)); - const updatedOptionalMembers = getPrismaQueryUserIds(await getUsers(optionalMemberIds)); - - let newStatus = status; - - // If schedule or location changed and event type requires confirmation, reset to UNCONFIRMED - if ((scheduleChanged || locationChanged) && foundEventType.requiresConfirmation) { - newStatus = Event_Status.UNCONFIRMED; - } else { - // If all required members are confirmed, set the status to SCHEDULED - const allRequiredMembersConfirmed = updatedRequiredMembers.every((member) => - foundEvent.confirmedMembers.map((user: { userId: string }) => user.userId).includes(member.userId) - ); + // If all required members are confirmed, set the status to SCHEDULED + const allRequiredMembersConfirmed = updatedRequiredMembers.every((member) => + foundEvent.confirmedMembers.map((user: { userId: string }) => user.userId).includes(member.userId) + ); - if (status === Event_Status.CONFIRMED && allRequiredMembersConfirmed) { - newStatus = Event_Status.SCHEDULED; - } - } + if (status === Event_Status.CONFIRMED && allRequiredMembersConfirmed) { + newStatus = Event_Status.SCHEDULED; + } - // Update the event with new data - return await tx.event.update({ - where: { eventId }, - data: { - title, - eventTypeId, - requiredMembers: { - set: updatedRequiredMembers - }, - optionalMembers: { - set: updatedOptionalMembers - }, - teams: { - set: teamIds.map((teamId) => ({ teamId })) - }, - ...(teamTypeId !== undefined && { teamTypeId }), - status: newStatus, - shops: { - set: shopIds.map((shopId) => ({ shopId })) - }, - machinery: { - set: machineryIds.map((machineryId) => ({ machineryId })) - }, - workPackages: { - set: workPackageIds.map((workPackageId) => ({ workPackageId })) - }, - // If schedule/location changed and there's a conflict, set approved=false and track who needs to approve - // Otherwise keep existing approval state - approved: - scheduleChanged || locationChanged - ? hasConflict - ? Conflict_Status.PENDING - : Conflict_Status.NO_CONFLICT - : foundEvent.approved, - approvalRequiredFromUserId: - scheduleChanged || locationChanged - ? hasConflict - ? approverUserId - : null - : foundEvent.approvalRequiredFromUserId, - location, - zoomLink, - questionDocumentLink, - description, - calendarEventIds + // Update the event with new data (excluding schedule slots) + const updatedEvent = await prisma.event.update({ + where: { eventId }, + data: { + title, + eventTypeId, + requiredMembers: { + set: updatedRequiredMembers }, - ...getEventQueryArgs(organization.organizationId) - }); + optionalMembers: { + set: updatedOptionalMembers + }, + teams: { + set: teamIds.map((teamId) => ({ teamId })) + }, + ...(teamTypeId !== undefined && { teamTypeId }), + status: newStatus, + shops: { + set: shopIds.map((shopId) => ({ shopId })) + }, + machinery: { + set: machineryIds.map((machineryId) => ({ machineryId })) + }, + workPackages: { + set: workPackageIds.map((workPackageId) => ({ workPackageId })) + }, + location, + zoomLink, + questionDocumentLink, + description + }, + ...getEventQueryArgs(organization.organizationId) }); //set any deleted documents with a dateDeleted @@ -990,6 +841,93 @@ export default class CalendarService { return edittedEvent; } + /** + * Edits a specific schedule slot of an event. + * Used when a user wants to change the time/date of a single occurrence in a recurring event. + * + * @param submitter The user submitting the request. + * @param scheduleSlotId The id of the specific schedule slot to edit. + * @param startTime The new start time. + * @param endTime The new end time. + * @param allDay Whether this is an all-day event. + * @param organization The organization context. + * + * @returns The updated event. + * + * @throws NotFoundException If the event or schedule slot is not found. + * @throws AccessDeniedException If the user doesn't have permission to edit. + */ + static async editScheduleSlot( + submitter: User, + scheduleSlotId: string, + startTime: Date, + endTime: Date, + allDay: boolean, + organization: Organization + ): Promise { + // Validate schedule slot exists and belongs to this event + const scheduleSlot = await prisma.schedule_Slot.findUnique({ + where: { scheduleSlotId }, + include: { event: true } + }); + + if (!scheduleSlot) throw new NotFoundException('Schedule Slot', scheduleSlotId); + + // Check permissions + const hasPermission = + (await userHasPermission(submitter.userId, organization.organizationId, isHead)) || + submitter.userId === scheduleSlot.event.userCreatedId; + + if (!hasPermission) { + throw new AccessDeniedException('Only admins, heads, or the event creator can edit the times of an event!'); + } + + // Check for conflicts with the new time + const newSlotData: ScheduleSlotCreateArgs = { + startTime, + endTime, + allDay + }; + + const { hasConflict, conflictingEvent } = await checkEventConflicts( + [newSlotData], + organization, + scheduleSlot.event.location ?? undefined, + scheduleSlot.event.eventId + ); + + // Update the schedule slot + await prisma.schedule_Slot.update({ + where: { scheduleSlotId }, + data: { + startTime: startTime ?? null, + endTime: endTime ?? null, + allDay + } + }); + + // Update conflict status if needed + if (hasConflict) { + await prisma.event.update({ + where: { eventId: scheduleSlot.event.eventId }, + data: { + approved: Conflict_Status.PENDING, + approvalRequiredFromUserId: conflictingEvent?.userCreated.userId + } + }); + } + + // Fetch and return the updated event + const updatedEvent = await prisma.event.findUnique({ + where: { eventId: scheduleSlot.event.eventId }, + ...getEventQueryArgs(organization.organizationId) + }); + + if (!updatedEvent) throw new NotFoundException('Event', scheduleSlot.event.eventId); + + return eventTransformer(updatedEvent); + } + /** * Service function to upload a picture to the event documents folder in the NER google drive * @param eventId id for the event we're tying the document to diff --git a/src/backend/src/services/notifications.services.ts b/src/backend/src/services/notifications.services.ts index 10230a5c3c..fa6202c00c 100644 --- a/src/backend/src/services/notifications.services.ts +++ b/src/backend/src/services/notifications.services.ts @@ -133,10 +133,7 @@ export default class NotificationsService { }, scheduledTimes: { some: { - initialDateScheduled: { - lte: endOfToday, - gte: startOfToday - } + AND: [{ endTime: { gte: startOfToday } }, { startTime: { lte: endOfToday } }] } } }, diff --git a/src/backend/src/transformers/calendar.transformer.ts b/src/backend/src/transformers/calendar.transformer.ts index 507451027a..d1317748a8 100644 --- a/src/backend/src/transformers/calendar.transformer.ts +++ b/src/backend/src/transformers/calendar.transformer.ts @@ -103,12 +103,8 @@ export const calendarTransformer = (calendar: Prisma.CalendarGetPayload): ScheduleSlot => { return { scheduleSlotId: scheduleTimes.scheduleSlotId, - days: scheduleTimes.days.map(dayOfWeekTransformer), startTime: scheduleTimes.startTime ?? undefined, endTime: scheduleTimes.endTime ?? undefined, - recurrenceNumber: scheduleTimes.recurrenceNumber, - initialDateScheduled: scheduleTimes.initialDateScheduled, - endDate: scheduleTimes.endDate, allDay: scheduleTimes.allDay }; }; @@ -137,7 +133,8 @@ export const eventTransformer = (event: Prisma.EventGetPayload): zoomLink: event.zoomLink ?? undefined, questionDocumentLink: event.questionDocumentLink ?? undefined, description: event.description ?? undefined, - status: eventStatusTransformer(event.status) + status: eventStatusTransformer(event.status), + initialDateScheduled: event.initialDateScheduled ?? undefined }; }; @@ -180,13 +177,17 @@ export const eventWithMembersTransformer = (event: Prisma.EventGetPayload, wbsName: string): EventPreview => { - // Get the earliest scheduled date from scheduledTimes - const dateScheduled = event.scheduledTimes.length > 0 ? event.scheduledTimes[0].initialDateScheduled : new Date(); + // Use first scheduled time's startTime, or fall back to initialDateScheduled (for confirmation events), or current date + const dateScheduled = + (event.scheduledTimes.length > 0 && event.scheduledTimes[0].startTime ? event.scheduledTimes[0].startTime : null) ?? + event.initialDateScheduled ?? + new Date(); return { eventId: event.eventId, diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index 34c9b1610a..9424733b6c 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -6,7 +6,8 @@ import { Document, ConflictStatus, Event, - EventWithMembers + EventWithMembers, + DayOfWeek } from 'shared'; import { InvalidEventTypeConfigurationException } from './errors.utils.js'; import prisma from '../prisma/prisma.js'; @@ -16,9 +17,28 @@ import { eventTransformer } from '../transformers/calendar.transformer.js'; export function buildScheduledTimesOverlap(start?: Date, end?: Date): Prisma.Schedule_SlotListRelationFilter | undefined { if (!start && !end) return undefined; + // With the new schema, we check if the slot's time range overlaps with the query range const AND: Prisma.Schedule_SlotWhereInput[] = []; - if (end) AND.push({ initialDateScheduled: { lte: end } }); - if (start) AND.push({ endDate: { gte: start } }); + + // For all-day events, we just check the date portion + // For timed events, we check the full datetime + if (start) { + AND.push({ + OR: [ + { allDay: true, startTime: { gte: start } }, + { allDay: false, endTime: { gte: start } } + ] + }); + } + + if (end) { + AND.push({ + OR: [ + { allDay: true, startTime: { lte: end } }, + { allDay: false, startTime: { lte: end } } + ] + }); + } return { some: { AND } }; } @@ -84,7 +104,8 @@ export function validateEventTypeConfiguration( machineryIds: string[]; workPackageIds: string[]; documents: EventDocumentCreateArgs[]; - scheduleSlot: ScheduleSlotCreateArgs[]; + scheduleSlots: ScheduleSlotCreateArgs[]; + initialDateScheduled?: Date; teamTypeId?: string; location?: string; zoomLink?: string; @@ -112,8 +133,11 @@ export function validateEventTypeConfiguration( if (eventType.questionDocument && !eventData.questionDocumentLink) { throw new InvalidEventTypeConfigurationException('a question document'); } - if (eventData.scheduleSlot.length === 0) { - throw new InvalidEventTypeConfigurationException('at least one schedule slot'); + + // For requiresConfirmation events, schedule slots are optional initially + // For normal events, we need at least the initialDateScheduled + if (!eventType.requiresConfirmation && !eventData.initialDateScheduled) { + throw new InvalidEventTypeConfigurationException('an initial date scheduled'); } // Check disallowed fields (inverse validation) @@ -153,11 +177,11 @@ export function validateEventTypeConfiguration( * Checks if there are any scheduling conflicts with existing events. * A conflict occurs when events overlap in both time and location. * - * @param eventId The event ID to exclude from conflict check (for edits) - * @param scheduleSlots The schedule slots to check + * @param scheduleSlots The schedule slots to check (individual occurrences with full datetimes) * @param location The location to check * @param organization The organization - * @returns An object with hasConflict boolean and the user who should approve (if any) + * @param eventId The event ID to exclude from conflict check (for edits) + * @returns An object with hasConflict boolean and the conflicting event (if any) */ export async function checkEventConflicts( scheduleSlots: ScheduleSlotCreateArgs[], @@ -175,51 +199,77 @@ export async function checkEventConflicts( return { hasConflict: false }; } + // To limit speed issues, find min start and max end across time slots being checked, and limit potential conflicts to that range + let minStart: Date | null = null; + let maxEnd: Date | null = null; + + for (const slot of scheduleSlots) { + if (slot.startTime) { + if (!minStart || slot.startTime < minStart) { + minStart = slot.startTime; + } + } + if (slot.endTime) { + if (!maxEnd || slot.endTime > maxEnd) { + maxEnd = slot.endTime; + } + } + } + // Find all events in the same organization with the same location const potentialConflicts = await prisma.event.findMany({ where: { - eventId: eventId ? { not: eventId } : undefined, // Exclude current event if editing + eventId: eventId ? { not: eventId } : undefined, location, dateDeleted: null, approved: { in: [ConflictStatus.APPROVED, ConflictStatus.NO_CONFLICT] }, eventType: { organizationId: organization.organizationId - } + }, + scheduledTimes: buildScheduledTimesOverlap(minStart ?? undefined, maxEnd ?? undefined) }, ...getEventQueryArgs(organization.organizationId) }); - // Check each schedule slot against existing events + // Check each new schedule slot against existing event slots for (const newSlot of scheduleSlots) { for (const event of potentialConflicts) { for (const existingSlot of event.scheduledTimes) { - // Check if there's a day overlap - const dayOverlap = newSlot.days.some((day) => existingSlot.days.includes(day)); + if (!existingSlot.startTime || !existingSlot.endTime) continue; - if (!dayOverlap) continue; + // Check if events overlap + // If both are all-day events on the same day, they conflict + if (newSlot.allDay && existingSlot.allDay) { + const newDate = new Date(newSlot.startTime); + const existingDate = new Date(existingSlot.startTime); - // Check if there's a date range overlap - const newStartDate = new Date(newSlot.initialDateScheduled); - const newEndDate = new Date(newStartDate.getTime() + (newSlot.recurrenceNumber ?? 0) * 7 * 24 * 60 * 60 * 1000); - const existingStartDate = new Date(existingSlot.initialDateScheduled); - const existingEndDate = new Date(existingSlot.endDate); + // Normalize to compare dates only + newDate.setHours(0, 0, 0, 0); + existingDate.setHours(0, 0, 0, 0); - const dateOverlap = newStartDate <= existingEndDate && newEndDate >= existingStartDate; + if (newDate.getTime() === existingDate.getTime()) { + return { hasConflict: true, conflictingEvent: eventTransformer(event) }; + } + } + // If one is all-day, check if the all-day event's date overlaps with the timed event + else if (newSlot.allDay || existingSlot.allDay) { + const allDaySlot = newSlot.allDay ? newSlot : existingSlot; + const timedSlot = newSlot.allDay ? existingSlot : newSlot; - if (!dateOverlap) continue; + const allDayDate = new Date(allDaySlot.startTime!); + allDayDate.setHours(0, 0, 0, 0); - // If both are all-day events, they conflict - if (newSlot.allDay && existingSlot.allDay) { - return { hasConflict: true, conflictingEvent: eventTransformer(event) }; - } + const timedStart = new Date(timedSlot.startTime!); + const timedEnd = new Date(timedSlot.endTime!); + const timedDate = new Date(timedStart); + timedDate.setHours(0, 0, 0, 0); - // If one is all-day and the other isn't, they conflict - if (newSlot.allDay || existingSlot.allDay) { - return { hasConflict: true, conflictingEvent: eventTransformer(event) }; + if (allDayDate.getTime() === timedDate.getTime()) { + return { hasConflict: true, conflictingEvent: eventTransformer(event) }; + } } - - // Check time overlap (both have specific times) - if (newSlot.startTime && newSlot.endTime && existingSlot.startTime && existingSlot.endTime) { + // Both have specific times - check for time overlap + else { const newStart = new Date(newSlot.startTime).getTime(); const newEnd = new Date(newSlot.endTime).getTime(); const existingStart = new Date(existingSlot.startTime).getTime(); diff --git a/src/backend/src/utils/errors.utils.ts b/src/backend/src/utils/errors.utils.ts index 7a7aad7b49..32e8716986 100644 --- a/src/backend/src/utils/errors.utils.ts +++ b/src/backend/src/utils/errors.utils.ts @@ -210,4 +210,5 @@ export type ExceptionObjectNames = | 'Reimbursement Request Comment' | 'Calendar' | 'Event Type' - | 'Event'; + | 'Event' + | 'Schedule Slot'; diff --git a/src/backend/src/utils/google-integration.utils.ts b/src/backend/src/utils/google-integration.utils.ts index 26a40456a0..cc6071f375 100644 --- a/src/backend/src/utils/google-integration.utils.ts +++ b/src/backend/src/utils/google-integration.utils.ts @@ -229,42 +229,38 @@ export const createCalendarEvent = async ( const calendarEventIds: string[] = []; for (const slot of scheduledSlots) { - const occurrences = generateOccurrences(slot); - - for (const occurrence of occurrences) { - const eventInput = { - location: isInPerson ? location : zoomLink, - summary: eventTitle, - start: slot.allDay - ? { date: occurrence.date } - : { - dateTime: occurrence.startDateTime.toISOString(), - timeZone: 'America/New_York' - }, - end: slot.allDay - ? { date: occurrence.date } - : { - dateTime: occurrence.endDateTime.toISOString(), - timeZone: 'America/New_York' - }, - attendees, - reminders: { - useDefault: false, - overrides: [ - { method: 'email', minutes: 24 * 60 }, - { method: 'popup', minutes: 10 } - ] - } - }; - - const calendarEvent = await calendar.events.insert({ - calendarId, - requestBody: eventInput - }); - - if (calendarEvent.data.id) { - calendarEventIds.push(calendarEvent.data.id); + const eventInput = { + location: isInPerson ? location : zoomLink, + summary: eventTitle, + start: slot.allDay + ? { date: slot.startTime ? slot.startTime.toISOString().split('T')[0] : undefined } + : { + dateTime: slot.startTime ? slot.startTime.toISOString() : undefined, + timeZone: 'America/New_York' + }, + end: slot.allDay + ? { date: slot.endTime ? slot.endTime.toISOString().split('T')[0] : undefined } + : { + dateTime: slot.endTime ? slot.endTime.toISOString() : undefined, + timeZone: 'America/New_York' + }, + attendees, + reminders: { + useDefault: false, + overrides: [ + { method: 'email', minutes: 24 * 60 }, + { method: 'popup', minutes: 10 } + ] } + }; + + const calendarEvent = await calendar.events.insert({ + calendarId, + requestBody: eventInput + }); + + if (calendarEvent.data.id) { + calendarEventIds.push(calendarEvent.data.id); } } @@ -325,64 +321,6 @@ export const updateCalendarEvent = async ( } }; -/** - * Helper function to generate all occurrences for a schedule slot - */ -const generateOccurrences = (slot: Schedule_Slot) => { - const occurrences: Array<{ - date: string; - startDateTime: Date; - endDateTime: Date; - }> = []; - - const startDate = new Date(slot.initialDateScheduled); - const endDate = new Date(slot.endDate); - const currentDate = new Date(startDate); - - const dayOfWeekMap: Record = { - SUNDAY: 0, - MONDAY: 1, - TUESDAY: 2, - WEDNESDAY: 3, - THURSDAY: 4, - FRIDAY: 5, - SATURDAY: 6 - }; - - const targetDays = slot.days.map((day) => dayOfWeekMap[day]); - - while (currentDate <= endDate) { - const currentDayOfWeek = currentDate.getDay(); - - if (targetDays.includes(currentDayOfWeek)) { - const [dateStr] = currentDate.toISOString().split('T'); - - if (slot.startTime && slot.endTime) { - const startTime = new Date(slot.startTime); - const endTime = new Date(slot.endTime); - - const startDateTime = new Date(currentDate); - startDateTime.setHours(startTime.getHours(), startTime.getMinutes(), 0, 0); - - const endDateTime = new Date(currentDate); - endDateTime.setHours(endTime.getHours(), endTime.getMinutes(), 0, 0); - - occurrences.push({ date: dateStr, startDateTime, endDateTime }); - } else { - occurrences.push({ - date: dateStr, - startDateTime: currentDate, - endDateTime: currentDate - }); - } - } - - currentDate.setDate(currentDate.getDate() + 1); - } - - return occurrences; -}; - /** * Deletes multiple Google Calendar Events * @param calendarId Id of the calendar the events are on diff --git a/src/backend/src/utils/slack.utils.ts b/src/backend/src/utils/slack.utils.ts index 2cbbaf8425..a42cc57633 100644 --- a/src/backend/src/utils/slack.utils.ts +++ b/src/backend/src/utils/slack.utils.ts @@ -426,7 +426,11 @@ export const sendEventScheduledSlackNotif = async (threads: SlackMessageThread[] throw new HttpException(400, 'Event has no scheduled times'); } - const dateScheduled = firstScheduledTime.initialDateScheduled; + const dateScheduled = firstScheduledTime.startTime; + + if (!dateScheduled) { + throw new HttpException(400, 'Event scheduled time has no start time'); + } // Extract meeting times from scheduled slots const meetingTimes = event.scheduledTimes diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index 155cd323bd..85925bd99a 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -615,22 +615,17 @@ export const createTestDesignReviewEvent = async () => { [testWorkPackage.workPackageId], // workPackageIds [ { - days: [DayOfWeek.TUESDAY], startTime: new Date('2027-03-25T10:00:00'), endTime: new Date('2027-03-25T11:00:00'), - recurrenceNumber: 0, - initialDateScheduled: new Date('2027-03-25'), allDay: false }, { - days: [DayOfWeek.TUESDAY], startTime: new Date('2027-03-25T11:00:00'), endTime: new Date('2027-03-25T12:00:00'), - recurrenceNumber: 0, - initialDateScheduled: new Date('2027-03-25'), allDay: false } ], // scheduleSlot - two 1-hour time slots + undefined, teamType.teamTypeId, // team type id 'https://docs.google.com/document/d/test-design-review-questions', // questionDocument 'Campus Center Room 101', // location diff --git a/src/backend/tests/unit/calendar.test.ts b/src/backend/tests/unit/calendar.test.ts index f0b218de17..92d124a05e 100644 --- a/src/backend/tests/unit/calendar.test.ts +++ b/src/backend/tests/unit/calendar.test.ts @@ -10,7 +10,7 @@ import { import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest, alfred } from '../test-data/users.test-data'; import { createTestOrganization, createTestUser, resetUsers } from '../test-utils'; import prisma from '../../src/prisma/prisma'; -import { DayOfWeek, EventType, Machinery, ScheduleSlotCreateArgs, Shop, Event } from 'shared'; +import { EventType, Machinery, ScheduleSlotCreateArgs, Shop, Event } from 'shared'; describe('Calendar Tests', () => { let orgId: string; @@ -866,11 +866,8 @@ describe('Calendar Tests', () => { it('succeeds for admin with valid inputs', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -906,7 +903,6 @@ describe('Calendar Tests', () => { expect(result.machinery[0].machineryId).toBe(machinery.machineryId); expect(result.workPackages).toHaveLength(0); expect(result.scheduledTimes).toHaveLength(1); - expect(result.scheduledTimes[0].days).toEqual([DayOfWeek.MONDAY, DayOfWeek.TUESDAY]); expect(result.teamType).toBe(undefined); expect(result.approved).toBe(Conflict_Status.NO_CONFLICT); expect(result.approvalRequiredFrom).toBe(undefined); @@ -919,11 +915,8 @@ describe('Calendar Tests', () => { it('fails if eventTypeId does not exist', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -940,7 +933,8 @@ describe('Calendar Tests', () => { [], [], [], - scheduleSlots + scheduleSlots, + undefined ) ).rejects.toThrow(new NotFoundException('Event Type', 'non-existent-event-type-id')); }); @@ -948,11 +942,8 @@ describe('Calendar Tests', () => { it('fails if organization is invalid', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -969,7 +960,8 @@ describe('Calendar Tests', () => { [shop.shopId], [], [], - scheduleSlots + scheduleSlots, + undefined ) ).rejects.toThrow(new InvalidOrganizationException('Event Type')); }); @@ -977,11 +969,8 @@ describe('Calendar Tests', () => { it('succeeds with minimal inputs', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1027,11 +1016,8 @@ describe('Calendar Tests', () => { it('fails if memberIds are invalid', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1061,11 +1047,8 @@ describe('Calendar Tests', () => { it('fails if memberIds belong to a different organization', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1095,11 +1078,8 @@ describe('Calendar Tests', () => { it('fails if shopIds are inputted', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1129,11 +1109,8 @@ describe('Calendar Tests', () => { it('fails if shopIds belong to a different organization', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1163,11 +1140,8 @@ describe('Calendar Tests', () => { it('fails if machineryIds belong to a different organization', async () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1203,11 +1177,8 @@ describe('Calendar Tests', () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1250,11 +1221,8 @@ describe('Calendar Tests', () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1288,11 +1256,8 @@ describe('Calendar Tests', () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1351,11 +1316,8 @@ describe('Calendar Tests', () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1400,11 +1362,8 @@ describe('Calendar Tests', () => { const scheduleSlots2 = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], - startTime: new Date('2025-10-13T09:00:00Z'), - endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 5, - initialDateScheduled: new Date('2029-10-01'), + startTime: new Date('2029-10-01T09:00:00Z'), + endTime: new Date('2029-10-01T10:00:00Z'), allDay: false } ]; @@ -1446,11 +1405,8 @@ describe('Calendar Tests', () => { const scheduleSlots = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1495,11 +1451,8 @@ describe('Calendar Tests', () => { const scheduleSlots2 = [ { - days: [DayOfWeek.MONDAY, DayOfWeek.TUESDAY], - startTime: new Date('2025-10-13T09:00:00Z'), - endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 5, - initialDateScheduled: new Date('2029-10-01'), + startTime: new Date('2029-10-01T09:00:00Z'), + endTime: new Date('2029-10-01T10:00:00Z'), allDay: false } ]; @@ -1678,11 +1631,8 @@ describe('Calendar Tests', () => { member = await createTestUser(supermanAdmin, orgId); scheduleSlots = [ { - days: [DayOfWeek.MONDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; @@ -1721,8 +1671,7 @@ describe('Calendar Tests', () => { [], [], [], - [], - scheduleSlots + [] ) ).rejects.toThrow(new NotFoundException('Event', 'non-existent-id')); }); @@ -1746,8 +1695,7 @@ describe('Calendar Tests', () => { [], [], [], - [], - scheduleSlots + [] ) ).rejects.toThrow(new DeletedException('Event', event.eventId)); }); @@ -1767,7 +1715,6 @@ describe('Calendar Tests', () => { [machinery.machineryId], [], [], - scheduleSlots, undefined, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1792,7 +1739,6 @@ describe('Calendar Tests', () => { [machinery.machineryId], [], [], - scheduleSlots, undefined, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1823,7 +1769,7 @@ describe('Calendar Tests', () => { [machinery.machineryId], [], [], - scheduleSlots, + undefined, 'https://example.com/questions.pdf', 'Conference Room A', 'https://zoom.us/j/123456789', @@ -1847,7 +1793,6 @@ describe('Calendar Tests', () => { ['non-existent-machinery-id'], [], [], - scheduleSlots, undefined, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1878,7 +1823,6 @@ describe('Calendar Tests', () => { [deletedMachinery.machineryId], [], [], - scheduleSlots, undefined, 'https://example.com/questions.pdf', 'Conference Room A', @@ -1890,16 +1834,6 @@ describe('Calendar Tests', () => { it('succeeds for admin and updates event', async () => { const newMember = await createTestUser(alfred, orgId); - const newScheduleSlots: ScheduleSlotCreateArgs[] = [ - { - days: [DayOfWeek.WEDNESDAY], - startTime: new Date('2025-10-15T14:00:00Z'), - endTime: new Date('2025-10-15T15:00:00Z'), - recurrenceNumber: 2, - initialDateScheduled: new Date('2025-10-15'), - allDay: true - } - ]; const result = await CalendarService.editEvent( adminUser, @@ -1914,7 +1848,6 @@ describe('Calendar Tests', () => { [machinery.machineryId], [], [], - newScheduleSlots, undefined, 'https://updated.com/questions.pdf', 'Updated Location', @@ -1946,11 +1879,8 @@ describe('Calendar Tests', () => { member = await createTestUser(wonderwomanGuest, orgId); const scheduleSlots: ScheduleSlotCreateArgs[] = [ { - days: [DayOfWeek.MONDAY], startTime: new Date('2025-10-13T09:00:00Z'), endTime: new Date('2025-10-13T10:00:00Z'), - recurrenceNumber: 1, - initialDateScheduled: new Date('2025-10-13'), allDay: false } ]; diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index 202a2fbeac..e0cc9e8790 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -200,6 +200,16 @@ export const postEditEvent = async (eventId: string, payload: EditEventArgs) => }); }; +export const postEditScheduleSlot = async ( + eventId: string, + scheduleSlotId: string, + payload: { startTime?: Date; endTime?: Date; allDay: boolean } +) => { + return axios.post(apiUrls.calendarEditScheduleSlot(eventId, scheduleSlotId), payload, { + transformResponse: (data) => eventTransformer(JSON.parse(data)) + }); +}; + /** * Upload a document * diff --git a/src/frontend/src/apis/transformers/calendar.transformer.ts b/src/frontend/src/apis/transformers/calendar.transformer.ts index 978c5ad74c..811728263e 100644 --- a/src/frontend/src/apis/transformers/calendar.transformer.ts +++ b/src/frontend/src/apis/transformers/calendar.transformer.ts @@ -15,8 +15,8 @@ export const filterEventTransformer = (event: Event): Event => { dateCreated: new Date(event.dateCreated), scheduledTimes: event.scheduledTimes.map((schedule) => ({ ...schedule, - startTime: schedule.startTime ? new Date(schedule.startTime) : undefined, - endTime: schedule.endTime ? new Date(schedule.endTime) : undefined + startTime: new Date(schedule.startTime), + endTime: new Date(schedule.endTime) })) }; }; @@ -31,12 +31,11 @@ export const eventWithMembersTransformer = (event: EventWithMembers): EventWithM return { ...event, dateCreated: new Date(event.dateCreated), + initialDateScheduled: event.initialDateScheduled ? new Date(event.initialDateScheduled) : undefined, scheduledTimes: event.scheduledTimes.map((slot: any) => ({ ...slot, - startTime: slot.startTime ? new Date(slot.startTime) : undefined, - endTime: slot.endTime ? new Date(slot.endTime) : undefined, - initialDateScheduled: new Date(slot.initialDateScheduled), - endDate: new Date(slot.endDate) + startTime: new Date(slot.startTime), + endTime: new Date(slot.endTime) })) }; }; diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 605e7bda87..592b53e43b 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -43,6 +43,7 @@ import { uploadSingleDocument, downloadDocumentPdf, postEditEvent, + postEditScheduleSlot, getSingleEventWithMembers } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; @@ -72,6 +73,7 @@ export interface EventCreateArgs { documentIds: string[]; questionDocument?: string; description?: string; + initialDateScheduled: Date; scheduleSlot: ScheduleSlotCreateArgs[]; } @@ -90,7 +92,12 @@ export interface EditEventArgs { documents: Array<{ name: string; googleFileId: string }>; questionDocumentLink?: string; description?: string; - scheduleSlot: ScheduleSlotCreateArgs[]; +} + +export interface EditScheduleSlotArgs { + startTime?: Date; + endTime?: Date; + allDay: boolean; } export interface DownloadDocumentsFormInput { @@ -480,6 +487,24 @@ export const useEditEvent = (eventId: string) => { ); }; +export const useEditScheduleSlot = (eventId: string, scheduleSlotId: string) => { + const queryClient = useQueryClient(); + return useMutation( + ['events', 'edit-schedule-slot', eventId, scheduleSlotId], + async (payload) => { + const { data } = await postEditScheduleSlot(eventId, scheduleSlotId, payload); + return data; + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['filter-events']); + queryClient.invalidateQueries(EVENT_KEY); + queryClient.invalidateQueries(['events', eventId]); + } + } + ); +}; + export const useDenyEvent = (id: string) => { const queryClient = useQueryClient(); return useMutation( diff --git a/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx b/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx index 5829cb9ab6..c8b3690e53 100644 --- a/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx +++ b/src/frontend/src/pages/CalendarPage/AvailabilityScheduleView.tsx @@ -27,7 +27,7 @@ const AvailabilityScheduleView: React.FC = ({ const totalUsers = usersToAvailabilities.size; const [selectedTimeslot, setSelectedTimeslot] = useState(null); // Use displayDate if provided, otherwise fall back to event's initial date - const initialDate = displayDate || event.scheduledTimes[0]?.initialDateScheduled || new Date(); + const initialDate = displayDate || event.initialDateScheduled || new Date(); const potentialDays = getNextSevenDays(initialDate); const handleTimeslotClick = (index: number, _day: Date) => { diff --git a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx index ffda67ec92..7aedec6cfb 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx @@ -102,27 +102,27 @@ const CalendarTab: React.FC = () => { if (!event) return; try { - const { scheduleSlot, documentFiles, ...eventData } = data; - - if (!scheduleSlot || scheduleSlot.length === 0) { - throw new Error('Missing scheduleSlot'); - } + const { documentFiles, ...eventData } = data; // Convert EventRoutePayload to EditEventArgs format + // Note: scheduleSlot and initialDateScheduled are only in EventCreatePayload, not EventEditPayload const editArgs: EditEventArgs = { - ...eventData, + title: eventData.title, + requiredMemberIds: eventData.requiredMemberIds, + optionalMemberIds: eventData.optionalMemberIds, + teamIds: eventData.teamIds, + teamTypeId: eventData.teamTypeId, + location: eventData.location, + zoomLink: eventData.zoomLink, + shopIds: eventData.shopIds, + machineryIds: eventData.machineryIds, + workPackageIds: eventData.workPackageIds, + questionDocumentLink: eventData.questionDocumentLink, + description: eventData.description, status: event.status, // Use existing event status documents: event.documents.map((doc) => ({ name: doc.name, googleFileId: doc.googleFileId - })), - scheduleSlot: scheduleSlot.map((slot) => ({ - days: slot.days, - startTime: slot.startTime, - endTime: slot.endTime, - recurrenceNumber: slot.recurrenceNumber, - initialDateScheduled: slot.initialDateScheduled, - allDay: slot.allDay })) }; diff --git a/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx index 8d1abf2425..097752ae74 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx @@ -11,7 +11,7 @@ export interface EditEventModalProps { } const EditEventModal: React.FC = (props) => { - return ; + return ; }; export default EditEventModal; diff --git a/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx b/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx index 2f1ce8e1b7..2db6780123 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EventAvailabilityPage.tsx @@ -128,9 +128,8 @@ export const EventAvailabilityPage: React.FC = () => { if (dateParam) { return new Date(dateParam); } - const raw = event?.scheduledTimes?.[0]?.initialDateScheduled; - return raw ? new Date(raw as any) : new Date(); - }, [dateParam, event?.scheduledTimes]); + return event?.initialDateScheduled ?? new Date(); + }, [dateParam, event]); const isUserMember = useMemo(() => { if (!event) return false; diff --git a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx index 298819666b..0d24cd1ccc 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx @@ -19,7 +19,16 @@ import { DatePicker, TimePicker } from '@mui/x-date-pickers'; import { Controller, useForm } from 'react-hook-form'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; -import { DayOfWeek, EventDocumentUploadArgs, WbsElementStatus, wbsNamePipe, EventType, isHead, MAX_FILE_SIZE } from 'shared'; +import { + DayOfWeek, + EventDocumentUploadArgs, + WbsElementStatus, + wbsNamePipe, + EventType, + isHead, + MAX_FILE_SIZE, + getNextSevenDays +} from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import { useAllUsers, useCurrentUser } from '../../../hooks/users.hooks'; import { useAllWorkPackagesPreview } from '../../../hooks/work-packages.hooks'; @@ -39,6 +48,11 @@ import { ClearIcon } from '@mui/x-date-pickers'; import { useAllMachines, useAllShops } from '../../../hooks/calendar.hooks'; import StoreIcon from '@mui/icons-material/Store'; import PrecisionManufacturingIcon from '@mui/icons-material/PrecisionManufacturing'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; +import Tooltip from '@mui/material/Tooltip'; +import { convertDayToInt, convertIntToDay } from '../../../utils/calendar.utils'; +import { getDay } from 'date-fns'; export interface EventFormValues { title: string; @@ -56,14 +70,14 @@ export interface EventFormValues { questionDocumentLink?: string; description?: string; scheduleDate: Date; - startTime?: Date; - endTime?: Date; + startTime: Date; + endTime: Date; allDay: boolean; recurrenceNumber: number; days: DayOfWeek[]; } -export interface EventRoutePayload { +export interface EventCreatePayload { title: string; eventTypeId: string; requiredMemberIds: string[]; @@ -78,16 +92,34 @@ export interface EventRoutePayload { documentFiles: EventDocumentUploadArgs[]; questionDocumentLink?: string; description?: string; + initialDateScheduled: Date; scheduleSlot: Array<{ - days: DayOfWeek[]; - startTime?: Date; - endTime?: Date; - recurrenceNumber: number; - initialDateScheduled: Date; + startTime: Date; + endTime: Date; allDay: boolean; }>; } +export interface EventEditPayload { + title: string; + eventTypeId: string; + requiredMemberIds: string[]; + optionalMemberIds: string[]; + teamIds: string[]; + teamTypeId?: string; + location?: string; + zoomLink?: string; + shopIds: string[]; + machineryIds: string[]; + workPackageIds: string[]; + documentFiles: EventDocumentUploadArgs[]; + questionDocumentLink?: string; + description?: string; +} + +// Union type for backward compatibility +export type EventRoutePayload = EventCreatePayload | EventEditPayload; + const schema = yup.object().shape({ title: yup.string().required('Title is required'), eventTypeId: yup.string().required('Event Type is required'), @@ -104,16 +136,8 @@ const schema = yup.object().shape({ questionDocumentLink: yup.string().optional(), description: yup.string().optional(), scheduleDate: yup.date().required('Date is required'), - startTime: yup.date().when('allDay', { - is: false, - then: (schema) => schema.required('Start time is required'), - otherwise: (schema) => schema.optional() - }), - endTime: yup.date().when('allDay', { - is: false, - then: (schema) => schema.required('End time is required').min(yup.ref('startTime'), 'End time must be after start time'), - otherwise: (schema) => schema.optional() - }), + startTime: yup.date().required('Start time is required'), + endTime: yup.date().required('End time is required'), allDay: yup.boolean().required(), recurrenceNumber: yup.number().min(0).required('Recurrence is required'), days: yup.array().of(yup.mixed().required()).default([]) @@ -126,6 +150,7 @@ export interface BaseEventModalProps { initialValues?: Partial; eventTypes: EventType[]; defaultDate?: Date; + isEditMode?: boolean; } const EventModal: React.FC = ({ @@ -134,7 +159,8 @@ const EventModal: React.FC = ({ onSubmit, initialValues, eventTypes, - defaultDate = new Date() + defaultDate = new Date(), + isEditMode = false }) => { const toast = useToast(); const user = useCurrentUser(); @@ -176,10 +202,10 @@ const EventModal: React.FC = ({ questionDocumentLink: initialValues?.questionDocumentLink, description: initialValues?.description, scheduleDate: initialValues?.scheduleDate ?? defaultDate, - startTime: initialValues?.startTime, - endTime: initialValues?.endTime, + startTime: initialValues?.startTime ?? new Date(), + endTime: initialValues?.endTime ?? new Date(), allDay: initialValues?.allDay ?? false, - recurrenceNumber: initialValues?.recurrenceNumber ?? 0, + recurrenceNumber: initialValues?.recurrenceNumber ?? 1, days: initialValues?.days ?? [] }), [initialValues, defaultDate] @@ -208,6 +234,11 @@ const EventModal: React.FC = ({ const selectedEventTypeId = watch('eventTypeId'); const documentFiles = watch('documentFiles'); + const selectedEventType = useMemo( + () => allowedEventTypes.find((et) => et.eventTypeId === selectedEventTypeId), + [allowedEventTypes, selectedEventTypeId] + ); + // Filter machinery based on selected shops const filteredMachineryOptions = useMemo(() => { if (!machinery || !shops) { @@ -265,14 +296,85 @@ const EventModal: React.FC = ({ } }, [open, initialValues?.days]); - const selectedEventType = useMemo( - () => allowedEventTypes.find((et) => et.eventTypeId === selectedEventTypeId), - [allowedEventTypes, selectedEventTypeId] - ); - - const isEditMode = !!initialValues?.eventTypeId; const computedTitle = isEditMode ? 'Edit Event' : 'Add Event'; + // Handle recurring dropdown toggle + const handleRecurringToggle = () => { + if (showRecurringOptions) { + // Closing the dropdown - reset to 0 + setValue('recurrenceNumber', 0); + setValue('days', []); + } else { + // Opening the dropdown - set to 1 + setValue('recurrenceNumber', 1); + const startDate = watch('scheduleDate') ?? new Date(); + setValue('days', [convertIntToDay(getDay(startDate))]); + } + setShowRecurringOptions(!showRecurringOptions); + }; + + // Handle event type change + const handleEventTypeChange = (newEventTypeId: string) => { + const newEventType = allowedEventTypes.find((et) => et.eventTypeId === newEventTypeId); + + const selectedDate = watch('scheduleDate'); + + // If switching to a confirmation event type, clear time-related fields + if (newEventType?.requiresConfirmation) { + setValue('startTime', selectedDate); + setValue('endTime', selectedDate); + setValue('allDay', false); + setValue('recurrenceNumber', 0); + setValue('days', []); + setShowRecurringOptions(false); + } + + // Update the event type + setValue('eventTypeId', newEventTypeId); + }; + + // Calculate the last occurrence date for recurring events + const calculateLastOccurrenceDate = () => { + const recurrenceNum = watch('recurrenceNumber'); + const startDate = watch('scheduleDate'); + const selectedDays = watch('days'); + + if (!recurrenceNum || recurrenceNum === 0 || selectedDays.length === 0) return null; + + // Convert to day indices (0 = Sunday, 1 = Monday, etc.) + const dayIndices: number[] = selectedDays.map(convertDayToInt).sort((a, b) => a - b); + + // Start from the initial date + const currentDate = new Date(startDate); + let occurrencesFound = 0; + let lastOccurrenceDate = currentDate; + + // Find all occurrences + const searchDate = new Date(currentDate); + + // Search for up to a year (52 weeks * 7 days = 364 days) + const maxDaysToSearch = 365; + let daysSearched = 0; + + while (occurrencesFound < recurrenceNum && daysSearched < maxDaysToSearch) { + const currentDayIndex = searchDate.getDay(); + + if (dayIndices.includes(currentDayIndex)) { + occurrencesFound++; + lastOccurrenceDate = new Date(searchDate); + + if (occurrencesFound >= recurrenceNum) { + break; + } + } + + searchDate.setDate(searchDate.getDate() + 1); + daysSearched++; + } + + return lastOccurrenceDate; + }; + const handleClose = () => { reset(defaultFormData); setRequiredMembers([]); @@ -314,89 +416,50 @@ const EventModal: React.FC = ({ const onFormSubmit = async (data: EventFormValues) => { try { const scheduleSlots: Array<{ - days: DayOfWeek[]; - startTime?: Date; - endTime?: Date; - recurrenceNumber: number; - initialDateScheduled: Date; + startTime: Date; + endTime: Date; allDay: boolean; }> = []; - // If recurrence is 0, automatically determine the day from the initial date - if (data.recurrenceNumber === 0) { - const dayOfWeek = data.scheduleDate.getDay(); // 0 = Sunday, 1 = Monday, etc. - const dayOfWeekEnum = [ - DayOfWeek.SUNDAY, - DayOfWeek.MONDAY, - DayOfWeek.TUESDAY, - DayOfWeek.WEDNESDAY, - DayOfWeek.THURSDAY, - DayOfWeek.FRIDAY, - DayOfWeek.SATURDAY - ][dayOfWeek]; - - // Create a schedule slot with just the initial date's day - scheduleSlots.push({ - days: [dayOfWeekEnum], - startTime: data.startTime, - endTime: data.endTime, - recurrenceNumber: 0, - initialDateScheduled: data.scheduleDate, - allDay: data.allDay - }); - } else { - // If there are recurring days selected - const dayOfWeek = data.scheduleDate.getDay(); - const dayOfWeekEnum = [ - DayOfWeek.SUNDAY, - DayOfWeek.MONDAY, - DayOfWeek.TUESDAY, - DayOfWeek.WEDNESDAY, - DayOfWeek.THURSDAY, - DayOfWeek.FRIDAY, - DayOfWeek.SATURDAY - ][dayOfWeek]; - - const selectedDays = data.days.length > 0 ? data.days : []; - const initialDayMatchesSelected = selectedDays.includes(dayOfWeekEnum); - - // If the initial date's day is NOT in the selected recurring days, - // create a separate slot for just the initial occurrence - if (!initialDayMatchesSelected && selectedDays.length > 0) { - scheduleSlots.push({ - days: [dayOfWeekEnum], - startTime: data.startTime, - endTime: data.endTime, - recurrenceNumber: 0, - initialDateScheduled: data.scheduleDate, - allDay: data.allDay - }); - } + // Helper function to create a date/time for a specific occurrence + const createSlotDateTime = (baseDate: Date, time: Date): Date => { + const result = new Date(baseDate); + result.setHours(time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds()); + return result; + }; - // Create the recurring schedule slot - if (selectedDays.length > 0) { - scheduleSlots.push({ - days: selectedDays, - startTime: data.startTime, - endTime: data.endTime, - recurrenceNumber: data.recurrenceNumber, - initialDateScheduled: data.scheduleDate, - allDay: data.allDay - }); - } else { - // If no days selected, use the initial date's day for recurring + // Generate schedule slots for recurring events + const dayOfWeekEnum = convertIntToDay(data.scheduleDate.getDay()); + const selectedDays = data.days.length > 0 ? data.days : [dayOfWeekEnum]; + + // Convert selected days to day indices for comparison + const dayIndices = selectedDays.map(convertDayToInt); + + // Generate additional recurring occurrences + let occurrencesGenerated = 0; + const searchDate = new Date(data.scheduleDate); + + const maxDaysToSearch = 365; // Search up to a year + let daysSearched = 0; + + while (occurrencesGenerated < data.recurrenceNumber && daysSearched < maxDaysToSearch) { + const currentDayIndex = searchDate.getDay(); + + if ((dayIndices as number[]).includes(currentDayIndex)) { scheduleSlots.push({ - days: [dayOfWeekEnum], - startTime: data.startTime, - endTime: data.endTime, - recurrenceNumber: data.recurrenceNumber, - initialDateScheduled: data.scheduleDate, + startTime: createSlotDateTime(searchDate, data.startTime), + endTime: createSlotDateTime(searchDate, data.endTime), allDay: data.allDay }); + occurrencesGenerated++; } + + searchDate.setDate(searchDate.getDate() + 1); + daysSearched++; } - const submitData: EventRoutePayload = { + // Build the appropriate payload based on mode + const basePayload = { title: data.title, eventTypeId: data.eventTypeId, requiredMemberIds: requiredMembers.map((m) => m.id), @@ -410,10 +473,16 @@ const EventModal: React.FC = ({ workPackageIds: data.workPackageIds, documentFiles: data.documentFiles, questionDocumentLink: data.questionDocumentLink, - description: data.description, - scheduleSlot: scheduleSlots + description: data.description }; + const submitData: EventRoutePayload = isEditMode + ? basePayload + : { + ...basePayload, + initialDateScheduled: data.scheduleDate, + scheduleSlot: scheduleSlots + }; await onSubmit(submitData); handleClose(); } catch (e: unknown) { @@ -472,336 +541,462 @@ const EventModal: React.FC = ({ > {/* Title Input with red placeholder styling */} - ( - + ( + - )} - /> + }} + /> + )} + /> + {errors.title?.message} + {/* Event Type Tabs */} - - {allowedEventTypes.map((et) => ( - ( - - )} - /> - ))} - - {/* Date and Time Section */} - - - - ( - setDatePickerOpen(false)} - onOpen={() => setDatePickerOpen(true)} - onChange={(newValue) => onChange(newValue ?? defaultDate)} - slotProps={{ - textField: { - variant: 'standard', - error: !!errors.scheduleDate, - onClick: () => setDatePickerOpen(true), - sx: { minWidth: 150 } - }, - day: { - sx: { - '&.Mui-selected': { - backgroundColor: '#EF4345 !important', - '&:hover': { - backgroundColor: '#d32f2f !important' + + + {allowedEventTypes.map((et) => ( + + ))} + + {errors.eventTypeId?.message} + + {/* Date and Time Section - Only show when event type is selected */} + {selectedEventType && ( + + {selectedEventType.requiresConfirmation ? ( + + {/* Header with info tooltip */} + + + + + + To be scheduled within: + + + + + ( + setDatePickerOpen(false)} + onOpen={() => setDatePickerOpen(true)} + onChange={(newValue) => onChange(newValue ?? defaultDate)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.scheduleDate, + onClick: () => setDatePickerOpen(true), + sx: { minWidth: 150 } }, - '&:focus': { - backgroundColor: '#EF4345 !important' - } - } - } - } - }} - /> - )} - /> - - {!watch('allDay') && ( - <> - ( - setStartTimePickerOpen(false)} - onOpen={() => setStartTimePickerOpen(true)} - onChange={(newValue) => onChange(newValue)} - slotProps={{ - textField: { - variant: 'standard', - error: !!errors.startTime, - onClick: () => setStartTimePickerOpen(true), - sx: { width: 100 } - }, - layout: { - sx: { - '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { - backgroundColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { - backgroundColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { - backgroundColor: '#EF4345', - borderColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { - backgroundColor: '#EF4345 !important' - }, - '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { - backgroundColor: '#EF4345 !important', - color: 'white' - }, - '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { - backgroundColor: '#EF4345 !important', - color: 'white' + day: { + sx: { + '&.Mui-selected': { + backgroundColor: '#EF4345 !important', + '&:hover': { + backgroundColor: '#d32f2f !important' + }, + '&:focus': { + backgroundColor: '#EF4345 !important' + } + } } } - } - }} - /> - )} - /> - - - ( - setEndTimePickerOpen(false)} - onOpen={() => setEndTimePickerOpen(true)} - onChange={(newValue) => onChange(newValue)} - slotProps={{ - textField: { - variant: 'standard', - error: !!errors.endTime, - onClick: () => setEndTimePickerOpen(true), - sx: { width: 100 } - }, - layout: { - sx: { - '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { - backgroundColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { - backgroundColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { - backgroundColor: '#EF4345', - borderColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { - backgroundColor: '#EF4345 !important' - }, - '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { - backgroundColor: '#EF4345 !important', - color: 'white' + }} + /> + )} + /> + + { + const weekDates = getNextSevenDays(value); + const endDate = weekDates.at(-1); + return ( + + ); + }} + /> + + + ) : ( + /* Normal Event Type - Full date/time selection */ + <> + {/* Date and Time Row */} + + + ( + setDatePickerOpen(false)} + onOpen={() => setDatePickerOpen(true)} + onChange={(newValue) => onChange(newValue ?? defaultDate)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.scheduleDate, + onClick: () => setDatePickerOpen(true), + sx: { minWidth: 150 } + }, + day: { + sx: { + '&.Mui-selected': { + backgroundColor: '#EF4345 !important', + '&:hover': { + backgroundColor: '#d32f2f !important' + }, + '&:focus': { + backgroundColor: '#EF4345 !important' + } + } } } - } - }} - /> - )} - /> - - )} + }} + /> + )} + /> - ( - onChange(e.target.checked)} />} - label="All Day" - /> - )} - /> + {!watch('allDay') && ( + <> + ( + setStartTimePickerOpen(false)} + onOpen={() => setStartTimePickerOpen(true)} + onChange={(newValue) => onChange(newValue)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.startTime, + onClick: () => setStartTimePickerOpen(true), + sx: { width: 100 } + }, + layout: { + sx: { + '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { + backgroundColor: '#EF4345', + borderColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { + backgroundColor: '#EF4345 !important' + }, + '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + }, + '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + } + } + } + }} + /> + )} + /> + - + ( + setEndTimePickerOpen(false)} + onOpen={() => setEndTimePickerOpen(true)} + onChange={(newValue) => onChange(newValue)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.endTime, + onClick: () => setEndTimePickerOpen(true), + sx: { width: 100 } + }, + layout: { + sx: { + '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { + backgroundColor: '#EF4345', + borderColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { + backgroundColor: '#EF4345 !important' + }, + '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + }, + '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + } + } + } + }} + /> + )} + /> + + )} + - - + {/* All Day and Recurring Row */} + + ( + onChange(e.target.checked)} />} + label="All Day" + /> + )} + /> - {/* Recurring Options */} - {showRecurringOptions && ( - - - - Repeat - - ( - 0 ? 'grey.400' : 'transparent' }} - inputProps={{ min: 1 }} - /> + > + Recurring ▼ + )} - /> - - more time(s) - - - - - Repeat on: - - { - const weekDays: DayOfWeek[] = [ - DayOfWeek.SUNDAY, - DayOfWeek.MONDAY, - DayOfWeek.TUESDAY, - DayOfWeek.WEDNESDAY, - DayOfWeek.THURSDAY, - DayOfWeek.FRIDAY, - DayOfWeek.SATURDAY - ]; - const dayLabels = ['S', 'M', 'T', 'W', 'TH', 'F', 'S']; - - const toggleDay = (day: DayOfWeek) => { - const currentDays = value || []; - if (currentDays.includes(day)) { - onChange(currentDays.filter((d) => d !== day)); - } else { - onChange([...currentDays, day]); - } - }; + - return ( - - {weekDays.map((day, index) => { - const isSelected = (value || []).includes(day); - return ( - + inputProps={{ min: 1 }} + /> + )} + /> + + more time(s) + + + + + Repeat on: + + { + const weekDays: DayOfWeek[] = [ + DayOfWeek.SUNDAY, + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SATURDAY + ]; + const dayLabels = ['S', 'M', 'T', 'W', 'TH', 'F', 'S']; + + const toggleDay = (day: DayOfWeek) => { + const currentDays = value || []; + if (currentDays.includes(day)) { + onChange(currentDays.filter((d) => d !== day)); + } else { + onChange([...currentDays, day]); + } + }; + + return ( + + {weekDays.map((day, index) => { + const isSelected = (value || []).includes(day); + return ( + + ); + })} + ); - })} -
    - ); - }} - /> + }} + /> - {errors.days && ( - - {errors.days.message} - - )} + {errors.days && ( + + {errors.days.message} + + )} - - - Note: This event will repeat {watch('recurrenceNumber')} time(s){' '} - {watch('days').length > 0 && `on ${watch('days').join(', ')}`} - - - - )} - + {/* Last Occurrence Info */} + {watch('recurrenceNumber') > 0 && watch('days').length > 0 ? ( + + + Last occurrence:{' '} + {calculateLastOccurrenceDate()?.toLocaleDateString('en-US', { + weekday: 'long', + month: 'long', + day: 'numeric', + year: 'numeric' + })} + + + ) : ( + + {watch('days').length === 0 + ? 'Select at least one day to see the last occurrence date.' + : "Select the number of times you'd like this event to recur."} + + )} + + )} + + )} + + )} {/* Required Members Section */} {selectedEventType?.requiredMembers && ( @@ -947,22 +1142,23 @@ const EventModal: React.FC = ({ {selectedEventType?.zoomLink && ( - ( - - )} - /> + + ( + + )} + /> + {errors.zoomLink?.message} + )} {selectedEventType?.shop && ( diff --git a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx index 49bf95cd79..8e39fd96d7 100644 --- a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx @@ -23,12 +23,11 @@ import HelpIcon from '@mui/icons-material/Help'; import EditIcon from '@mui/icons-material/Edit'; import PeopleIcon from '@mui/icons-material/People'; import DeleteIcon from '@mui/icons-material/Delete'; - import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; import NERSuccessButton from '../../components/NERSuccessButton'; import NERFailButton from '../../components/NERFailButton'; import { EditEventArgs, useApproveEvent, useDeleteEvent, useDenyEvent, useEditEvent } from '../../hooks/calendar.hooks'; -import { convertDayToDayShorthand, convertEventToFormValues } from '../../utils/calendar.utils'; +import { convertEventToFormValues } from '../../utils/calendar.utils'; import EditEventModal from './Components/EditEventModal'; import { useToast } from '../../hooks/toasts.hooks'; import NERDeleteModal from '../../components/NERDeleteModal'; @@ -98,9 +97,7 @@ const EventClickContent: React.FC = ({ const showAvailabilityButton = true; - const eventDate = - clickedDate || - (event.scheduledTimes[0]?.initialDateScheduled ? new Date(event.scheduledTimes[0].initialDateScheduled) : new Date()); + const eventDate = clickedDate || (event.scheduledTimes[0]?.startTime ? event.scheduledTimes[0].startTime : new Date()); const availabilityUrl = `${routes.NEW_CALENDAR}/event/${event.eventId}?date=${eventDate.toISOString()}`; @@ -190,14 +187,18 @@ const EventClickContent: React.FC = ({ {!dayOfWeek && } {!dayOfWeek && ( - {event.scheduledTimes.map((slot) => ( - - {slot.startTime?.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) ?? 'N/A'} –{' '} - {slot.endTime?.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) ?? 'N/A'} - {' : '} - {slot.days.map((day) => convertDayToDayShorthand(day)).join(', ')} - - ))} + {event.scheduledTimes.map((slot, index) => { + const slotDate = slot.startTime ? new Date(slot.startTime) : null; + const dateStr = slotDate + ? slotDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) + : 'N/A'; + return ( + + {dateStr} {slot.startTime?.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) ?? 'N/A'}{' '} + – {slot.endTime?.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) ?? 'N/A'} + + ); + })} )} {hasValue(locationText) && ( @@ -524,9 +525,7 @@ export const EventClickPopup: React.FC = ({ initialValues={convertEventToFormValues(clickedEvent)} eventTypes={eventTypes} defaultDate={ - clickedEvent.scheduledTimes[0]?.initialDateScheduled - ? new Date(clickedEvent.scheduledTimes[0].initialDateScheduled) - : new Date() + clickedEvent.scheduledTimes[0]?.startTime ? new Date(clickedEvent.scheduledTimes[0].startTime) : new Date() } /> )} diff --git a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx index f7f54b9af0..29e935fb1e 100644 --- a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx @@ -304,24 +304,18 @@ const NewCalendarPage: React.FC = ({ const handleCreateEvent = async (data: EventRoutePayload) => { try { - const { scheduleSlot, documentFiles, ...eventData } = data; - - if (!scheduleSlot || scheduleSlot.length === 0) { - throw new Error('Missing scheduleSlot'); + // Type guard to ensure we have a create payload with schedule slots + if (!('scheduleSlot' in data) || !('initialDateScheduled' in data)) { + throw new Error('Invalid payload for creating event'); } + const { documentFiles, ...eventData } = data; + // Create the event first without documents + // EventModal already generates the schedule slots with actual dates/times const createArgs = { ...eventData, - documentIds: [], - scheduleSlot: scheduleSlot.map((slot) => ({ - days: slot.days, - startTime: slot.startTime, - endTime: slot.endTime, - recurrenceNumber: slot.recurrenceNumber, - initialDateScheduled: slot.initialDateScheduled, - allDay: slot.allDay - })) + documentIds: [] }; const createdEvent = await createEvent(createArgs); diff --git a/src/frontend/src/pages/HomePage/components/EventCard.tsx b/src/frontend/src/pages/HomePage/components/EventCard.tsx index c392993c03..f2bf7ef690 100644 --- a/src/frontend/src/pages/HomePage/components/EventCard.tsx +++ b/src/frontend/src/pages/HomePage/components/EventCard.tsx @@ -69,7 +69,7 @@ const removeYear = (str: string): string => { const UpcomingEventCard: React.FC = ({ event, user }) => { const theme = useTheme(); - const firstScheduledDate = event.scheduledTimes[0]?.initialDateScheduled; + const firstScheduledDate = event.initialDateScheduled || event.scheduledTimes[0]?.startTime; const timezoneAdjustedDate = firstScheduledDate ? timezoneOffset(firstScheduledDate) : new Date(); const [firstWorkPackage] = event.workPackages; diff --git a/src/frontend/src/pages/HomePage/components/UpcomingDesignReviews.tsx b/src/frontend/src/pages/HomePage/components/UpcomingDesignReviews.tsx index 47192c14fd..ce2cbad04a 100644 --- a/src/frontend/src/pages/HomePage/components/UpcomingDesignReviews.tsx +++ b/src/frontend/src/pages/HomePage/components/UpcomingDesignReviews.tsx @@ -34,7 +34,7 @@ const UpcomingEvents: React.FC = ({ user }) => { const filteredEvents = events.filter((event) => { // Get the first scheduled date - const scheduledDate = event.scheduledTimes[0]?.initialDateScheduled; + const scheduledDate = event.scheduledTimes[0]?.startTime; if (!scheduledDate) return false; const currentDate = new Date(); diff --git a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx index e323c78f17..9577dab8d9 100644 --- a/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx +++ b/src/frontend/src/pages/SettingsPage/UserScheduleSettings/UserScheduleSettingsView.tsx @@ -29,8 +29,8 @@ const UserScheduleSettingsView = ({ // Get first scheduled date from event let firstScheduledDate: Date | undefined; - if (event && event.scheduledTimes && event.scheduledTimes.length > 0 && event.scheduledTimes[0].initialDateScheduled) { - firstScheduledDate = new Date(event.scheduledTimes[0].initialDateScheduled); + if (event && event.scheduledTimes && event.scheduledTimes.length > 0 && event.scheduledTimes[0].startTime) { + firstScheduledDate = new Date(event.scheduledTimes[0].startTime); } // Get work package names for the event title @@ -56,7 +56,7 @@ const UserScheduleSettingsView = ({ }; const firstDate = useMemo(() => { - const raw = event?.scheduledTimes?.[0]?.initialDateScheduled; + const raw = event?.scheduledTimes?.[0]?.startTime; return raw ? new Date(raw as any) : new Date(); }, [event?.scheduledTimes]); diff --git a/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts b/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts index 886a8b5f01..0d9b092220 100644 --- a/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts +++ b/src/frontend/src/tests/test-support/test-data/design-reviews.stub.ts @@ -3,7 +3,7 @@ * See the LICENSE file in the repository root folder for details. */ -import { ConflictStatus, DayOfWeek, Event, EventStatus, TeamType } from 'shared'; +import { ConflictStatus, Event, EventStatus, TeamType } from 'shared'; import { exampleAdminUser, exampleAppAdminUser } from './users.stub'; export const teamType1: TeamType = { @@ -28,42 +28,26 @@ export const exampleDesignReviewEvent1: Event = { scheduledTimes: [ { scheduleSlotId: 'slot-1', - days: [DayOfWeek.TUESDAY], startTime: new Date('2024-03-25T10:00:00'), endTime: new Date('2024-03-25T11:00:00'), - recurrenceNumber: 0, - initialDateScheduled: new Date('2024-03-25'), - endDate: new Date('2024-03-25'), allDay: false }, { scheduleSlotId: 'slot-2', - days: [DayOfWeek.TUESDAY], startTime: new Date('2024-03-25T11:00:00'), endTime: new Date('2024-03-25T12:00:00'), - recurrenceNumber: 0, - initialDateScheduled: new Date('2024-03-25'), - endDate: new Date('2024-03-25'), allDay: false }, { scheduleSlotId: 'slot-3', - days: [DayOfWeek.TUESDAY], startTime: new Date('2024-03-25T12:00:00'), endTime: new Date('2024-03-25T13:00:00'), - recurrenceNumber: 0, - initialDateScheduled: new Date('2024-03-25'), - endDate: new Date('2024-03-25'), allDay: false }, { scheduleSlotId: 'slot-4', - days: [DayOfWeek.TUESDAY], startTime: new Date('2024-03-25T13:00:00'), endTime: new Date('2024-03-25T14:00:00'), - recurrenceNumber: 0, - initialDateScheduled: new Date('2024-03-25'), - endDate: new Date('2024-03-25'), allDay: false } ], @@ -104,22 +88,14 @@ export const exampleDesignReviewEvent2: Event = { scheduledTimes: [ { scheduleSlotId: 'slot-5', - days: [DayOfWeek.TUESDAY], startTime: new Date('2024-03-25T10:00:00'), endTime: new Date('2024-03-25T11:00:00'), - recurrenceNumber: 0, - initialDateScheduled: new Date('2024-03-25'), - endDate: new Date('2024-03-25'), allDay: false }, { scheduleSlotId: 'slot-6', - days: [DayOfWeek.TUESDAY], startTime: new Date('2024-03-25T14:00:00'), endTime: new Date('2024-03-25T15:00:00'), - recurrenceNumber: 0, - initialDateScheduled: new Date('2024-03-25'), - endDate: new Date('2024-03-25'), allDay: false } ], diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index debb7fe222..8c64a1d1a8 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -18,8 +18,6 @@ export const convertDayToInt = (day: DayOfWeek) => { return 6; case DayOfWeek.SUNDAY: return 0; - default: - return -1; } }; @@ -66,44 +64,22 @@ export const convertDayToDayShorthand = (day: DayOfWeek) => { }; // Get a list of dates for user viewing purposes (formatted to their timezone, with date and start/end time) -// If start/end time is not needed, then only use the provided day +// After the recurring events refactor, each schedule slot contains the actual date/time // Should be used when events need to be populated/displayed export const getMeetingDates = (event: Event, startTimes: boolean = true) => { const times: Date[] = []; + event.scheduledTimes.forEach((schedule) => { const specificTime = startTimes ? schedule.startTime : schedule.endTime; - schedule.days.forEach((day) => { - const startTimeDate = new Date(schedule.initialDateScheduled); - const timezoneOffset = startTimeDate.getTimezoneOffset() * 60000; - - // get the initial date (adjusted to match UTC) - // this is done to ensure offset is properly calculated - const startDate = new Date(startTimeDate.getTime() + timezoneOffset); - - // set the hour and minutes using UTC to match the adjusted date - startDate.setHours(specificTime?.getUTCHours() ?? 0); - startDate.setMinutes(specificTime?.getUTCMinutes() ?? 0); - - // Calculate offset based on the current day being checked - const offset = startDate.getDay() - convertDayToInt(day); - - // apply offset to get the true date of this specific event - startDate.setDate(startDate.getDate() - offset); - - // adjust for the users time - const startDateAdjusted = new Date(startDate.getTime() - timezoneOffset); - - // potentially needed to prevent extra events from showing up before the initial date - times.push(startDateAdjusted); - - // add additional events for each recurrence on this day - for (let i = 1; i <= schedule.recurrenceNumber; i++) { - const nextDate = new Date(startDateAdjusted); - nextDate.setDate(nextDate.getDate() + 7 * i); - times.push(nextDate); - } - }); + // With the new schema, startTime and endTime contain the full date/time + // Just return the dates directly + if (specificTime) { + times.push(new Date(specificTime)); + } else if (schedule.allDay && schedule.startTime) { + // For all-day events, use startTime for the date + times.push(new Date(schedule.startTime)); + } }); return times; @@ -160,7 +136,26 @@ export const getEventsFlattened = (events: Event[], startPeriod: Date, endPeriod }; // converts an Event into Event Form Values +// Note: After the recurring events refactor, we store individual schedule slots +// When editing, we show the first occurrence and set recurrence to 0 +// Users will need to delete and recreate if they want to change recurring patterns export const convertEventToFormValues = (event: Event): Partial => { + // Use the first schedule slot for the form values + const [firstSlot] = event.scheduledTimes; + + // Extract the date from the first slot's startTime + // For confirmation-required events, initialDateScheduled represents the start of the week range + // For regular events, we use the actual startTime from the first slot + let scheduleDate = new Date(); + if (firstSlot?.startTime) { + scheduleDate = new Date(firstSlot.startTime); + } else if (firstSlot?.endTime) { + scheduleDate = new Date(firstSlot.endTime); + } else if (event.initialDateScheduled) { + // Only fall back to initialDateScheduled if no slot times exist (confirmation events) + scheduleDate = new Date(event.initialDateScheduled); + } + return { title: event.title, eventTypeId: event.eventTypeId, @@ -179,13 +174,13 @@ export const convertEventToFormValues = (event: Event): Partial })), questionDocumentLink: event.questionDocumentLink, description: event.description, - scheduleDate: event.scheduledTimes[0]?.initialDateScheduled - ? new Date(event.scheduledTimes[0].initialDateScheduled) - : new Date(), - startTime: event.scheduledTimes[0]?.startTime ? new Date(event.scheduledTimes[0].startTime) : undefined, - endTime: event.scheduledTimes[0]?.endTime ? new Date(event.scheduledTimes[0].endTime) : undefined, - allDay: event.scheduledTimes[0]?.allDay ?? false, - recurrenceNumber: event.scheduledTimes[0]?.recurrenceNumber ?? 0, - days: event.scheduledTimes[0]?.days ?? [] + scheduleDate, + startTime: firstSlot?.startTime ? new Date(firstSlot.startTime) : undefined, + endTime: firstSlot?.endTime ? new Date(firstSlot.endTime) : undefined, + allDay: firstSlot?.allDay ?? false, + // Set recurrence to 0 since we've already expanded the schedule + recurrenceNumber: 0, + // No days since this is now a single occurrence + days: [] }; }; diff --git a/src/frontend/src/utils/datetime.utils.ts b/src/frontend/src/utils/datetime.utils.ts index 8f9e573351..9012e0567b 100644 --- a/src/frontend/src/utils/datetime.utils.ts +++ b/src/frontend/src/utils/datetime.utils.ts @@ -65,27 +65,88 @@ export const isPastEvent = (startDate: Date, endDate: Date) => { return startDate < endDate; }; -// gets the start time of an event for a given day -export const getConvertedStart = (event: Event, dayOfWeek: DayOfWeek) => { - const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); - - const startTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(Date.now()); - - const convertedStartTime = startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); +// Gets the start time of an event for a given date +// With the new schema, we find the schedule slot that occurs on the specified date +export const getConvertedStart = (event: Event, dateOrDayOfWeek: Date | DayOfWeek) => { + // If passed a DayOfWeek enum, we need to find a slot on that day of the week + // This is for backward compatibility with components that don't have the specific date + if (typeof dateOrDayOfWeek === 'string') { + // It's a DayOfWeek enum - find any slot that matches this day + const dayOfWeekMap: { [key in DayOfWeek]: number } = { + [DayOfWeek.SUNDAY]: 0, + [DayOfWeek.MONDAY]: 1, + [DayOfWeek.TUESDAY]: 2, + [DayOfWeek.WEDNESDAY]: 3, + [DayOfWeek.THURSDAY]: 4, + [DayOfWeek.FRIDAY]: 5, + [DayOfWeek.SATURDAY]: 6 + }; + const targetDayIndex = dayOfWeekMap[dateOrDayOfWeek]; + + const specificSlot = event.scheduledTimes.find((slot) => { + if (!slot.startTime) return false; + const slotDate = new Date(slot.startTime); + return slotDate.getDay() === targetDayIndex; + }); + + const startTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(); + return startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); + } + + // It's a Date object - find the slot for this specific date + const targetDate = dateOrDayOfWeek; + targetDate.setHours(0, 0, 0, 0); + + const specificSlot = event.scheduledTimes.find((slot) => { + if (!slot.startTime) return false; + const slotDate = new Date(slot.startTime); + slotDate.setHours(0, 0, 0, 0); + return slotDate.getTime() === targetDate.getTime(); + }); - return convertedStartTime; + const startTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(); + return startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); }; -// gets the end time of an event for a given day -export const getConvertedEnd = (event: Event, dayOfWeek: DayOfWeek) => { - const specificSlot = event.scheduledTimes.find((slot) => slot.days.find((day) => day === dayOfWeek)); - - const endTime = new Date(specificSlot?.endTime ?? Date.now()); - - const convertedEndTime = endTime.toLocaleTimeString('en-US', { - hour: 'numeric', - minute: '2-digit' +// Gets the end time of an event for a given date +// With the new schema, we find the schedule slot that occurs on the specified date +export const getConvertedEnd = (event: Event, dateOrDayOfWeek: Date | DayOfWeek) => { + // If passed a DayOfWeek enum, we need to find a slot on that day of the week + // This is for backward compatibility with components that don't have the specific date + if (typeof dateOrDayOfWeek === 'string') { + // It's a DayOfWeek enum - find any slot that matches this day + const dayOfWeekMap: { [key in DayOfWeek]: number } = { + [DayOfWeek.SUNDAY]: 0, + [DayOfWeek.MONDAY]: 1, + [DayOfWeek.TUESDAY]: 2, + [DayOfWeek.WEDNESDAY]: 3, + [DayOfWeek.THURSDAY]: 4, + [DayOfWeek.FRIDAY]: 5, + [DayOfWeek.SATURDAY]: 6 + }; + const targetDayIndex = dayOfWeekMap[dateOrDayOfWeek]; + + const specificSlot = event.scheduledTimes.find((slot) => { + if (!slot.endTime) return false; + const slotDate = new Date(slot.endTime); + return slotDate.getDay() === targetDayIndex; + }); + + const endTime = specificSlot?.endTime ? new Date(specificSlot.endTime) : new Date(); + return endTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); + } + + // It's a Date object - find the slot for this specific date + const targetDate = dateOrDayOfWeek; + targetDate.setHours(0, 0, 0, 0); + + const specificSlot = event.scheduledTimes.find((slot) => { + if (!slot.endTime) return false; + const slotDate = new Date(slot.endTime); + slotDate.setHours(0, 0, 0, 0); + return slotDate.getTime() === targetDate.getTime(); }); - return convertedEndTime; + const endTime = specificSlot?.endTime ? new Date(specificSlot.endTime) : new Date(); + return endTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); }; diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index ea9c4d8ef1..304d1687e2 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -477,6 +477,8 @@ const calendarApproveEvent = (id: string) => `${calendar()}/event/${id}/approve` const calendarDenyEvent = (id: string) => `${calendar()}/event/${id}/deny`; const calendarCreateEvent = () => `${calendar()}/event/create`; const calendarEditEvent = (eventId: string) => `${calendar()}/event/${eventId}/edit`; +const calendarEditScheduleSlot = (eventId: string, scheduleSlotId: string) => + `${calendar()}/event/${eventId}/schedule-slot/${scheduleSlotId}/edit`; const calendarUploadDocument = (eventId: string) => `${calendar()}/event/${eventId}/upload-document`; const calendarPDFById = (fileId: string) => `${calendar()}/document/${fileId}`; @@ -820,6 +822,7 @@ export const apiUrls = { calendarApproveEvent, calendarDenyEvent, calendarEditEvent, + calendarEditScheduleSlot, version }; diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 90ccd3d861..4a5f7be6d0 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -99,21 +99,14 @@ export interface Calendar { export interface ScheduleSlot { scheduleSlotId: string; - days: DayOfWeek[]; - startTime?: Date; - endTime?: Date; - recurrenceNumber: number; - initialDateScheduled: Date; - endDate: Date; + startTime: Date; + endTime: Date; allDay: boolean; } export interface ScheduleSlotCreateArgs { - days: DayOfWeek[]; - startTime?: Date; - endTime?: Date; - recurrenceNumber: number; - initialDateScheduled: Date; + startTime: Date; + endTime: Date; allDay: boolean; } @@ -219,6 +212,7 @@ export interface Event { questionDocumentLink?: string; description?: string; status: EventStatus; + initialDateScheduled?: Date; } export type EventPreview = { @@ -254,4 +248,5 @@ export interface EventWithMembers { questionDocumentLink?: string; description?: string; status: EventStatus; + initialDateScheduled?: Date; } From 912fcf8eefb67561b418013402cdc4a9adadf60d Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Tue, 20 Jan 2026 10:07:09 -0500 Subject: [PATCH 470/477] event modal correct abstraction --- .../pages/CalendarPage/CalendarDayCard.tsx | 12 +- .../src/pages/CalendarPage/CalendarTab.tsx | 70 +---- .../Components/CreateEventModal.tsx | 40 ++- .../Components/EditEventModal.tsx | 58 +++- .../CalendarPage/Components/EventModal.tsx | 108 ++++---- .../pages/CalendarPage/EventClickPopup.tsx | 22 +- .../src/pages/CalendarPage/EventsTable.tsx | 33 +-- .../pages/CalendarPage/NewCalendarPage.tsx | 261 +++++++++--------- 8 files changed, 282 insertions(+), 322 deletions(-) diff --git a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx index 171defcb9c..da952352b9 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx @@ -21,8 +21,6 @@ import GroupsIcon from '@mui/icons-material/Groups'; import { EventClickPopup } from './EventClickPopup'; import EventPartialInfoView from './EventPartialInfoView'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; -import { EventRoutePayload } from './Components/EventModal'; -import { EditEventArgs } from '../../hooks/calendar.hooks'; export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { const teamIcons: Map = new Map([ @@ -52,12 +50,6 @@ interface CalendarDayCardProps { eventTypes?: EventType[]; calendars?: Calendar[]; dayOfWeek?: DayOfWeek; - handleEditSubmit: ( - data: EventRoutePayload, - event: Event, - editEvent: (editArgs: EditEventArgs) => Promise, - onClose: () => void - ) => Promise; } const CalendarDayCard: React.FC = ({ @@ -65,8 +57,7 @@ const CalendarDayCard: React.FC = ({ events, eventTypes = [], calendars = [], - dayOfWeek = DayOfWeek.MONDAY, - handleEditSubmit + dayOfWeek = DayOfWeek.MONDAY }) => { const [, setIsCreateModalOpen] = useState(false); const theme = useTheme(); @@ -485,7 +476,6 @@ const CalendarDayCard: React.FC = ({ calendars={calendars} dayOfWeek={dayOfWeek} clickedDate={cardDate} - handleEditSubmit={handleEditSubmit} /> ); diff --git a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx index 7aedec6cfb..6df11b08cf 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx @@ -5,27 +5,17 @@ import { Box } from '@mui/material'; import FullPageTabs from '../../components/FullPageTabs'; import { useState } from 'react'; import { useCurrentUser } from '../../hooks/users.hooks'; -import { Event, ConflictStatus, isHead, isLead } from 'shared'; -import { - EditEventArgs, - useAllCalendars, - useAllEventTypes, - useFilterEvents, - useUploadManyDocuments -} from '../../hooks/calendar.hooks'; +import { ConflictStatus, isHead, isLead } from 'shared'; +import { useAllCalendars, useAllEventTypes, useFilterEvents } from '../../hooks/calendar.hooks'; import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; import EventsTable from './EventsTable'; -import { EventRoutePayload } from './Components/EventModal'; -import { useToast } from '../../hooks/toasts.hooks'; const CalendarTab: React.FC = () => { const [tabIndex, setTabIndex] = useState(0); const user = useCurrentUser(); const canViewReviews = isHead(user.role) || isLead(user.role); - const toast = useToast(); - const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); const tabs = [ { tabUrlValue: 'mainCalendar', tabName: 'Calendar' }, @@ -93,60 +83,6 @@ const CalendarTab: React.FC = () => { if (canViewReviews) tabs.push({ tabUrlValue: 'reviews', tabName: 'Review Bookings' }); - const handleEditSubmit = async ( - data: EventRoutePayload, - event: Event, - editEvent: (editArgs: EditEventArgs) => Promise, - onClose: () => void - ) => { - if (!event) return; - - try { - const { documentFiles, ...eventData } = data; - - // Convert EventRoutePayload to EditEventArgs format - // Note: scheduleSlot and initialDateScheduled are only in EventCreatePayload, not EventEditPayload - const editArgs: EditEventArgs = { - title: eventData.title, - requiredMemberIds: eventData.requiredMemberIds, - optionalMemberIds: eventData.optionalMemberIds, - teamIds: eventData.teamIds, - teamTypeId: eventData.teamTypeId, - location: eventData.location, - zoomLink: eventData.zoomLink, - shopIds: eventData.shopIds, - machineryIds: eventData.machineryIds, - workPackageIds: eventData.workPackageIds, - questionDocumentLink: eventData.questionDocumentLink, - description: eventData.description, - status: event.status, // Use existing event status - documents: event.documents.map((doc) => ({ - name: doc.name, - googleFileId: doc.googleFileId - })) - }; - - const editedEvent = await editEvent(editArgs); - - // Upload new documents if any - const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); - - if (filesToUpload.length > 0) { - await uploadDocuments({ - id: editedEvent.eventId, - files: filesToUpload - }); - } - - toast.success('Event updated successfully!'); - onClose(); - } catch (err) { - if (err instanceof Error) { - toast.error(err.message); - } - } - }; - return ( { reviewEvents={reviewEvents ?? []} yourEvents={yourEvents ?? []} allCalendars={allCalendars} - handleEditSubmit={handleEditSubmit} /> ) : ( { reviewEvents={reviewEvents ?? []} allEventTypes={allEventTypes} allCalendars={allCalendars} - handleEditSubmit={handleEditSubmit} /> )} diff --git a/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx index ad6a607eeb..11fc119416 100644 --- a/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx @@ -1,16 +1,48 @@ -import EventModal, { EventRoutePayload } from './EventModal'; +import React from 'react'; +import EventModal, { EventFormSubmitResult } from './EventModal'; import type { EventType } from 'shared'; +import { useCreateEvent, useUploadManyDocuments } from '../../../hooks/calendar.hooks'; +import { useToast } from '../../../hooks/toasts.hooks'; interface CreateEventModalProps { open: boolean; onClose: () => void; - onSubmit: (data: EventRoutePayload) => void; eventTypes: EventType[]; defaultDate?: Date; } -const CreateEventModal: React.FC = (props) => { - return ; +const CreateEventModal: React.FC = ({ open, onClose, eventTypes, defaultDate }) => { + const toast = useToast(); + const { mutateAsync: createEvent } = useCreateEvent(); + const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); + + const handleSubmit = async ({ basePayload, scheduleSlots, scheduleDate, requiresConfirmation }: EventFormSubmitResult) => { + const { documentFiles, ...eventData } = basePayload; + + const createArgs = { + ...eventData, + initialDateScheduled: scheduleDate, + scheduleSlot: requiresConfirmation ? [] : scheduleSlots, + documentIds: [] + }; + + // Don't wrap in try catch because we want errors to propagate to the modal + const createdEvent = await createEvent(createArgs); + + const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); + if (filesToUpload.length > 0) { + await uploadDocuments({ + id: createdEvent.eventId, + files: filesToUpload + }); + } + + toast.success('Event created successfully!'); + }; + + return ( + + ); }; export default CreateEventModal; diff --git a/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx index 097752ae74..5829cc85ba 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx @@ -1,17 +1,63 @@ -import EventModal, { EventFormValues, EventRoutePayload } from './EventModal'; -import type { EventType } from 'shared'; +import React from 'react'; +import EventModal, { EventFormSubmitResult } from './EventModal'; +import type { Event, EventType } from 'shared'; +import { convertEventToFormValues } from '../../../utils/calendar.utils'; +import { useEditEvent, useUploadManyDocuments } from '../../../hooks/calendar.hooks'; +import { useToast } from '../../../hooks/toasts.hooks'; export interface EditEventModalProps { open: boolean; onClose: () => void; - onSubmit: (data: EventRoutePayload) => void; - initialValues: Partial; + event: Event; eventTypes: EventType[]; defaultDate?: Date; } -const EditEventModal: React.FC = (props) => { - return ; +const EditEventModal: React.FC = ({ open, onClose, event, eventTypes, defaultDate }) => { + const toast = useToast(); + const { mutateAsync: editEvent } = useEditEvent(event.eventId); + const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); + + const initialValues = convertEventToFormValues(event); + const computedDefaultDate = + defaultDate ?? (event.scheduledTimes[0]?.startTime ? new Date(event.scheduledTimes[0].startTime) : new Date()); + + const handleSubmit = async ({ basePayload }: EventFormSubmitResult) => { + const { documentFiles, ...eventData } = basePayload; + + const editArgs = { + ...eventData, + status: event.status, + documents: event.documents.map((doc) => ({ + name: doc.name, + googleFileId: doc.googleFileId + })) + }; + + // Don't wrap in try catch because we want errors to propagate to the modal + const editedEvent = await editEvent(editArgs); + + const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); + if (filesToUpload.length > 0) { + await uploadDocuments({ + id: editedEvent.eventId, + files: filesToUpload + }); + } + + toast.success('Event updated successfully!'); + }; + + return ( + + ); }; export default EditEventModal; diff --git a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx index 0d24cd1ccc..6eacd0b7c6 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx @@ -117,9 +117,19 @@ export interface EventEditPayload { description?: string; } -// Union type for backward compatibility export type EventRoutePayload = EventCreatePayload | EventEditPayload; +export interface EventFormSubmitResult { + basePayload: EventEditPayload; + scheduleSlots: Array<{ + startTime: Date; + endTime: Date; + allDay: boolean; + }>; + scheduleDate: Date; + requiresConfirmation: boolean; +} + const schema = yup.object().shape({ title: yup.string().required('Title is required'), eventTypeId: yup.string().required('Event Type is required'), @@ -146,11 +156,10 @@ const schema = yup.object().shape({ export interface BaseEventModalProps { open: boolean; onClose: () => void; - onSubmit: (data: EventRoutePayload) => Promise | unknown; + onSubmit: (data: EventFormSubmitResult) => Promise | unknown; initialValues?: Partial; eventTypes: EventType[]; defaultDate?: Date; - isEditMode?: boolean; } const EventModal: React.FC = ({ @@ -159,8 +168,7 @@ const EventModal: React.FC = ({ onSubmit, initialValues, eventTypes, - defaultDate = new Date(), - isEditMode = false + defaultDate = new Date() }) => { const toast = useToast(); const user = useCurrentUser(); @@ -296,6 +304,7 @@ const EventModal: React.FC = ({ } }, [open, initialValues?.days]); + const isEditMode = !!initialValues; const computedTitle = isEditMode ? 'Edit Event' : 'Add Event'; // Handle recurring dropdown toggle @@ -415,51 +424,54 @@ const EventModal: React.FC = ({ const onFormSubmit = async (data: EventFormValues) => { try { + const requiresConfirmation = selectedEventType?.requiresConfirmation ?? false; const scheduleSlots: Array<{ startTime: Date; endTime: Date; allDay: boolean; }> = []; - // Helper function to create a date/time for a specific occurrence - const createSlotDateTime = (baseDate: Date, time: Date): Date => { - const result = new Date(baseDate); - result.setHours(time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds()); - return result; - }; - - // Generate schedule slots for recurring events - const dayOfWeekEnum = convertIntToDay(data.scheduleDate.getDay()); - const selectedDays = data.days.length > 0 ? data.days : [dayOfWeekEnum]; - - // Convert selected days to day indices for comparison - const dayIndices = selectedDays.map(convertDayToInt); - - // Generate additional recurring occurrences - let occurrencesGenerated = 0; - const searchDate = new Date(data.scheduleDate); - - const maxDaysToSearch = 365; // Search up to a year - let daysSearched = 0; - - while (occurrencesGenerated < data.recurrenceNumber && daysSearched < maxDaysToSearch) { - const currentDayIndex = searchDate.getDay(); - - if ((dayIndices as number[]).includes(currentDayIndex)) { - scheduleSlots.push({ - startTime: createSlotDateTime(searchDate, data.startTime), - endTime: createSlotDateTime(searchDate, data.endTime), - allDay: data.allDay - }); - occurrencesGenerated++; + // If the event requires confirmation, use startTime for initialDateScheduled and don't add any schedule slots + if (!requiresConfirmation) { + // Helper function to create a date/time for a specific occurrence + const createSlotDateTime = (baseDate: Date, time: Date): Date => { + const result = new Date(baseDate); + result.setHours(time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds()); + return result; + }; + + // Generate schedule slots for recurring events + const dayOfWeekEnum = convertIntToDay(data.scheduleDate.getDay()); + const selectedDays = data.days.length > 0 ? data.days : [dayOfWeekEnum]; + + // Convert selected days to day indices for comparison + const dayIndices = selectedDays.map(convertDayToInt); + + // Generate additional recurring occurrences + let occurrencesGenerated = 0; + const searchDate = new Date(data.scheduleDate); + + const maxDaysToSearch = 365; // Search up to a year + let daysSearched = 0; + + while (occurrencesGenerated < data.recurrenceNumber && daysSearched < maxDaysToSearch) { + const currentDayIndex = searchDate.getDay(); + + if ((dayIndices as number[]).includes(currentDayIndex)) { + scheduleSlots.push({ + startTime: createSlotDateTime(searchDate, data.startTime), + endTime: createSlotDateTime(searchDate, data.endTime), + allDay: data.allDay + }); + occurrencesGenerated++; + } + + searchDate.setDate(searchDate.getDate() + 1); + daysSearched++; } - - searchDate.setDate(searchDate.getDate() + 1); - daysSearched++; } - // Build the appropriate payload based on mode - const basePayload = { + const basePayload: EventEditPayload = { title: data.title, eventTypeId: data.eventTypeId, requiredMemberIds: requiredMembers.map((m) => m.id), @@ -476,14 +488,12 @@ const EventModal: React.FC = ({ description: data.description }; - const submitData: EventRoutePayload = isEditMode - ? basePayload - : { - ...basePayload, - initialDateScheduled: data.scheduleDate, - scheduleSlot: scheduleSlots - }; - await onSubmit(submitData); + await onSubmit({ + basePayload, + scheduleSlots, + scheduleDate: data.scheduleDate, + requiresConfirmation + }); handleClose(); } catch (e: unknown) { if (e instanceof Error) toast.error(e.message); diff --git a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx index 8e39fd96d7..968e1b4314 100644 --- a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx @@ -26,12 +26,10 @@ import DeleteIcon from '@mui/icons-material/Delete'; import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; import NERSuccessButton from '../../components/NERSuccessButton'; import NERFailButton from '../../components/NERFailButton'; -import { EditEventArgs, useApproveEvent, useDeleteEvent, useDenyEvent, useEditEvent } from '../../hooks/calendar.hooks'; -import { convertEventToFormValues } from '../../utils/calendar.utils'; +import { useApproveEvent, useDeleteEvent, useDenyEvent } from '../../hooks/calendar.hooks'; import EditEventModal from './Components/EditEventModal'; import { useToast } from '../../hooks/toasts.hooks'; import NERDeleteModal from '../../components/NERDeleteModal'; -import { EventRoutePayload } from './Components/EventModal'; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ @@ -432,12 +430,6 @@ export interface EventClickPopupProps { disable?: boolean; addApprovalButtons?: boolean; clickedDate?: Date; - handleEditSubmit: ( - data: EventRoutePayload, - event: Event, - editEvent: (editArgs: EditEventArgs) => Promise, - onClose: () => void - ) => Promise; } export const EventClickPopup: React.FC = ({ @@ -449,15 +441,13 @@ export const EventClickPopup: React.FC = ({ dayOfWeek, disable = false, addApprovalButtons = false, - clickedDate, - handleEditSubmit + clickedDate }) => { const toast = useToast(); const [showEditModal, setShowEditModal] = useState(false); const [showDeleteModal, setShowDeleteModal] = useState(false); const { mutateAsync: deleteEvent } = useDeleteEvent(clickedEvent?.eventId ?? ''); - const { mutateAsync: editEvent } = useEditEvent(clickedEvent?.eventId ?? ''); const handleEdit = () => { setShowEditModal(true); @@ -516,13 +506,7 @@ export const EventClickPopup: React.FC = ({ setShowEditModal(false); onClose(); }} - onSubmit={(data) => - handleEditSubmit(data, clickedEvent, editEvent, () => { - setShowEditModal(false); - onClose(); - }) - } - initialValues={convertEventToFormValues(clickedEvent)} + event={clickedEvent} eventTypes={eventTypes} defaultDate={ clickedEvent.scheduledTimes[0]?.startTime ? new Date(clickedEvent.scheduledTimes[0].startTime) : new Date() diff --git a/src/frontend/src/pages/CalendarPage/EventsTable.tsx b/src/frontend/src/pages/CalendarPage/EventsTable.tsx index 8405ece2dd..d396df7534 100644 --- a/src/frontend/src/pages/CalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/CalendarPage/EventsTable.tsx @@ -21,11 +21,10 @@ import React, { useEffect, useState } from 'react'; import { Calendar, ConflictStatus, EventType } from 'shared'; import { Event } from 'shared'; import WarningTooltip from './YourEventsComponents/WarningTooltip'; -import { convertEventToFormValues, getMeetingDates } from '../../utils/calendar.utils'; +import { getMeetingDates } from '../../utils/calendar.utils'; import { EventClickPopup } from './EventClickPopup'; -import { EditEventArgs, useDeleteEvent, useEditEvent } from '../../hooks/calendar.hooks'; +import { useDeleteEvent } from '../../hooks/calendar.hooks'; import EditEventModal from './Components/EditEventModal'; -import { EventRoutePayload } from './Components/EventModal'; import { useToast } from '../../hooks/toasts.hooks'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; @@ -58,12 +57,6 @@ export interface EventTableArgs { allEventTypes: EventType[]; allCalendars: Calendar[]; tab: number; - handleEditSubmit: ( - data: EventRoutePayload, - event: Event, - editEvent: (editArgs: EditEventArgs) => Promise, - onClose: () => void - ) => Promise; } // trigger re-renders specifically for the timer @@ -103,14 +96,7 @@ const CountdownElement = ({ targetDate }: { targetDate: Date }) => { ); }; -const EventsTable: React.FC = ({ - tab, - yourEvents, - reviewEvents, - allEventTypes, - allCalendars, - handleEditSubmit -}) => { +const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, allEventTypes, allCalendars }) => { // Convert to include proper dates // Done this way to allow the old events transformer to function properly // but provide better utility to this file (without breaking other files that may rely on eventTransformer) @@ -125,8 +111,6 @@ const EventsTable: React.FC = ({ const [eventToDelete, setEventToDelete] = useState(undefined); - const { mutateAsync: editEvent } = useEditEvent(clickedEditEvent?.eventId ?? ''); - const handleOpenClickPopup = (event: Event) => { setClickedEvent(event); if (typeof window !== 'undefined') { @@ -400,21 +384,12 @@ const EventsTable: React.FC = ({ onClose={handleCloseClickPopup} eventTypes={allEventTypes} calendars={allCalendars} - disable={true} - addApprovalButtons={true} - handleEditSubmit={handleEditSubmit} /> {clickedEditEvent && showEditModal && ( { - handleEditSubmit(data, clickedEditEvent, editEvent, () => { - setShowEditModal(false); - handleCloseEdit(); - }); - }} - initialValues={convertEventToFormValues(clickedEditEvent)} + event={clickedEditEvent} eventTypes={allEventTypes} defaultDate={new Date()} /> diff --git a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx index 29e935fb1e..f7793f6412 100644 --- a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx @@ -20,13 +20,7 @@ import PageLayout from '../../components/PageLayout'; import { Calendar, ConflictStatus, DayOfWeek, Event, EventType } from 'shared'; import CalendarDayCard from './CalendarDayCard'; import { DAY_NAMES, enumToArray, calendarPaddingDays, daysInMonth } from '../../utils/design-review.utils'; -import { - useConflictingEvents, - useFilterEvents, - useCreateEvent, - useUploadManyDocuments, - EditEventArgs -} from '../../hooks/calendar.hooks'; +import { useConflictingEvents, useFilterEvents } from '../../hooks/calendar.hooks'; import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; @@ -38,8 +32,6 @@ import { useCurrentUser } from '../../hooks/users.hooks'; import { useGetUsersTeams } from '../../hooks/teams.hooks'; import { convertIntToDay, getEventsFlattened, getMeetingDates, getOverlapTime } from '../../utils/calendar.utils'; import CreateEventModal from './Components/CreateEventModal'; -import { EventRoutePayload } from './Components/EventModal'; -import { useToast } from '../../hooks/toasts.hooks'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; import WarningIcon from '@mui/icons-material/Warning'; import { useHistory } from 'react-router-dom'; @@ -53,22 +45,9 @@ interface NewCalendarPageProps { yourEvents: Event[]; reviewEvents: Event[]; allCalendars: Calendar[]; - handleEditSubmit: ( - data: EventRoutePayload, - event: Event, - editEvent: (editArgs: EditEventArgs) => Promise, - onClose: () => void - ) => Promise; } -const NewCalendarPage: React.FC = ({ - allEventTypes, - yourEvents, - reviewEvents, - allCalendars, - handleEditSubmit -}) => { - const toast = useToast(); +const NewCalendarPage: React.FC = ({ allEventTypes, yourEvents, reviewEvents, allCalendars }) => { const theme = useTheme(); const { data: allTeamTypes, @@ -168,9 +147,6 @@ const NewCalendarPage: React.FC = ({ const conflictingReviewEvents = untransformedConflictingReviewEvents?.map(filterEventTransformer); - const { mutateAsync: createEvent } = useCreateEvent(); - const { isLoading: documentsIsLoading, mutateAsync: uploadDocuments } = useUploadManyDocuments(); - const [upcomingStartPeriod] = useState(() => new Date()); const [upcomingEndPeriod] = useState(() => { @@ -237,8 +213,7 @@ const NewCalendarPage: React.FC = ({ conflictingDeniedEventsLoading || !conflictingDeniedEvents || conflictingReviewEventsLoading || - !conflictingReviewEvents || - documentsIsLoading + !conflictingReviewEvents ) return ; @@ -302,49 +277,12 @@ const NewCalendarPage: React.FC = ({ if (!allTeams || allTeamsLoading) return ; if (allTeamsIsError) return ; - const handleCreateEvent = async (data: EventRoutePayload) => { - try { - // Type guard to ensure we have a create payload with schedule slots - if (!('scheduleSlot' in data) || !('initialDateScheduled' in data)) { - throw new Error('Invalid payload for creating event'); - } - - const { documentFiles, ...eventData } = data; - - // Create the event first without documents - // EventModal already generates the schedule slots with actual dates/times - const createArgs = { - ...eventData, - documentIds: [] - }; - - const createdEvent = await createEvent(createArgs); - - const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); - - if (filesToUpload.length > 0) { - await uploadDocuments({ - id: createdEvent.eventId, - files: filesToUpload - }); - } - - toast.success('Event created successfully!'); - setIsCreateModalOpen(false); - } catch (err) { - if (err instanceof Error) { - toast.error(err.message); - } - } - }; - return ( <> {isCreateModalOpen && ( setIsCreateModalOpen(false)} - onSubmit={handleCreateEvent} eventTypes={allEventTypes} defaultDate={displayMonthYear} /> @@ -547,7 +485,6 @@ const NewCalendarPage: React.FC = ({ dayDict.get(datePipe(new Date(cardDate.getTime() + cardDate.getTimezoneOffset() * 60000))) ?? DayOfWeek.SUNDAY } - handleEditSubmit={handleEditSubmit} /> @@ -566,49 +503,68 @@ const NewCalendarPage: React.FC = ({ gap: 2 }} > - setDisplayMonthYear(newDate)} - onChange={(newDate) => { - if (newDate) setDisplayMonthYear(newDate); - }} - slotProps={{ - day: { - sx: { - '&.Mui-selected': { - bgcolor: 'red', - '&:hover': { - bgcolor: 'darkred' - }, - '&:focus': { - bgcolor: 'red' + + setDisplayMonthYear(newDate)} + onChange={(newDate) => { + if (newDate) setDisplayMonthYear(newDate); + }} + slotProps={{ + day: { + sx: { + '&.Mui-selected': { + bgcolor: 'red', + '&:hover': { + bgcolor: 'darkred' + }, + '&:focus': { + bgcolor: 'red' + } } } } - } + }} + /> + + + + + + {/* Upcoming Meetings Section */} + - - - + > + My Upcoming Meetings: {upcomingOccurences && ( {upcomingOccurences?.map((event) => ( @@ -621,46 +577,79 @@ const NewCalendarPage: React.FC = ({ ))} )} - {/* Calendar Selector */} - - - t.typography.h4.fontFamily, - fontWeight: 400, - fontSize: 22 - }} - > - Calendars: - + - -
    - - {calendars.length > 0 && ( + backgroundColor: 'rgba(255, 255, 255, 0.1)' + } + }} + > + More Filters + +
    + + {calendars.length > 0 && ( + {calendars.map((cal) => { const { calendarId, color } = cal; @@ -702,8 +691,8 @@ const NewCalendarPage: React.FC = ({ ); })} - )} - + + )} From 5bf7d380c5cd9ca25a0d1d4b9d108612b3b2ca8a Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Thu, 22 Jan 2026 08:32:13 -0500 Subject: [PATCH 471/477] event instance refactor to make display logic much simpler --- .../src/controllers/calendar.controllers.ts | 9 +- .../20260111001906_calendar/migration.sql | 2 +- src/backend/src/prisma/seed.ts | 12 +- src/backend/src/routes/calendar.routes.ts | 9 +- src/backend/src/services/calendar.services.ts | 142 ++++++++--- src/backend/src/utils/calendar.utils.ts | 10 +- src/frontend/src/apis/calendar.api.ts | 8 +- src/frontend/src/hooks/calendar.hooks.ts | 7 +- .../pages/CalendarPage/CalendarDayCard.tsx | 22 +- .../src/pages/CalendarPage/CalendarTab.tsx | 5 +- .../Components/CreateEventModal.tsx | 110 ++++++-- .../Components/EditEventModal.tsx | 86 ++++--- .../CalendarPage/Components/EventModal.tsx | 237 +++++++----------- .../pages/CalendarPage/EventClickPopup.tsx | 45 +--- .../CalendarPage/EventPartialInfoView.tsx | 23 +- .../src/pages/CalendarPage/EventsTable.tsx | 21 +- .../pages/CalendarPage/NewCalendarPage.tsx | 48 ++-- .../CalendarPage/UpcomingMeetingsCard.tsx | 11 +- src/frontend/src/utils/calendar.utils.ts | 58 +---- src/frontend/src/utils/datetime.utils.ts | 87 +------ src/shared/src/types/calendar-types.ts | 2 + 21 files changed, 469 insertions(+), 485 deletions(-) diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 3a9c29bb89..02b6fd71e3 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -273,7 +273,7 @@ export default class CalendarController { shopIds, machineryIds, workPackageIds, - scheduleSlot, + scheduleSlots, initialDateScheduled, questionDocumentLink, location, @@ -281,7 +281,7 @@ export default class CalendarController { description } = req.body; - const parsedScheduleSlot = scheduleSlot.map((slot: any) => ({ + const parsedScheduleSlots = scheduleSlots.map((slot: any) => ({ startTime: slot.startTime ? new Date(slot.startTime) : undefined, endTime: slot.endTime ? new Date(slot.endTime) : undefined, allDay: slot.allDay @@ -300,7 +300,7 @@ export default class CalendarController { shopIds, machineryIds, workPackageIds, - parsedScheduleSlot, + parsedScheduleSlots, parsedInitialDateScheduled, teamTypeId, questionDocumentLink, @@ -363,7 +363,7 @@ export default class CalendarController { static async editScheduleSlot(req: Request, res: Response, next: NextFunction) { try { const { scheduleSlotId } = req.params as Record; - const { startTime, endTime, allDay } = req.body; + const { startTime, endTime, allDay, editAllInSeries } = req.body; const event = await CalendarService.editScheduleSlot( req.currentUser, @@ -371,6 +371,7 @@ export default class CalendarController { new Date(startTime), new Date(endTime), allDay, + editAllInSeries ?? false, req.organization ); res.status(200).json(event); diff --git a/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql b/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql index d8bbfc11b1..3833d48c7c 100644 --- a/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql +++ b/src/backend/src/prisma/migrations/20260111001906_calendar/migration.sql @@ -79,7 +79,7 @@ CREATE TABLE "public"."Event" ( "approvalRequiredFromUserId" TEXT, "location" TEXT, "zoomLink" TEXT, - "initialDateScheduled" DATE NOT NULL, + "initialDateScheduled" TIMESTAMP(3), "questionDocumentLink" TEXT, "description" TEXT, "teamTypeId" TEXT, diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 7831bccd64..8b641d8659 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -3205,7 +3205,7 @@ const performSeed: () => Promise = async () => { true, false, false, - true, + false, false ); @@ -3414,14 +3414,8 @@ const performSeed: () => Promise = async () => { [], [], [workPackage1.id], - [ - { - startTime: new Date('2025-10-22T14:00:00.000Z'), - endTime: new Date('2025-10-22T16:00:00.000Z'), - allDay: false - } - ], - undefined, + [], + weeksFromNow(1), software.teamTypeId, 'https://docs.google.com/document/d/2_example', 'Conference Room B', diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 8c187848a8..7519f03949 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -5,7 +5,6 @@ import { isDate, nonEmptyString, validateInputs, - isDayOfWeek, isEventStatus, isConflictStatus, requireFile @@ -115,10 +114,10 @@ calendarRouter.post( body('questionDocumentLink').optional().isString(), body('description').optional().isString(), isDate(body('initialDateScheduled')), - body('scheduleSlot').isArray(), - isDate(body('scheduleSlot.*.startTime')), - isDate(body('scheduleSlot.*.endTime')), - body('scheduleSlot.*.allDay').isBoolean(), + body('scheduleSlots').isArray(), + isDate(body('scheduleSlots.*.startTime')), + isDate(body('scheduleSlots.*.endTime')), + body('scheduleSlots.*.allDay').isBoolean(), validateInputs, CalendarController.createEvent ); diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index efbfb92408..2ac054ef84 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -48,7 +48,6 @@ import { } from '../utils/errors.utils.js'; import { createCalendarEvent, - updateCalendarEvent, uploadFile, downloadFile, deleteCalendarEvents @@ -421,18 +420,6 @@ export default class CalendarService { // Check for conflicts using expanded slots const { hasConflict, conflictingEvent } = await checkEventConflicts(scheduleSlots, organization, location, undefined); - const duplicate = await prisma.event.findFirst({ - where: { - dateDeleted: null, - title: { equals: title, mode: 'insensitive' }, - // scope to org via related eventType - eventType: { organizationId: organization.organizationId } - } - }); - if (duplicate) { - throw new HttpException(409, "Can't have two events with the same title"); - } - const newEvent = await prisma.event.create({ data: { userCreatedId: submitter.userId, @@ -850,6 +837,7 @@ export default class CalendarService { * @param startTime The new start time. * @param endTime The new end time. * @param allDay Whether this is an all-day event. + * @param editAllInSeries If true, edits all schedule slots with matching time-of-day. * @param organization The organization context. * * @returns The updated event. @@ -863,20 +851,38 @@ export default class CalendarService { startTime: Date, endTime: Date, allDay: boolean, + editAllInSeries: boolean, organization: Organization ): Promise { - // Validate schedule slot exists and belongs to this event + // Validate schedule slot exists and get its eventId const scheduleSlot = await prisma.schedule_Slot.findUnique({ where: { scheduleSlotId }, - include: { event: true } + select: { + scheduleSlotId: true, + eventId: true + } }); if (!scheduleSlot) throw new NotFoundException('Schedule Slot', scheduleSlotId); + // Now fetch the event separately to check permissions + const event = await prisma.event.findUnique({ + where: { eventId: scheduleSlot.eventId }, + select: { + eventId: true, + userCreatedId: true, + location: true, + dateDeleted: true + } + }); + + if (!event) throw new NotFoundException('Event', scheduleSlot.eventId); + if (event.dateDeleted) throw new DeletedException('Event', scheduleSlot.eventId); + // Check permissions const hasPermission = (await userHasPermission(submitter.userId, organization.organizationId, isHead)) || - submitter.userId === scheduleSlot.event.userCreatedId; + submitter.userId === event.userCreatedId; if (!hasPermission) { throw new AccessDeniedException('Only admins, heads, or the event creator can edit the times of an event!'); @@ -892,24 +898,104 @@ export default class CalendarService { const { hasConflict, conflictingEvent } = await checkEventConflicts( [newSlotData], organization, - scheduleSlot.event.location ?? undefined, - scheduleSlot.event.eventId + event.location ?? undefined, + event.eventId ); - // Update the schedule slot - await prisma.schedule_Slot.update({ - where: { scheduleSlotId }, - data: { - startTime: startTime ?? null, - endTime: endTime ?? null, - allDay + // Determine which slots to update + let slotsToUpdate: string[] = [scheduleSlotId]; + + if (editAllInSeries) { + // Fetch all schedule slots for this event + const allSlots = await prisma.schedule_Slot.findMany({ + where: { eventId: scheduleSlot.eventId }, + select: { + scheduleSlotId: true, + startTime: true, + endTime: true + } + }); + + // Get the original slot's time-of-day + const originalSlot = allSlots.find((s) => s.scheduleSlotId === scheduleSlotId); + if (originalSlot && originalSlot.startTime && originalSlot.endTime) { + const originalStartHour = originalSlot.startTime.getHours(); + const originalStartMinute = originalSlot.startTime.getMinutes(); + const originalEndHour = originalSlot.endTime.getHours(); + const originalEndMinute = originalSlot.endTime.getMinutes(); + + // Find all slots that have the same time-of-day + slotsToUpdate = allSlots + .filter((slot) => { + if (!slot.startTime || !slot.endTime) return false; + return ( + slot.startTime.getHours() === originalStartHour && + slot.startTime.getMinutes() === originalStartMinute && + slot.endTime.getHours() === originalEndHour && + slot.endTime.getMinutes() === originalEndMinute + ); + }) + .map((slot) => slot.scheduleSlotId); } + } + + // Calculate the time offset from the original slot to the new time + const originalSlot = await prisma.schedule_Slot.findUnique({ + where: { scheduleSlotId }, + select: { startTime: true, endTime: true } }); + if (!originalSlot || !originalSlot.startTime) { + throw new NotFoundException('Schedule Slot', scheduleSlotId); + } + + // Update all matching schedule slots + for (const slotId of slotsToUpdate) { + const currentSlot = await prisma.schedule_Slot.findUnique({ + where: { scheduleSlotId: slotId }, + select: { startTime: true, endTime: true } + }); + + if (!currentSlot || !currentSlot.startTime || !currentSlot.endTime) continue; + + // For the clicked slot, use the exact new times provided + if (slotId === scheduleSlotId) { + await prisma.schedule_Slot.update({ + where: { scheduleSlotId: slotId }, + data: { + startTime, + endTime, + allDay + } + }); + } else { + // For other slots in the series, preserve their date but update time-of-day + const newSlotStart = new Date(currentSlot.startTime); + newSlotStart.setHours( + startTime.getHours(), + startTime.getMinutes(), + startTime.getSeconds(), + startTime.getMilliseconds() + ); + + const newSlotEnd = new Date(currentSlot.endTime); + newSlotEnd.setHours(endTime.getHours(), endTime.getMinutes(), endTime.getSeconds(), endTime.getMilliseconds()); + + await prisma.schedule_Slot.update({ + where: { scheduleSlotId: slotId }, + data: { + startTime: newSlotStart, + endTime: newSlotEnd, + allDay + } + }); + } + } + // Update conflict status if needed if (hasConflict) { await prisma.event.update({ - where: { eventId: scheduleSlot.event.eventId }, + where: { eventId: event.eventId }, data: { approved: Conflict_Status.PENDING, approvalRequiredFromUserId: conflictingEvent?.userCreated.userId @@ -919,11 +1005,11 @@ export default class CalendarService { // Fetch and return the updated event const updatedEvent = await prisma.event.findUnique({ - where: { eventId: scheduleSlot.event.eventId }, + where: { eventId: event.eventId }, ...getEventQueryArgs(organization.organizationId) }); - if (!updatedEvent) throw new NotFoundException('Event', scheduleSlot.event.eventId); + if (!updatedEvent) throw new NotFoundException('Event', event.eventId); return eventTransformer(updatedEvent); } diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index 9424733b6c..df86da66b1 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -134,12 +134,16 @@ export function validateEventTypeConfiguration( throw new InvalidEventTypeConfigurationException('a question document'); } - // For requiresConfirmation events, schedule slots are optional initially - // For normal events, we need at least the initialDateScheduled - if (!eventType.requiresConfirmation && !eventData.initialDateScheduled) { + // For requiresConfirmation events, the event must have an initialDateScheduled + if (eventType.requiresConfirmation && !eventData.initialDateScheduled) { throw new InvalidEventTypeConfigurationException('an initial date scheduled'); } + // For non-requiresConfirmation events, there must be at least one schedule slot + if (!eventType.requiresConfirmation && eventData.scheduleSlots.length === 0) { + throw new InvalidEventTypeConfigurationException('at least one schedule slot'); + } + // Check disallowed fields (inverse validation) if (!eventType.requiredMembers && eventData.requiredMemberIds.length > 0) { throw new InvalidEventTypeConfigurationException('Event type does not allow required members'); diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index e0cc9e8790..feec988c46 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -12,7 +12,7 @@ import { FilterArgs } from 'shared'; import { eventTransformer } from './transformers/calendar.transformer'; -import { EditEventArgs, EventCreateArgs } from '../hooks/calendar.hooks'; +import { EditEventArgs, EditScheduleSlotArgs, EventCreateArgs } from '../hooks/calendar.hooks'; export const getAllCalendars = () => { return axios.get(apiUrls.calendarCalendars(), { @@ -200,11 +200,7 @@ export const postEditEvent = async (eventId: string, payload: EditEventArgs) => }); }; -export const postEditScheduleSlot = async ( - eventId: string, - scheduleSlotId: string, - payload: { startTime?: Date; endTime?: Date; allDay: boolean } -) => { +export const postEditScheduleSlot = async (eventId: string, scheduleSlotId: string, payload: EditScheduleSlotArgs) => { return axios.post(apiUrls.calendarEditScheduleSlot(eventId, scheduleSlotId), payload, { transformResponse: (data) => eventTransformer(JSON.parse(data)) }); diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 592b53e43b..809c889caf 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -74,7 +74,7 @@ export interface EventCreateArgs { questionDocument?: string; description?: string; initialDateScheduled: Date; - scheduleSlot: ScheduleSlotCreateArgs[]; + scheduleSlots: ScheduleSlotCreateArgs[]; } export interface EditEventArgs { @@ -95,9 +95,10 @@ export interface EditEventArgs { } export interface EditScheduleSlotArgs { - startTime?: Date; - endTime?: Date; + startTime: Date; + endTime: Date; allDay: boolean; + editAllInSeries: boolean; } export interface DownloadDocumentsFormInput { diff --git a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx index da952352b9..c8c72f2e0a 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { Box, Card, CardContent, Grid, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; -import { Calendar, DayOfWeek, Event, EventType } from 'shared'; +import { Calendar, DayOfWeek, EventInstance, EventType } from 'shared'; import ConstructionIcon from '@mui/icons-material/Construction'; import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices'; @@ -17,10 +17,9 @@ import DescriptionIcon from '@mui/icons-material/Description'; import ArticleIcon from '@mui/icons-material/Article'; import HelpIcon from '@mui/icons-material/Help'; import GroupsIcon from '@mui/icons-material/Groups'; - import { EventClickPopup } from './EventClickPopup'; import EventPartialInfoView from './EventPartialInfoView'; -import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; +import { formatTime } from '../../utils/datetime.utils'; export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { const teamIcons: Map = new Map([ @@ -46,7 +45,7 @@ export const getStatusIcon = (status: string, isLarge?: boolean) => { interface CalendarDayCardProps { cardDate: Date; - events: Event[]; + events: EventInstance[]; eventTypes?: EventType[]; calendars?: Calendar[]; dayOfWeek?: DayOfWeek; @@ -66,10 +65,10 @@ const CalendarDayCard: React.FC = ({ const isCurrentDay = cardDate.toDateString() === today; const isFutureDay = cardDate >= new Date(); - const [clickedEvent, setClickedEvent] = useState(); + const [clickedEvent, setClickedEvent] = useState(); const [anchorPosition, setAnchorPosition] = useState<{ top: number; left: number }>(); - const handleOpenClickPopup = (event: Event) => { + const handleOpenClickPopup = (event: EventInstance) => { setClickedEvent(event); if (typeof window !== 'undefined') { setAnchorPosition({ @@ -103,10 +102,8 @@ const CalendarDayCard: React.FC = ({ ); - const EventPopupInfo = ({ event, color }: { event: Event; color: string }) => { + const EventPopupInfo = ({ event, color }: { event: EventInstance; color: string }) => { const name = event.title; - const convertedStartTime = getConvertedStart(event, dayOfWeek); - const convertedEndTime = getConvertedEnd(event, dayOfWeek); return ( <> @@ -142,7 +139,7 @@ const CalendarDayCard: React.FC = ({ noWrap align="left" > - {convertedStartTime} - {convertedEndTime} + {event.allDay ? 'All Day' : `${formatTime(event.startTime)} - ${formatTime(event.endTime)}`} @@ -292,7 +289,7 @@ const CalendarDayCard: React.FC = ({ ); }; - const EventCard = ({ event }: { event: Event }) => { + const EventCard = ({ event }: { event: EventInstance }) => { const specificEventType = eventTypes.find((eventType) => eventType.eventTypeId === event.eventTypeId); const specificCalendar = calendars.find((calendar) => calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) @@ -366,7 +363,7 @@ const CalendarDayCard: React.FC = ({ ); }; - const ExtraEventsCard = ({ extraEvents }: { extraEvents: Event[] }) => { + const ExtraEventsCard = ({ extraEvents }: { extraEvents: EventInstance[] }) => { return ( = ({ key={event.eventId} event={event} onClick={() => handleOpenClickPopup(event)} - dayOfWeek={dayOfWeek} calendars={calendars} eventTypes={eventTypes} /> diff --git a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx index 6df11b08cf..1473638735 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx @@ -103,7 +103,10 @@ const CalendarTab: React.FC = () => { event.scheduledTimes.map((scheduledTime) => ({ ...event, ...scheduledTime }))) ?? + [] + } allCalendars={allCalendars} /> ) : ( diff --git a/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx index 11fc119416..022e570544 100644 --- a/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/CreateEventModal.tsx @@ -1,8 +1,9 @@ import React from 'react'; -import EventModal, { EventFormSubmitResult } from './EventModal'; -import type { EventType } from 'shared'; +import EventModal, { EventPayload } from './EventModal'; +import type { EventType, EventDocumentUploadArgs } from 'shared'; import { useCreateEvent, useUploadManyDocuments } from '../../../hooks/calendar.hooks'; import { useToast } from '../../../hooks/toasts.hooks'; +import { convertDayToInt } from '../../../utils/calendar.utils'; interface CreateEventModalProps { open: boolean; @@ -16,32 +17,93 @@ const CreateEventModal: React.FC = ({ open, onClose, even const { mutateAsync: createEvent } = useCreateEvent(); const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); - const handleSubmit = async ({ basePayload, scheduleSlots, scheduleDate, requiresConfirmation }: EventFormSubmitResult) => { - const { documentFiles, ...eventData } = basePayload; - - const createArgs = { - ...eventData, - initialDateScheduled: scheduleDate, - scheduleSlot: requiresConfirmation ? [] : scheduleSlots, - documentIds: [] - }; - - // Don't wrap in try catch because we want errors to propagate to the modal - const createdEvent = await createEvent(createArgs); - - const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); - if (filesToUpload.length > 0) { - await uploadDocuments({ - id: createdEvent.eventId, - files: filesToUpload - }); - } + const handleSubmit = async (payload: EventPayload) => { + try { + const { documentFiles, createScheduleSlotArgs, initialDateScheduled, ...eventData } = payload; + + const scheduleSlots: Array<{ + startTime: Date; + endTime: Date; + allDay: boolean; + }> = []; + + // Generate schedule slots from createScheduleSlotArgs if provided + if (createScheduleSlotArgs) { + const { startTime, endTime, days, recurrenceNumber, allDay } = createScheduleSlotArgs; + + // Helper function to create a date/time for a specific occurrence + const createSlotDateTime = (baseDate: Date, time: Date): Date => { + const result = new Date(baseDate); + result.setHours(time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds()); + return result; + }; + + // Convert selected days to day indices for comparison + const dayIndices = days.map(convertDayToInt); + + // Generate recurring occurrences + let occurrencesGenerated = 0; + const searchDate = new Date(startTime); + + const maxDaysToSearch = 365; // Search up to a year + let daysSearched = 0; - toast.success('Event created successfully!'); + while (occurrencesGenerated < recurrenceNumber && daysSearched < maxDaysToSearch) { + const currentDayIndex = searchDate.getDay(); + + if ((dayIndices as number[]).includes(currentDayIndex)) { + scheduleSlots.push({ + startTime: createSlotDateTime(searchDate, startTime), + endTime: createSlotDateTime(searchDate, endTime), + allDay + }); + occurrencesGenerated++; + } + + searchDate.setDate(searchDate.getDate() + 1); + daysSearched++; + } + } + + const createArgs = { + ...eventData, + initialDateScheduled: initialDateScheduled ?? new Date(), + scheduleSlots, + documentIds: [] + }; + + const createdEvent = await createEvent(createArgs); + + const filesToUpload = documentFiles + .map((doc: EventDocumentUploadArgs) => doc.file) + .filter((file: File | undefined): file is File => file !== undefined); + if (filesToUpload.length > 0) { + await uploadDocuments({ + id: createdEvent.eventId, + files: filesToUpload + }); + } + + toast.success('Event created successfully!'); + } catch (e: unknown) { + if (e instanceof Error) { + toast.error(e.message, 5000); + } else { + toast.error('Failed to create event', 5000); + } + throw e; + } }; return ( - + ); }; diff --git a/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx index 5829cc85ba..48af6347f5 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx @@ -1,61 +1,81 @@ import React from 'react'; -import EventModal, { EventFormSubmitResult } from './EventModal'; -import type { Event, EventType } from 'shared'; +import EventModal, { EventPayload } from './EventModal'; +import type { EventInstance, EventType, EventDocumentUploadArgs } from 'shared'; import { convertEventToFormValues } from '../../../utils/calendar.utils'; -import { useEditEvent, useUploadManyDocuments } from '../../../hooks/calendar.hooks'; +import { useEditEvent, useEditScheduleSlot, useUploadManyDocuments } from '../../../hooks/calendar.hooks'; import { useToast } from '../../../hooks/toasts.hooks'; export interface EditEventModalProps { open: boolean; onClose: () => void; - event: Event; + event: EventInstance; eventTypes: EventType[]; - defaultDate?: Date; } -const EditEventModal: React.FC = ({ open, onClose, event, eventTypes, defaultDate }) => { +const EditEventModal: React.FC = ({ open, onClose, event, eventTypes }) => { const toast = useToast(); const { mutateAsync: editEvent } = useEditEvent(event.eventId); + const { mutateAsync: editScheduleSlot } = useEditScheduleSlot(event.eventId, event.scheduleSlotId); const { mutateAsync: uploadDocuments } = useUploadManyDocuments(); const initialValues = convertEventToFormValues(event); - const computedDefaultDate = - defaultDate ?? (event.scheduledTimes[0]?.startTime ? new Date(event.scheduledTimes[0].startTime) : new Date()); - - const handleSubmit = async ({ basePayload }: EventFormSubmitResult) => { - const { documentFiles, ...eventData } = basePayload; - - const editArgs = { - ...eventData, - status: event.status, - documents: event.documents.map((doc) => ({ - name: doc.name, - googleFileId: doc.googleFileId - })) - }; - - // Don't wrap in try catch because we want errors to propagate to the modal - const editedEvent = await editEvent(editArgs); - - const filesToUpload = documentFiles.map((doc) => doc.file).filter((file): file is File => file !== undefined); - if (filesToUpload.length > 0) { - await uploadDocuments({ - id: editedEvent.eventId, - files: filesToUpload - }); - } - toast.success('Event updated successfully!'); + const handleSubmit = async (payload: EventPayload) => { + try { + const { documentFiles, editScheduleSlotArgs, ...eventData } = payload; + + // First, update the event base information + const editArgs = { + ...eventData, + status: event.status, + documents: event.documents.map((doc) => ({ + name: doc.name, + googleFileId: doc.googleFileId + })) + }; + + const editedEvent = await editEvent(editArgs); + + // If there are schedule slot changes, update the schedule slot separately + if (editScheduleSlotArgs) { + await editScheduleSlot({ + startTime: editScheduleSlotArgs.newStartTime, + endTime: editScheduleSlotArgs.newEndTime, + allDay: editScheduleSlotArgs.newAllDay, + editAllInSeries: editScheduleSlotArgs.editAllInSeries + }); + } + + // Handle document uploads + const filesToUpload = documentFiles + .map((doc: EventDocumentUploadArgs) => doc.file) + .filter((file: File | undefined): file is File => file !== undefined); + if (filesToUpload.length > 0) { + await uploadDocuments({ + id: editedEvent.eventId, + files: filesToUpload + }); + } + + toast.success('Event updated successfully!'); + } catch (e: unknown) { + if (e instanceof Error) { + toast.error(e.message, 5000); + } else { + toast.error('Failed to update event', 5000); + } + throw e; + } }; return ( ); }; diff --git a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx index 6eacd0b7c6..43b8184b16 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx @@ -75,9 +75,10 @@ export interface EventFormValues { allDay: boolean; recurrenceNumber: number; days: DayOfWeek[]; + selectedScheduleSlotId?: string; } -export interface EventCreatePayload { +export interface EventPayload { title: string; eventTypeId: string; requiredMemberIds: string[]; @@ -92,42 +93,24 @@ export interface EventCreatePayload { documentFiles: EventDocumentUploadArgs[]; questionDocumentLink?: string; description?: string; - initialDateScheduled: Date; - scheduleSlot: Array<{ + // If the event type requires confirmation, only intialDateScheduled will be populated. If not, + // scheduleSlots will be populated based on if the event is being editted or created + initialDateScheduled?: Date; + createScheduleSlotArgs?: { startTime: Date; endTime: Date; + days: DayOfWeek[]; + recurrenceNumber: number; allDay: boolean; - }>; -} - -export interface EventEditPayload { - title: string; - eventTypeId: string; - requiredMemberIds: string[]; - optionalMemberIds: string[]; - teamIds: string[]; - teamTypeId?: string; - location?: string; - zoomLink?: string; - shopIds: string[]; - machineryIds: string[]; - workPackageIds: string[]; - documentFiles: EventDocumentUploadArgs[]; - questionDocumentLink?: string; - description?: string; -} - -export type EventRoutePayload = EventCreatePayload | EventEditPayload; - -export interface EventFormSubmitResult { - basePayload: EventEditPayload; - scheduleSlots: Array<{ - startTime: Date; - endTime: Date; - allDay: boolean; - }>; - scheduleDate: Date; - requiresConfirmation: boolean; + }; + // For editing, only single schedule slots can be editted (and optionally propogated) + editScheduleSlotArgs?: { + scheduleSlotId: string; + newStartTime: Date; + newEndTime: Date; + newAllDay: boolean; + editAllInSeries: boolean; + }; } const schema = yup.object().shape({ @@ -150,13 +133,14 @@ const schema = yup.object().shape({ endTime: yup.date().required('End time is required'), allDay: yup.boolean().required(), recurrenceNumber: yup.number().min(0).required('Recurrence is required'), - days: yup.array().of(yup.mixed().required()).default([]) + days: yup.array().of(yup.mixed().required()).default([]), + selectedScheduleSlotId: yup.string().optional() }); export interface BaseEventModalProps { open: boolean; onClose: () => void; - onSubmit: (data: EventFormSubmitResult) => Promise | unknown; + onSubmit: (data: EventPayload) => Promise | unknown; initialValues?: Partial; eventTypes: EventType[]; defaultDate?: Date; @@ -193,6 +177,7 @@ const EventModal: React.FC = ({ const { isLoading: teamsLoading, isError: teamsError, error: teamsErrorMsg, data: teams } = useAllTeamPreviews(); const { isError: teamTypesError, error: teamTypesErrorMsg, data: teamTypes } = useAllTeamTypes(); + // Compute default form values - memo ensures stable reference const defaultFormData = useMemo( () => ({ title: initialValues?.title ?? '', @@ -213,8 +198,9 @@ const EventModal: React.FC = ({ startTime: initialValues?.startTime ?? new Date(), endTime: initialValues?.endTime ?? new Date(), allDay: initialValues?.allDay ?? false, - recurrenceNumber: initialValues?.recurrenceNumber ?? 1, - days: initialValues?.days ?? [] + recurrenceNumber: 0, + days: [], + selectedScheduleSlotId: initialValues?.selectedScheduleSlotId }), [initialValues, defaultDate] ); @@ -267,42 +253,37 @@ const EventModal: React.FC = ({ }); }, [machinery, shops, shopIds]); + // Initialize autocomplete states when data loads - runs only on mount or when dependencies change useEffect(() => { - if (open) { - reset(defaultFormData); - - if (initialValues?.requiredMemberIds && users) { - const reqMembers = users - .filter((u) => initialValues.requiredMemberIds?.includes(u.userId)) - .map(userToAutocompleteOption); - setRequiredMembers(reqMembers); - } - - if (initialValues?.optionalMemberIds && users) { - const optMembers = users - .filter((u) => initialValues.optionalMemberIds?.includes(u.userId)) - .map(userToAutocompleteOption); - setOptionalMembers(optMembers); - } + // Set autocomplete state for required members + if (initialValues?.requiredMemberIds && users) { + const reqMembers = users + .filter((u) => initialValues.requiredMemberIds?.includes(u.userId)) + .map(userToAutocompleteOption); + setRequiredMembers(reqMembers); + } - if (initialValues?.teamIds && teams) { - const teamOptions = teams - .filter((t) => initialValues.teamIds?.includes(t.teamId)) - .map((t) => ({ id: t.teamId, label: t.teamName })); - setSelectedTeams(teamOptions); - } + // Set autocomplete state for optional members + if (initialValues?.optionalMemberIds && users) { + const optMembers = users + .filter((u) => initialValues.optionalMemberIds?.includes(u.userId)) + .map(userToAutocompleteOption); + setOptionalMembers(optMembers); + } - if (initialValues?.days && initialValues.days.length > 0) { - setShowRecurringOptions(true); - } + // Set autocomplete state for teams + if (initialValues?.teamIds && teams) { + const teamOptions = teams + .filter((t) => initialValues.teamIds?.includes(t.teamId)) + .map((t) => ({ id: t.teamId, label: t.teamName })); + setSelectedTeams(teamOptions); } - }, [open, defaultFormData, initialValues, users, teams, reset]); - useEffect(() => { - if (open && initialValues?.days && initialValues.days.length > 0) { + // Set recurring options visibility + if (initialValues?.days && initialValues.days.length > 0) { setShowRecurringOptions(true); } - }, [open, initialValues?.days]); + }, [initialValues, users, teams]); const isEditMode = !!initialValues; const computedTitle = isEditMode ? 'Edit Event' : 'Add Event'; @@ -385,10 +366,7 @@ const EventModal: React.FC = ({ }; const handleClose = () => { - reset(defaultFormData); - setRequiredMembers([]); - setOptionalMembers([]); - setSelectedTeams([]); + reset(); onClose(); }; @@ -423,81 +401,50 @@ const EventModal: React.FC = ({ }; const onFormSubmit = async (data: EventFormValues) => { - try { - const requiresConfirmation = selectedEventType?.requiresConfirmation ?? false; - const scheduleSlots: Array<{ - startTime: Date; - endTime: Date; - allDay: boolean; - }> = []; - - // If the event requires confirmation, use startTime for initialDateScheduled and don't add any schedule slots - if (!requiresConfirmation) { - // Helper function to create a date/time for a specific occurrence - const createSlotDateTime = (baseDate: Date, time: Date): Date => { - const result = new Date(baseDate); - result.setHours(time.getHours(), time.getMinutes(), time.getSeconds(), time.getMilliseconds()); - return result; - }; - - // Generate schedule slots for recurring events - const dayOfWeekEnum = convertIntToDay(data.scheduleDate.getDay()); - const selectedDays = data.days.length > 0 ? data.days : [dayOfWeekEnum]; - - // Convert selected days to day indices for comparison - const dayIndices = selectedDays.map(convertDayToInt); - - // Generate additional recurring occurrences - let occurrencesGenerated = 0; - const searchDate = new Date(data.scheduleDate); - - const maxDaysToSearch = 365; // Search up to a year - let daysSearched = 0; - - while (occurrencesGenerated < data.recurrenceNumber && daysSearched < maxDaysToSearch) { - const currentDayIndex = searchDate.getDay(); - - if ((dayIndices as number[]).includes(currentDayIndex)) { - scheduleSlots.push({ - startTime: createSlotDateTime(searchDate, data.startTime), - endTime: createSlotDateTime(searchDate, data.endTime), - allDay: data.allDay - }); - occurrencesGenerated++; - } - - searchDate.setDate(searchDate.getDate() + 1); - daysSearched++; - } - } - - const basePayload: EventEditPayload = { - title: data.title, - eventTypeId: data.eventTypeId, - requiredMemberIds: requiredMembers.map((m) => m.id), - optionalMemberIds: optionalMembers.map((m) => m.id), - teamIds: selectedTeams.map((t) => t.id), - teamTypeId: data.teamTypeId, - location: data.location, - zoomLink: data.zoomLink, - shopIds: data.shopIds, - machineryIds: data.machineryIds, - workPackageIds: data.workPackageIds, - documentFiles: data.documentFiles, - questionDocumentLink: data.questionDocumentLink, - description: data.description + const requiresConfirmation = selectedEventType?.requiresConfirmation ?? false; + + const payload: EventPayload = { + title: data.title, + eventTypeId: data.eventTypeId, + requiredMemberIds: requiredMembers.map((m) => m.id), + optionalMemberIds: optionalMembers.map((m) => m.id), + teamIds: selectedTeams.map((t) => t.id), + teamTypeId: data.teamTypeId, + location: data.location, + zoomLink: data.zoomLink, + shopIds: data.shopIds, + machineryIds: data.machineryIds, + workPackageIds: data.workPackageIds, + documentFiles: data.documentFiles, + questionDocumentLink: data.questionDocumentLink, + description: data.description + }; + + // If the event requires confirmation, only populate initialDateScheduled + if (requiresConfirmation) { + payload.initialDateScheduled = data.scheduleDate; + } else if (isEditMode && data.selectedScheduleSlotId) { + // For edit mode, populate editScheduleSlotArgs + payload.editScheduleSlotArgs = { + scheduleSlotId: data.selectedScheduleSlotId, + newStartTime: data.startTime, + newEndTime: data.endTime, + newAllDay: data.allDay, + editAllInSeries: false // Always false for now as per requirements + }; + } else if (!isEditMode) { + // For create mode, populate createScheduleSlotArgs + payload.createScheduleSlotArgs = { + startTime: data.startTime, + endTime: data.endTime, + days: data.days.length > 0 ? data.days : [convertIntToDay(data.scheduleDate.getDay())], + recurrenceNumber: data.recurrenceNumber > 0 ? data.recurrenceNumber : 1, + allDay: data.allDay }; - - await onSubmit({ - basePayload, - scheduleSlots, - scheduleDate: data.scheduleDate, - requiresConfirmation - }); - handleClose(); - } catch (e: unknown) { - if (e instanceof Error) toast.error(e.message); } + + await onSubmit(payload); + handleClose(); }; // When data loads from endpoint, update the options for the autocomplete fields @@ -543,7 +490,7 @@ const EventModal: React.FC = ({ open={open} onHide={handleClose} title={computedTitle} - reset={() => reset(defaultFormData)} + reset={handleClose} handleUseFormSubmit={handleSubmit} onFormSubmit={onFormSubmit} formId="event-form" diff --git a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx index 968e1b4314..1b69e36838 100644 --- a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx @@ -1,12 +1,9 @@ import React, { useState } from 'react'; import { Box, Button, IconButton, Link, Popover, Stack, Typography, useTheme } from '@mui/material'; -import { Calendar, DayOfWeek, Event, EventType } from 'shared'; - +import { Calendar, DayOfWeek, EventInstance, EventType } from 'shared'; import { Link as RouterLink } from 'react-router-dom'; import { routes } from '../../utils/routes'; - import { getTeamTypeIcon } from './CalendarDayCard'; - import AccessTimeIcon from '@mui/icons-material/AccessTime'; import LocationOnIcon from '@mui/icons-material/LocationOn'; import GroupIcon from '@mui/icons-material/Group'; @@ -23,13 +20,13 @@ import HelpIcon from '@mui/icons-material/Help'; import EditIcon from '@mui/icons-material/Edit'; import PeopleIcon from '@mui/icons-material/People'; import DeleteIcon from '@mui/icons-material/Delete'; -import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; import NERSuccessButton from '../../components/NERSuccessButton'; import NERFailButton from '../../components/NERFailButton'; import { useApproveEvent, useDeleteEvent, useDenyEvent } from '../../hooks/calendar.hooks'; import EditEventModal from './Components/EditEventModal'; import { useToast } from '../../hooks/toasts.hooks'; import NERDeleteModal from '../../components/NERDeleteModal'; +import { datePipe } from '../../utils/pipes'; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ @@ -46,15 +43,15 @@ const stopClick: React.MouseEventHandler = (e) => { }; interface EventClickContentProps { - event: Event; + event: EventInstance; eventTypes: EventType[]; calendars: Calendar[]; dayOfWeek?: DayOfWeek; disable: boolean; addApprovalButtons: boolean; onClose: () => void; - onEdit: (event: Event) => void; - onDelete: (event: Event) => void; + onEdit: (event: EventInstance) => void; + onDelete: (event: EventInstance) => void; clickedDate?: Date; } @@ -84,8 +81,6 @@ const EventClickContent: React.FC = ({ const theme = useTheme(); const name = event.workPackages?.[0]?.wbsElement?.name || event.title; - const startTime = dayOfWeek ? getConvertedStart(event, dayOfWeek) : ''; - const endTime = dayOfWeek ? getConvertedEnd(event, dayOfWeek) : ''; const specificEventType = eventTypes.find((et) => et.eventTypeId === event.eventTypeId); const specificCalendar = calendars.find((calendar) => @@ -95,7 +90,7 @@ const EventClickContent: React.FC = ({ const showAvailabilityButton = true; - const eventDate = clickedDate || (event.scheduledTimes[0]?.startTime ? event.scheduledTimes[0].startTime : new Date()); + const eventDate = clickedDate || event.startTime; const availabilityUrl = `${routes.NEW_CALENDAR}/event/${event.eventId}?date=${eventDate.toISOString()}`; @@ -177,28 +172,13 @@ const EventClickContent: React.FC = ({ {dayOfWeek && } - {dayOfWeek && ( + {dayOfWeek && !event.allDay && ( - {startTime} – {endTime} + {datePipe(event.startTime)} – {datePipe(event.endTime)} )} + {dayOfWeek && event.allDay && All day} {!dayOfWeek && } - {!dayOfWeek && ( - - {event.scheduledTimes.map((slot, index) => { - const slotDate = slot.startTime ? new Date(slot.startTime) : null; - const dateStr = slotDate - ? slotDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) - : 'N/A'; - return ( - - {dateStr} {slot.startTime?.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) ?? 'N/A'}{' '} - – {slot.endTime?.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }) ?? 'N/A'} - - ); - })} - - )} {hasValue(locationText) && ( <> @@ -421,7 +401,7 @@ const EventClickContent: React.FC = ({ }; export interface EventClickPopupProps { - clickedEvent?: Event; + clickedEvent?: EventInstance; anchorPosition?: { top: number; left: number }; onClose: () => void; eventTypes: EventType[]; @@ -449,7 +429,7 @@ export const EventClickPopup: React.FC = ({ const { mutateAsync: deleteEvent } = useDeleteEvent(clickedEvent?.eventId ?? ''); - const handleEdit = () => { + const handleEdit = (_event: EventInstance) => { setShowEditModal(true); }; @@ -508,9 +488,6 @@ export const EventClickPopup: React.FC = ({ }} event={clickedEvent} eventTypes={eventTypes} - defaultDate={ - clickedEvent.scheduledTimes[0]?.startTime ? new Date(clickedEvent.scheduledTimes[0].startTime) : new Date() - } /> )} diff --git a/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx b/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx index 78bbceba56..e83ea18e1d 100644 --- a/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx @@ -1,24 +1,21 @@ import AccessTimeIcon from '@mui/icons-material/AccessTime'; import LocationOnIcon from '@mui/icons-material/LocationOn'; -import { Calendar, DayOfWeek, Event, EventType } from 'shared'; +import { Calendar, EventInstance, EventType } from 'shared'; import GroupIcon from '@mui/icons-material/Group'; import { Stack } from '@mui/system'; import { getTeamTypeIcon } from './CalendarDayCard'; import { Typography } from '@mui/material'; -import { getConvertedEnd, getConvertedStart } from '../../utils/datetime.utils'; +import { datePipe } from '../../utils/pipes'; interface EventInfoProps { - event: Event; + event: EventInstance; eventTypes?: EventType[]; calendars?: Calendar[]; - dayOfWeek: DayOfWeek; onClick: () => void; } -const EventPartialInfoView: React.FC = ({ event, eventTypes, calendars, dayOfWeek, onClick }) => { +const EventPartialInfoView: React.FC = ({ event, eventTypes, calendars, onClick }) => { const name = event.title; - const convertedStartTime = getConvertedStart(event, dayOfWeek); - const convertedEndTime = getConvertedEnd(event, dayOfWeek); const specificEventType = eventTypes?.find((eventType) => eventType.eventTypeId === event.eventTypeId); const specificCalendar = calendars?.find((calendar) => calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) @@ -47,9 +44,15 @@ const EventPartialInfoView: React.FC = ({ event, eventTypes, cal - - {convertedStartTime} - {convertedEndTime} - + {event.allDay ? ( + + All Day + + ) : ( + + {datePipe(event.startTime)} - {datePipe(event.endTime)} + + )} diff --git a/src/frontend/src/pages/CalendarPage/EventsTable.tsx b/src/frontend/src/pages/CalendarPage/EventsTable.tsx index d396df7534..944cd7c98c 100644 --- a/src/frontend/src/pages/CalendarPage/EventsTable.tsx +++ b/src/frontend/src/pages/CalendarPage/EventsTable.tsx @@ -379,7 +379,17 @@ const EventsTable: React.FC = ({ tab, yourEvents, reviewEvents, = ({ tab, yourEvents, reviewEvents, )} = ({ allEventTypes, yourEv }); const upcomingOccurences = upcomingEvents - ? getEventsFlattened(upcomingEvents, upcomingStartPeriod, upcomingEndPeriod) + ? upcomingEvents.flatMap((event) => event.scheduledTimes.map((slot) => ({ ...event, ...slot }))) : []; const toggleCalendar = (calendarId: string) => { @@ -231,28 +232,27 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv return time1 - time2; }); - const eventDict = new Map(); + const eventDict = new Map(); const dayDict = new Map(); + const eventInstances: EventInstance[] = sortedEvents.flatMap((event) => + event.scheduledTimes.map((slot) => ({ + ...event, + ...slot + })) + ); - sortedEvents.forEach((event) => { - const times: Date[] = getMeetingDates(event); - - times.forEach((date) => { - const eventDate = new Date(date); - const dateString = datePipe(eventDate); - eventDate.setHours(0, 0, 0, 0); - const day = convertIntToDay(eventDate.getDay()); - dayDict.set(dateString, day); - if (eventDict.has(dateString)) { - // Check if this event is already in this date's array to avoid duplicates - const existingEvents = eventDict.get(dateString)!; - if (!existingEvents.find((e) => e.eventId === event.eventId)) { - existingEvents.push(event); - } - } else { - eventDict.set(dateString, [event]); - } - }); + eventInstances.forEach((event) => { + const eventDate = new Date(event.startTime); + const dateString = datePipe(eventDate); + eventDate.setHours(0, 0, 0, 0); + const day = convertIntToDay(eventDate.getDay()); + dayDict.set(dateString, day); + if (eventDict.has(dateString)) { + const existingEvents = eventDict.get(dateString)!; + existingEvents.push(event); + } else { + eventDict.set(dateString, [event]); + } }); const startOfEachWeek = [0, 7, 14, 21, 28, 35]; diff --git a/src/frontend/src/pages/CalendarPage/UpcomingMeetingsCard.tsx b/src/frontend/src/pages/CalendarPage/UpcomingMeetingsCard.tsx index 093c859044..bdf0f235c6 100644 --- a/src/frontend/src/pages/CalendarPage/UpcomingMeetingsCard.tsx +++ b/src/frontend/src/pages/CalendarPage/UpcomingMeetingsCard.tsx @@ -2,20 +2,15 @@ import { Card, Box, Typography, Stack } from '@mui/material'; import BuildOutlinedIcon from '@mui/icons-material/BuildOutlined'; import RoomOutlinedIcon from '@mui/icons-material/RoomOutlined'; import GroupsOutlinedIcon from '@mui/icons-material/GroupsOutlined'; -import { Calendar, DayOfWeek, Event, EventType } from 'shared'; -import { getConvertedStart } from '../../utils/datetime.utils'; +import { Calendar, EventInstance, EventType } from 'shared'; interface UpcomingMeetingProp { calendars: Calendar[]; - event: Event; + event: EventInstance; eventTypes?: EventType[]; } -const dayOfWeek = DayOfWeek.MONDAY; - const UpcomingMeetingsCard: React.FC = ({ event, calendars = [], eventTypes = [] }) => { - const convertedStartTime = getConvertedStart(event, dayOfWeek); - const specificEventType = eventTypes?.find((eventType) => eventType.eventTypeId === event.eventTypeId); const specificCalendar = calendars?.find((calendar) => calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) @@ -46,7 +41,7 @@ const UpcomingMeetingsCard: React.FC = ({ event, calendars {/* Event Time */} - {convertedStartTime} + {new Date(event.startTime).toLocaleTimeString()} diff --git a/src/frontend/src/utils/calendar.utils.ts b/src/frontend/src/utils/calendar.utils.ts index 8c64a1d1a8..d644b8809f 100644 --- a/src/frontend/src/utils/calendar.utils.ts +++ b/src/frontend/src/utils/calendar.utils.ts @@ -1,5 +1,4 @@ -import { DayOfWeek, Event } from 'shared'; -import { filterEventTransformer } from '../apis/transformers/calendar.transformer'; +import { DayOfWeek, Event, EventInstance } from 'shared'; import { EventFormValues } from '../pages/CalendarPage/Components/EventModal'; export const convertDayToInt = (day: DayOfWeek) => { @@ -114,47 +113,13 @@ export const getOverlapTime = (event1: Event, event2: Event) => { return overlaps; }; -// Returns a flat list of event occurrences within a given period -export const getEventsFlattened = (events: Event[], startPeriod: Date, endPeriod: Date): Event[] => { - const occurrences: { event: Event; date: Date }[] = []; - - events.forEach((event) => { - const eventDates = getMeetingDates(filterEventTransformer(event)); - - eventDates.forEach((date) => { - if (date >= startPeriod && date <= endPeriod) { - occurrences.push({ event, date }); - } - }); - }); - - // Sort by date - occurrences.sort((a, b) => a.date.getTime() - b.date.getTime()); - - // Return only the events, possibly repeated for multiple occurrences - return occurrences.map(({ event }) => event); -}; - // converts an Event into Event Form Values -// Note: After the recurring events refactor, we store individual schedule slots -// When editing, we show the first occurrence and set recurrence to 0 -// Users will need to delete and recreate if they want to change recurring patterns -export const convertEventToFormValues = (event: Event): Partial => { - // Use the first schedule slot for the form values - const [firstSlot] = event.scheduledTimes; - - // Extract the date from the first slot's startTime - // For confirmation-required events, initialDateScheduled represents the start of the week range - // For regular events, we use the actual startTime from the first slot - let scheduleDate = new Date(); - if (firstSlot?.startTime) { - scheduleDate = new Date(firstSlot.startTime); - } else if (firstSlot?.endTime) { - scheduleDate = new Date(firstSlot.endTime); - } else if (event.initialDateScheduled) { - // Only fall back to initialDateScheduled if no slot times exist (confirmation events) - scheduleDate = new Date(event.initialDateScheduled); - } +// Note: Because users can only edit a single instaces time, editModal is always populated with an event instance +// representing a single occurrence of the event. However, event edits will effect the entire series for all values +// except for the schedule slot (date/time), and users are prompted if they want the time effects to propogate to other schedule slots +export const convertEventToFormValues = (event: EventInstance): Partial => { + // For edit mode, use the actual scheduled date of this occurrence, not initialDateScheduled + const scheduleDate = event.startTime ? new Date(event.startTime) : undefined; return { title: event.title, @@ -175,12 +140,13 @@ export const convertEventToFormValues = (event: Event): Partial questionDocumentLink: event.questionDocumentLink, description: event.description, scheduleDate, - startTime: firstSlot?.startTime ? new Date(firstSlot.startTime) : undefined, - endTime: firstSlot?.endTime ? new Date(firstSlot.endTime) : undefined, - allDay: firstSlot?.allDay ?? false, + startTime: event.startTime ? new Date(event.startTime) : undefined, + endTime: event.endTime ? new Date(event.endTime) : undefined, + allDay: event.allDay ?? false, // Set recurrence to 0 since we've already expanded the schedule recurrenceNumber: 0, // No days since this is now a single occurrence - days: [] + days: [], + selectedScheduleSlotId: event.scheduleSlotId }; }; diff --git a/src/frontend/src/utils/datetime.utils.ts b/src/frontend/src/utils/datetime.utils.ts index 9012e0567b..4d562c5ca1 100644 --- a/src/frontend/src/utils/datetime.utils.ts +++ b/src/frontend/src/utils/datetime.utils.ts @@ -1,5 +1,4 @@ import dayjs from 'dayjs'; -import { DayOfWeek, Event } from 'shared'; /** * Returns monday of current week @@ -65,88 +64,6 @@ export const isPastEvent = (startDate: Date, endDate: Date) => { return startDate < endDate; }; -// Gets the start time of an event for a given date -// With the new schema, we find the schedule slot that occurs on the specified date -export const getConvertedStart = (event: Event, dateOrDayOfWeek: Date | DayOfWeek) => { - // If passed a DayOfWeek enum, we need to find a slot on that day of the week - // This is for backward compatibility with components that don't have the specific date - if (typeof dateOrDayOfWeek === 'string') { - // It's a DayOfWeek enum - find any slot that matches this day - const dayOfWeekMap: { [key in DayOfWeek]: number } = { - [DayOfWeek.SUNDAY]: 0, - [DayOfWeek.MONDAY]: 1, - [DayOfWeek.TUESDAY]: 2, - [DayOfWeek.WEDNESDAY]: 3, - [DayOfWeek.THURSDAY]: 4, - [DayOfWeek.FRIDAY]: 5, - [DayOfWeek.SATURDAY]: 6 - }; - const targetDayIndex = dayOfWeekMap[dateOrDayOfWeek]; - - const specificSlot = event.scheduledTimes.find((slot) => { - if (!slot.startTime) return false; - const slotDate = new Date(slot.startTime); - return slotDate.getDay() === targetDayIndex; - }); - - const startTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(); - return startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); - } - - // It's a Date object - find the slot for this specific date - const targetDate = dateOrDayOfWeek; - targetDate.setHours(0, 0, 0, 0); - - const specificSlot = event.scheduledTimes.find((slot) => { - if (!slot.startTime) return false; - const slotDate = new Date(slot.startTime); - slotDate.setHours(0, 0, 0, 0); - return slotDate.getTime() === targetDate.getTime(); - }); - - const startTime = specificSlot?.startTime ? new Date(specificSlot.startTime) : new Date(); - return startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); -}; - -// Gets the end time of an event for a given date -// With the new schema, we find the schedule slot that occurs on the specified date -export const getConvertedEnd = (event: Event, dateOrDayOfWeek: Date | DayOfWeek) => { - // If passed a DayOfWeek enum, we need to find a slot on that day of the week - // This is for backward compatibility with components that don't have the specific date - if (typeof dateOrDayOfWeek === 'string') { - // It's a DayOfWeek enum - find any slot that matches this day - const dayOfWeekMap: { [key in DayOfWeek]: number } = { - [DayOfWeek.SUNDAY]: 0, - [DayOfWeek.MONDAY]: 1, - [DayOfWeek.TUESDAY]: 2, - [DayOfWeek.WEDNESDAY]: 3, - [DayOfWeek.THURSDAY]: 4, - [DayOfWeek.FRIDAY]: 5, - [DayOfWeek.SATURDAY]: 6 - }; - const targetDayIndex = dayOfWeekMap[dateOrDayOfWeek]; - - const specificSlot = event.scheduledTimes.find((slot) => { - if (!slot.endTime) return false; - const slotDate = new Date(slot.endTime); - return slotDate.getDay() === targetDayIndex; - }); - - const endTime = specificSlot?.endTime ? new Date(specificSlot.endTime) : new Date(); - return endTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); - } - - // It's a Date object - find the slot for this specific date - const targetDate = dateOrDayOfWeek; - targetDate.setHours(0, 0, 0, 0); - - const specificSlot = event.scheduledTimes.find((slot) => { - if (!slot.endTime) return false; - const slotDate = new Date(slot.endTime); - slotDate.setHours(0, 0, 0, 0); - return slotDate.getTime() === targetDate.getTime(); - }); - - const endTime = specificSlot?.endTime ? new Date(specificSlot.endTime) : new Date(); - return endTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); +export const formatTime = (date: Date) => { + return date.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' }); }; diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 4a5f7be6d0..6c718f7d03 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -215,6 +215,8 @@ export interface Event { initialDateScheduled?: Date; } +export type EventInstance = Omit & ScheduleSlot; + export type EventPreview = { eventId: string; title: string; From 95e65b9fa1ba1420b976da35429638e8e76d81bf Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Thu, 22 Jan 2026 09:46:43 -0500 Subject: [PATCH 472/477] event popup consistency --- .gitignore | 2 + .../pages/CalendarPage/CalendarDayCard.tsx | 455 +++++++++--------- .../pages/CalendarPage/EventClickPopup.tsx | 6 +- .../CalendarPage/EventPartialInfoView.tsx | 4 +- 4 files changed, 228 insertions(+), 239 deletions(-) diff --git a/.gitignore b/.gitignore index c5fc746811..3c818c0e54 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,5 @@ eb-deploy/ # Docker *.bak *.backup + +CLAUDE.md \ No newline at end of file diff --git a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx index c8c72f2e0a..3ad7a0a849 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx @@ -1,25 +1,18 @@ import { useState } from 'react'; -import { Box, Card, CardContent, Grid, Link, Stack, Tooltip, Typography, useTheme } from '@mui/material'; +import { Box, Card, CardContent, Grid, Stack, Tooltip, Typography, useTheme } from '@mui/material'; import { Calendar, DayOfWeek, EventInstance, EventType } from 'shared'; import ConstructionIcon from '@mui/icons-material/Construction'; import WorkOutlineIcon from '@mui/icons-material/WorkOutline'; import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices'; import TerminalIcon from '@mui/icons-material/Terminal'; -import AccessTimeIcon from '@mui/icons-material/AccessTime'; -import LocationOnIcon from '@mui/icons-material/LocationOn'; -import GroupIcon from '@mui/icons-material/Group'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; -import DoNotDisturbIcon from '@mui/icons-material/DoNotDisturb'; -import LinkIcon from '@mui/icons-material/Link'; -import StorefrontIcon from '@mui/icons-material/Storefront'; -import BusinessCenterIcon from '@mui/icons-material/BusinessCenter'; -import DescriptionIcon from '@mui/icons-material/Description'; -import ArticleIcon from '@mui/icons-material/Article'; import HelpIcon from '@mui/icons-material/Help'; -import GroupsIcon from '@mui/icons-material/Groups'; -import { EventClickPopup } from './EventClickPopup'; +import { EventClickContent } from './EventClickPopup'; import EventPartialInfoView from './EventPartialInfoView'; -import { formatTime } from '../../utils/datetime.utils'; +import EditEventModal from './Components/EditEventModal'; +import NERDeleteModal from '../../components/NERDeleteModal'; +import { useDeleteEvent } from '../../hooks/calendar.hooks'; +import { useToast } from '../../hooks/toasts.hooks'; export const getTeamTypeIcon = (teamTypeName: string, isLarge?: boolean) => { const teamIcons: Map = new Map([ @@ -65,24 +58,36 @@ const CalendarDayCard: React.FC = ({ const isCurrentDay = cardDate.toDateString() === today; const isFutureDay = cardDate >= new Date(); - const [clickedEvent, setClickedEvent] = useState(); - const [anchorPosition, setAnchorPosition] = useState<{ top: number; left: number }>(); + // Track which event's tooltip is locked open after clicking + const [lockedTooltipEventId, setLockedTooltipEventId] = useState(null); + const [showEditModal, setShowEditModal] = useState(false); + const [showDeleteModal, setShowDeleteModal] = useState(false); + const [selectedEvent, setSelectedEvent] = useState(null); + const toast = useToast(); - const handleOpenClickPopup = (event: EventInstance) => { - setClickedEvent(event); - if (typeof window !== 'undefined') { - setAnchorPosition({ - top: window.innerHeight / 2, - left: window.innerWidth / 2 - }); - } else { - setAnchorPosition({ top: 0, left: 0 }); - } + const { mutateAsync: deleteEvent } = useDeleteEvent(selectedEvent?.eventId ?? ''); + + const handleEdit = (event: EventInstance) => { + setSelectedEvent(event); + setShowEditModal(true); }; - const handleCloseClickPopup = () => { - setClickedEvent(undefined); - setAnchorPosition(undefined); + const handleDelete = (event: EventInstance) => { + setSelectedEvent(event); + setShowDeleteModal(true); + }; + + const handleDeleteConfirm = async () => { + try { + setShowDeleteModal(false); + setLockedTooltipEventId(null); + await deleteEvent(); + toast.success('Event deleted successfully!'); + } catch (err) { + if (err instanceof Error) { + toast.error(err.message); + } + } }; const DayCardTitle = () => ( @@ -102,209 +107,35 @@ const CalendarDayCard: React.FC = ({ ); - const EventPopupInfo = ({ event, color }: { event: EventInstance; color: string }) => { - const name = event.title; - - return ( - <> - - - - {getTeamTypeIcon(event.teamType?.name ?? '', true)} - - - - {name} - - - - - - - {event.allDay ? 'All Day' : `${formatTime(event.startTime)} - ${formatTime(event.endTime)}`} - - - - {event.location ?? 'N/A'} - - - - {event.requiredMembers.length > 0 && ( - - - - Required : - - - {event.requiredMembers.map((member) => `${member.firstName} ${member.lastName}`).join(', ')} - - - )} - - {event.optionalMembers.length > 0 && ( - - - - Optional : - - - {event.optionalMembers.map((member) => `${member.firstName} ${member.lastName}`).join(', ')} - - - )} - - {event.confirmedMembers.length > 0 && ( - - - - {event.confirmedMembers.map((member) => `${member.firstName} ${member.lastName}`).join(', ')} - - - )} - - {event.deniedMembers.length > 0 && ( - - - - {event.deniedMembers.map((member) => `${member.firstName} ${member.lastName}`).join(', ')} - - - )} - - {event.teams.length > 0 && ( - - - - Teams : - - - {event.teams.map((team) => team.teamName).join(', ')} - - - )} - - {event.machinery.length > 0 && ( - - - - {event.machinery.map((machine) => machine.name).join(', ')} - - - )} - - {event.shops.length > 0 && ( - - - - {event.shops.map((shop) => shop.name).join(', ')} - - - )} - - {event.workPackages.length > 0 && ( - - - - {event.workPackages.map((wp) => wp.wbsElement.name).join(', ')} - - - )} - - {event.zoomLink && ( - - - - e.stopPropagation()} target="_blank" rel="noopener"> - Zoom Link - - - - )} - {event.questionDocumentLink && ( - - - - {event.questionDocumentLink ? ( - e.stopPropagation()} - target="_blank" - rel="noopener" - > - Question Document Link - - ) : ( - 'N/A' - )} - - - )} - - {event.description && ( - - - - {event.description.substring(0, name.length * 2)} - {event.description.length > name.length * 2 && '...'} - - - )} - - {event.status && ( - - {getStatusIcon(event.status)} - - {event.status} - - - )} - - - ); - }; const EventCard = ({ event }: { event: EventInstance }) => { + const [isHovered, setIsHovered] = useState(false); + const [tooltipHovered, setTooltipHovered] = useState(false); const specificEventType = eventTypes.find((eventType) => eventType.eventTypeId === event.eventTypeId); const specificCalendar = calendars.find((calendar) => calendar.eventTypes.some((eventType) => eventType.eventTypeId === specificEventType?.eventTypeId) ); const bgColor = specificCalendar?.color ?? 'gray'; + const isLocked = lockedTooltipEventId === event.eventId; + const shouldBeOpen = isLocked || isHovered || tooltipHovered; return ( setIsHovered(true)} + onMouseLeave={() => { + setTimeout(() => { + if (!isLocked && !tooltipHovered) { + setIsHovered(false); + } + }, 100); + }} onClick={(e) => { e.stopPropagation(); - handleOpenClickPopup(event); + setLockedTooltipEventId(event.eventId); }} sx={{ position: 'relative', @@ -324,16 +155,40 @@ const CalendarDayCard: React.FC = ({ } + open={shouldBeOpen} + disableHoverListener + disableFocusListener + disableTouchListener + enterDelay={0} + leaveDelay={200} + title={ + setTooltipHovered(true)} + onMouseLeave={() => setTooltipHovered(false)} + > + setLockedTooltipEventId(null)} + onEdit={handleEdit} + onDelete={handleDelete} + clickedDate={cardDate} + /> + + } slotProps={{ popper: { sx: { zIndex: 1200 } }, tooltip: { sx: { maxWidth: 'none', borderRadius: 4, - p: 2, + p: 0, cursor: 'pointer', - bgcolor: theme.palette.grey[900], + bgcolor: 'transparent', boxShadow: '0 0 15px rgba(255, 255, 255, 1.0)' } }, @@ -344,6 +199,16 @@ const CalendarDayCard: React.FC = ({ } } }} + PopperProps={{ + modifiers: [ + { + name: 'offset', + options: { + offset: [0, 4] + } + } + ] + }} > = ({ ); }; + const ExtraEventItem = ({ event }: { event: EventInstance }) => { + const [isHovered, setIsHovered] = useState(false); + const [tooltipHovered, setTooltipHovered] = useState(false); + const isLocked = lockedTooltipEventId === event.eventId; + const shouldBeOpen = isLocked || isHovered || tooltipHovered; + + return ( + setTooltipHovered(true)} + onMouseLeave={() => setTooltipHovered(false)} + > + setLockedTooltipEventId(null)} + onEdit={handleEdit} + onDelete={handleDelete} + clickedDate={cardDate} + /> + + } + slotProps={{ + popper: { sx: { zIndex: 1300 } }, + tooltip: { + sx: { + maxWidth: 'none', + borderRadius: 4, + p: 0, + cursor: 'pointer', + bgcolor: 'transparent', + boxShadow: '0 0 15px rgba(255, 255, 255, 1.0)' + } + }, + arrow: { + sx: { + color: theme.palette.grey[900], + fontSize: 16 + } + } + }} + PopperProps={{ + modifiers: [ + { + name: 'offset', + options: { + offset: [0, 4] + } + } + ] + }} + > + setIsHovered(true)} + onMouseLeave={() => { + setTimeout(() => { + if (!isLocked && !tooltipHovered) { + setIsHovered(false); + } + }, 100); + }} + onClick={(e) => { + e.stopPropagation(); + setLockedTooltipEventId(event.eventId); + }} + > + {}} calendars={calendars} eventTypes={eventTypes} /> + + + ); + }; + const ExtraEventsCard = ({ extraEvents }: { extraEvents: EventInstance[] }) => { return ( {extraEvents.map((event) => ( - handleOpenClickPopup(event)} - calendars={calendars} - eventTypes={eventTypes} - /> + ))} } @@ -400,6 +346,16 @@ const CalendarDayCard: React.FC = ({ } } }} + PopperProps={{ + modifiers: [ + { + name: 'offset', + options: { + offset: [0, 4] + } + } + ] + }} > = ({ return ( <> + {/* Backdrop for locked tooltips to handle click-away */} + {lockedTooltipEventId && ( + setLockedTooltipEventId(null)} + /> + )} + = ({ - + {selectedEvent && showEditModal && ( + { + setShowEditModal(false); + setLockedTooltipEventId(null); + }} + event={selectedEvent} + eventTypes={eventTypes} + /> + )} + + {selectedEvent && showDeleteModal && ( + { + setShowDeleteModal(false); + setLockedTooltipEventId(null); + }} + formId="delete-event-form" + dataType={selectedEvent.title} + onFormSubmit={handleDeleteConfirm} + /> + )} ); }; diff --git a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx index 1b69e36838..0d3846f5da 100644 --- a/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx +++ b/src/frontend/src/pages/CalendarPage/EventClickPopup.tsx @@ -26,7 +26,7 @@ import { useApproveEvent, useDeleteEvent, useDenyEvent } from '../../hooks/calen import EditEventModal from './Components/EditEventModal'; import { useToast } from '../../hooks/toasts.hooks'; import NERDeleteModal from '../../components/NERDeleteModal'; -import { datePipe } from '../../utils/pipes'; +import { formatTime } from '../../utils/datetime.utils'; export const getStatusIcon = (status: string, isLarge?: boolean) => { const statusIcons: Map = new Map([ @@ -63,7 +63,7 @@ const hasValue = (v?: string | null) => { return s.length > 0 && s.toLowerCase() !== 'n/a'; }; -const EventClickContent: React.FC = ({ +export const EventClickContent: React.FC = ({ event, eventTypes, calendars, @@ -174,7 +174,7 @@ const EventClickContent: React.FC = ({ {dayOfWeek && } {dayOfWeek && !event.allDay && ( - {datePipe(event.startTime)} – {datePipe(event.endTime)} + {formatTime(event.startTime)} – {formatTime(event.endTime)} )} {dayOfWeek && event.allDay && All day} diff --git a/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx b/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx index e83ea18e1d..0ec6347108 100644 --- a/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx +++ b/src/frontend/src/pages/CalendarPage/EventPartialInfoView.tsx @@ -5,7 +5,7 @@ import GroupIcon from '@mui/icons-material/Group'; import { Stack } from '@mui/system'; import { getTeamTypeIcon } from './CalendarDayCard'; import { Typography } from '@mui/material'; -import { datePipe } from '../../utils/pipes'; +import { formatTime } from '../../utils/datetime.utils'; interface EventInfoProps { event: EventInstance; @@ -50,7 +50,7 @@ const EventPartialInfoView: React.FC = ({ event, eventTypes, cal ) : ( - {datePipe(event.startTime)} - {datePipe(event.endTime)} + {formatTime(event.startTime)} - {formatTime(event.endTime)} )} From 1dd4f9fe24c95531cad9726859f9e179cc4374ec Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Thu, 22 Jan 2026 10:16:10 -0500 Subject: [PATCH 473/477] new event in top right and clicking events, +N on second event in day card --- src/backend/src/services/calendar.services.ts | 7 +- .../pages/CalendarPage/CalendarDayCard.tsx | 39 +++--- .../src/pages/CalendarPage/CalendarTab.tsx | 114 +++++++++++++----- .../pages/CalendarPage/NewCalendarPage.tsx | 50 ++------ 4 files changed, 109 insertions(+), 101 deletions(-) diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 2ac054ef84..17b2437860 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -46,12 +46,7 @@ import { AccessDeniedException, AccessDeniedGuestException } from '../utils/errors.utils.js'; -import { - createCalendarEvent, - uploadFile, - downloadFile, - deleteCalendarEvents -} from '../utils/google-integration.utils.js'; +import { createCalendarEvent, uploadFile, downloadFile, deleteCalendarEvents } from '../utils/google-integration.utils.js'; import { sendEventPopUp } from '../utils/pop-up.utils.js'; import { sendSlackEventConfirmNotification, diff --git a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx index 3ad7a0a849..339b2f23dc 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx @@ -42,6 +42,7 @@ interface CalendarDayCardProps { eventTypes?: EventType[]; calendars?: Calendar[]; dayOfWeek?: DayOfWeek; + onCreateEventClick: () => void; } const CalendarDayCard: React.FC = ({ @@ -49,9 +50,9 @@ const CalendarDayCard: React.FC = ({ events, eventTypes = [], calendars = [], - dayOfWeek = DayOfWeek.MONDAY + dayOfWeek = DayOfWeek.MONDAY, + onCreateEventClick }) => { - const [, setIsCreateModalOpen] = useState(false); const theme = useTheme(); const today = new Date().toDateString(); @@ -94,11 +95,13 @@ const CalendarDayCard: React.FC = ({ {cardDate.getDate()} @@ -107,7 +110,6 @@ const CalendarDayCard: React.FC = ({ ); - const EventCard = ({ event }: { event: EventInstance }) => { const [isHovered, setIsHovered] = useState(false); const [tooltipHovered, setTooltipHovered] = useState(false); @@ -162,10 +164,7 @@ const CalendarDayCard: React.FC = ({ enterDelay={0} leaveDelay={200} title={ - setTooltipHovered(true)} - onMouseLeave={() => setTooltipHovered(false)} - > + setTooltipHovered(true)} onMouseLeave={() => setTooltipHovered(false)}> = ({ enterDelay={0} leaveDelay={200} title={ - setTooltipHovered(true)} - onMouseLeave={() => setTooltipHovered(false)} - > + setTooltipHovered(true)} onMouseLeave={() => setTooltipHovered(false)}> = ({ position: 'relative', backgroundColor: !(isFutureDay || isCurrentDay) ? theme.palette.grey[900] : 'inherit', borderRadius: 2, - width: { xs: '95%', md: '80%' }, + width: { xs: '98%', md: '90%' }, height: { xs: '10vh', sm: '12vh' }, border: isCurrentDay ? '2px solid gray' : 'none', cursor: isFutureDay || isCurrentDay ? 'pointer' : 'default', @@ -411,7 +407,7 @@ const CalendarDayCard: React.FC = ({ > { - if (isFutureDay || isCurrentDay) setIsCreateModalOpen(true); + if (isFutureDay || isCurrentDay) onCreateEventClick(); }} sx={{ position: 'absolute', @@ -424,15 +420,14 @@ const CalendarDayCard: React.FC = ({ - {events.length < 3 ? ( - events.map((event) => ) - ) : ( + {events.length === 1 ? ( + + ) : events.length >= 2 ? ( <> - - + - )} + ) : null} diff --git a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx index 1473638735..04ebcac277 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx @@ -1,7 +1,7 @@ import { routes } from '../../utils/routes'; import NewCalendarPage from './NewCalendarPage'; import PageLayout from '../../components/PageLayout'; -import { Box } from '@mui/material'; +import { Box, Button } from '@mui/material'; import FullPageTabs from '../../components/FullPageTabs'; import { useState } from 'react'; import { useCurrentUser } from '../../hooks/users.hooks'; @@ -11,10 +11,15 @@ import LoadingIndicator from '../../components/LoadingIndicator'; import ErrorPage from '../ErrorPage'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; import EventsTable from './EventsTable'; +import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; +import CreateEventModal from './Components/CreateEventModal'; +import { useHistory } from 'react-router-dom'; const CalendarTab: React.FC = () => { const [tabIndex, setTabIndex] = useState(0); + const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const user = useCurrentUser(); + const history = useHistory(); const canViewReviews = isHead(user.role) || isLead(user.role); const tabs = [ @@ -83,42 +88,85 @@ const CalendarTab: React.FC = () => { if (canViewReviews) tabs.push({ tabUrlValue: 'reviews', tabName: 'Review Bookings' }); + const handleNewEventClick = () => { + if (tabIndex !== 0) { + history.push(`${routes.NEW_CALENDAR}/mainCalendar`); + } + setIsCreateModalOpen(true); + }; + return ( - - + + + + } + headerRight={ + + } + > + {tabIndex === 0 ? ( + event.scheduledTimes.map((scheduledTime) => ({ ...event, ...scheduledTime }))) ?? + [] + } + allCalendars={allCalendars} + onCreateEventClick={handleNewEventClick} /> - - } - > - {tabIndex === 0 ? ( - event.scheduledTimes.map((scheduledTime) => ({ ...event, ...scheduledTime }))) ?? - [] - } - allCalendars={allCalendars} - /> - ) : ( - + )} + + + {isCreateModalOpen && ( + setIsCreateModalOpen(false)} + eventTypes={allEventTypes} + defaultDate={new Date()} /> )} - + ); }; diff --git a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx index 2ec6674b90..dcfdfe9c3a 100644 --- a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx @@ -25,13 +25,11 @@ import ErrorPage from '../ErrorPage'; import { datePipe } from '../../utils/pipes'; import LoadingIndicator from '../../components/LoadingIndicator'; import { useAllTeamTypes } from '../../hooks/team-types.hooks'; -import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline'; import FilterModal from './FilterModal'; import { DateCalendar } from '@mui/x-date-pickers'; import { useCurrentUser } from '../../hooks/users.hooks'; import { useGetUsersTeams } from '../../hooks/teams.hooks'; import { convertIntToDay, getOverlapTime } from '../../utils/calendar.utils'; -import CreateEventModal from './Components/CreateEventModal'; import { filterEventTransformer } from '../../apis/transformers/calendar.transformer'; import WarningIcon from '@mui/icons-material/Warning'; import { useHistory } from 'react-router-dom'; @@ -46,9 +44,16 @@ interface NewCalendarPageProps { yourEvents: EventInstance[]; reviewEvents: Event[]; allCalendars: Calendar[]; + onCreateEventClick: () => void; } -const NewCalendarPage: React.FC = ({ allEventTypes, yourEvents, reviewEvents, allCalendars }) => { +const NewCalendarPage: React.FC = ({ + allEventTypes, + yourEvents, + reviewEvents, + allCalendars, + onCreateEventClick +}) => { const theme = useTheme(); const { data: allTeamTypes, @@ -65,7 +70,6 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv const [showInvitedEvents, setShowInvitedEvents] = useState(true); const [showTeamEvents, setShowTeamEvents] = useState(true); const [openFilterModal, setOpenFilterModal] = useState(false); - const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [additionalMemberIds, setAdditionalMemberIds] = useState([user.userId]); const [additionalTeamIds, setAdditionalTeamIds] = useState([]); const isLargerView = useMediaQuery(theme.breakpoints.up('md')); @@ -279,14 +283,6 @@ const NewCalendarPage: React.FC = ({ allEventTypes, yourEv return ( <> - {isCreateModalOpen && ( - setIsCreateModalOpen(false)} - eventTypes={allEventTypes} - defaultDate={displayMonthYear} - /> - )} = ({ allEventTypes, yourEv )} - - - - - - = ({ allEventTypes, yourEv ); return ( - + = ({ allEventTypes, yourEv dayDict.get(datePipe(new Date(cardDate.getTime() + cardDate.getTimezoneOffset() * 60000))) ?? DayOfWeek.SUNDAY } + onCreateEventClick={onCreateEventClick} /> From 0ffa6d5b4119427a6d6d09783ed210c20e52de65 Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Fri, 23 Jan 2026 21:03:40 -0500 Subject: [PATCH 474/477] calendar page formatting --- .gitignore | 4 +- .../controllers/work-packages.controllers.ts | 11 ++ .../pages/CalendarPage/CalendarDayCard.tsx | 37 +++++-- .../pages/CalendarPage/NewCalendarPage.tsx | 102 ++++++++++++------ 4 files changed, 107 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 3c818c0e54..f77840056a 100644 --- a/.gitignore +++ b/.gitignore @@ -65,4 +65,6 @@ eb-deploy/ *.bak *.backup -CLAUDE.md \ No newline at end of file +# Claude Code Files +CLAUDE.md +.playwright-mcp/ \ No newline at end of file diff --git a/src/backend/src/controllers/work-packages.controllers.ts b/src/backend/src/controllers/work-packages.controllers.ts index 2c0b34ddf9..0228861eec 100644 --- a/src/backend/src/controllers/work-packages.controllers.ts +++ b/src/backend/src/controllers/work-packages.controllers.ts @@ -7,6 +7,9 @@ export default class WorkPackagesController { // Fetch all work packages, optionally filtered by query parameters static async getAllWorkPackages(req: Request, res: Response, next: NextFunction) { try { + setTimeout(() => { + console.log('This message appears after 1 second.'); + }, 1000); const { query } = req; const outputWorkPackages: WorkPackage[] = await WorkPackagesService.getAllWorkPackages(query, req.organization); @@ -22,6 +25,10 @@ export default class WorkPackagesController { try { const { status } = req.query as { status?: string }; + setTimeout(() => { + console.log('This message appears after 1 second.'); + }, 1000); + const outputWorkPackages: WorkPackagePreview[] = await WorkPackagesService.getAllWorkPackagesPreview( status, req.organization @@ -50,6 +57,10 @@ export default class WorkPackagesController { try { const { wbsNums } = req.body; + setTimeout(() => { + console.log('This message appears after 1 second.'); + }, 1000); + const workPackages: WorkPackage[] = await WorkPackagesService.getManyWorkPackages(wbsNums, req.organization); res.status(200).json(workPackages); } catch (error: unknown) { diff --git a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx index 339b2f23dc..a4c9fa3177 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx @@ -38,6 +38,7 @@ export const getStatusIcon = (status: string, isLarge?: boolean) => { interface CalendarDayCardProps { cardDate: Date; + displayMonth: Date; events: EventInstance[]; eventTypes?: EventType[]; calendars?: Calendar[]; @@ -47,6 +48,7 @@ interface CalendarDayCardProps { const CalendarDayCard: React.FC = ({ cardDate, + displayMonth, events, eventTypes = [], calendars = [], @@ -55,9 +57,16 @@ const CalendarDayCard: React.FC = ({ }) => { const theme = useTheme(); - const today = new Date().toDateString(); - const isCurrentDay = cardDate.toDateString() === today; - const isFutureDay = cardDate >= new Date(); + const today = new Date(); + today.setHours(0, 0, 0, 0); + const isCurrentDay = cardDate.toDateString() === today.toDateString(); + const isCurrentMonth = + cardDate.getMonth() === displayMonth.getMonth() && cardDate.getFullYear() === displayMonth.getFullYear(); + const isFutureDay = cardDate >= today; + const isClickable = isFutureDay || isCurrentDay; + + // Track hover state for stable hover effect + const [isHovered, setIsHovered] = useState(false); // Track which event's tooltip is locked open after clicking const [lockedTooltipEventId, setLockedTooltipEventId] = useState(null); @@ -99,7 +108,7 @@ const CalendarDayCard: React.FC = ({ margin={0.5} noWrap sx={{ - color: !(isFutureDay || isCurrentDay) ? theme.palette.grey[100] : theme.palette.grey[600], + color: isCurrentMonth ? theme.palette.grey[100] : theme.palette.grey[500], fontSize: 16, fontWeight: 500 }} @@ -393,21 +402,27 @@ const CalendarDayCard: React.FC = ({ )} isClickable && setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} sx={{ position: 'relative', - backgroundColor: !(isFutureDay || isCurrentDay) ? theme.palette.grey[900] : 'inherit', + backgroundColor: !isCurrentMonth + ? '#1f1f1f' + : isHovered + ? '#383838' + : '#2a2a2a', borderRadius: 2, - width: { xs: '98%', md: '90%' }, - height: { xs: '10vh', sm: '12vh' }, + width: '100%', + height: '100%', border: isCurrentDay ? '2px solid gray' : 'none', - cursor: isFutureDay || isCurrentDay ? 'pointer' : 'default', - transition: 'background 0.2s', - '&:hover': isFutureDay || isCurrentDay ? { background: '#232323' } : {} + cursor: isClickable ? 'pointer' : 'default', + transition: 'background-color 0.15s ease-in-out', + opacity: isCurrentMonth ? 1 : 0.5 }} > { - if (isFutureDay || isCurrentDay) onCreateEventClick(); + if (isClickable) onCreateEventClick(); }} sx={{ position: 'absolute', diff --git a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx index dcfdfe9c3a..dbce29e4e7 100644 --- a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx @@ -412,11 +412,13 @@ const NewCalendarPage: React.FC = ({ sx={{ display: 'flex', gap: 2, - height: '100vh' + height: 'calc(100vh - 120px)', + overflow: 'hidden', + pb: 2 }} > - - + + {enumToArray(DAY_NAMES).map((day, index) => ( @@ -428,10 +430,29 @@ const NewCalendarPage: React.FC = ({ ))} - - - {startOfEachWeek.map((week, weekIndex) => ( - + + {startOfEachWeek + .filter((week) => daysThisMonth.slice(week, week + 7).length > 0) + .map((week, weekIndex) => ( + {daysThisMonth.slice(week, week + 7).map((day, dayIndex) => { const cardDate = new Date( displayMonthYear.getFullYear(), @@ -439,30 +460,38 @@ const NewCalendarPage: React.FC = ({ day ); return ( - - - - - + + + ); })} - + ))} - = ({ width: 320, display: 'flex', flexDirection: 'column', - gap: 2 + gap: 0, + overflow: 'hidden' }} > - + setDisplayMonthYear(newDate)} @@ -511,17 +541,20 @@ const NewCalendarPage: React.FC = ({ sx={{ display: 'flex', flexDirection: 'column', - minHeight: '15vh', - maxHeight: '30vh' + flex: 1, + minHeight: 0, + overflow: 'hidden', + mt: -2 }} > - + My Upcoming Meetings: {upcomingOccurences && ( = ({ sx={{ display: 'flex', flexDirection: 'column', - minHeight: '15vh', - maxHeight: '30vh' + flexShrink: 0 }} > Date: Sat, 24 Jan 2026 14:11:59 -0500 Subject: [PATCH 475/477] recurring event edit logic --- .../src/controllers/calendar.controllers.ts | 15 + .../controllers/work-packages.controllers.ts | 11 - src/backend/src/routes/calendar.routes.ts | 5 + src/backend/src/services/calendar.services.ts | 120 +- src/backend/src/utils/calendar.utils.ts | 42 +- src/frontend/src/apis/calendar.api.ts | 14 +- src/frontend/src/hooks/calendar.hooks.ts | 23 +- .../pages/CalendarPage/CalendarDayCard.tsx | 6 +- .../Components/EditEventModal.tsx | 1 + .../EditSeriesConfirmationModal.tsx | 205 +++ .../CalendarPage/Components/EventModal.tsx | 1622 +++++++++-------- .../pages/CalendarPage/NewCalendarPage.tsx | 5 +- src/frontend/src/utils/urls.ts | 3 + 13 files changed, 1263 insertions(+), 809 deletions(-) create mode 100644 src/frontend/src/pages/CalendarPage/Components/EditSeriesConfirmationModal.tsx diff --git a/src/backend/src/controllers/calendar.controllers.ts b/src/backend/src/controllers/calendar.controllers.ts index 02b6fd71e3..bda9025559 100644 --- a/src/backend/src/controllers/calendar.controllers.ts +++ b/src/backend/src/controllers/calendar.controllers.ts @@ -380,6 +380,21 @@ export default class CalendarController { } } + static async previewScheduleSlotRecurringEdits(req: Request, res: Response, next: NextFunction) { + try { + const { scheduleSlotId } = req.params as Record; + + const affectedSlots = await CalendarService.previewScheduleSlotRecurringEdits( + req.currentUser, + scheduleSlotId, + req.organization + ); + res.status(200).json(affectedSlots); + } catch (error: unknown) { + next(error); + } + } + static async uploadDocument(req: Request, res: Response, next: NextFunction) { try { const { file } = req; diff --git a/src/backend/src/controllers/work-packages.controllers.ts b/src/backend/src/controllers/work-packages.controllers.ts index 0228861eec..2c0b34ddf9 100644 --- a/src/backend/src/controllers/work-packages.controllers.ts +++ b/src/backend/src/controllers/work-packages.controllers.ts @@ -7,9 +7,6 @@ export default class WorkPackagesController { // Fetch all work packages, optionally filtered by query parameters static async getAllWorkPackages(req: Request, res: Response, next: NextFunction) { try { - setTimeout(() => { - console.log('This message appears after 1 second.'); - }, 1000); const { query } = req; const outputWorkPackages: WorkPackage[] = await WorkPackagesService.getAllWorkPackages(query, req.organization); @@ -25,10 +22,6 @@ export default class WorkPackagesController { try { const { status } = req.query as { status?: string }; - setTimeout(() => { - console.log('This message appears after 1 second.'); - }, 1000); - const outputWorkPackages: WorkPackagePreview[] = await WorkPackagesService.getAllWorkPackagesPreview( status, req.organization @@ -57,10 +50,6 @@ export default class WorkPackagesController { try { const { wbsNums } = req.body; - setTimeout(() => { - console.log('This message appears after 1 second.'); - }, 1000); - const workPackages: WorkPackage[] = await WorkPackagesService.getManyWorkPackages(wbsNums, req.organization); res.status(200).json(workPackages); } catch (error: unknown) { diff --git a/src/backend/src/routes/calendar.routes.ts b/src/backend/src/routes/calendar.routes.ts index 7519f03949..89b134746b 100644 --- a/src/backend/src/routes/calendar.routes.ts +++ b/src/backend/src/routes/calendar.routes.ts @@ -159,6 +159,11 @@ calendarRouter.post( CalendarController.editScheduleSlot ); +calendarRouter.get( + '/event/:eventId/schedule-slot/:scheduleSlotId/preview-recurring-edits', + CalendarController.previewScheduleSlotRecurringEdits +); + calendarRouter.get('/document/:fileId', CalendarController.downloadDocument); calendarRouter.post( diff --git a/src/backend/src/services/calendar.services.ts b/src/backend/src/services/calendar.services.ts index 17b2437860..1a727902f6 100644 --- a/src/backend/src/services/calendar.services.ts +++ b/src/backend/src/services/calendar.services.ts @@ -12,7 +12,8 @@ import { Shop, Calendar, FilterArgs, - Machinery + Machinery, + ScheduleSlot } from 'shared'; import { getCalendarQueryArgs } from '../prisma-query-args/calendar.query-args.js'; import { getEventTypeQueryArgs } from '../prisma-query-args/event-type.query-args.js'; @@ -35,7 +36,8 @@ import { checkEventConflicts, removeDeletedEventDocuments, isUserOnEvent, - buildScheduledTimesOverlap + buildScheduledTimesOverlap, + findMatchingTimeOfDaySlots } from '../utils/calendar.utils.js'; import { AccessDeniedAdminOnlyException, @@ -823,6 +825,93 @@ export default class CalendarService { return edittedEvent; } + /** + * Previews which schedule slots would be affected when editing a slot with "edit all in series". + * Returns only the OTHER slots that would be edited (excludes the current slot being edited). + * + * @param submitter The user submitting the request. + * @param scheduleSlotId The id of the specific schedule slot being edited. + * @param organization The organization context. + * + * @returns Array of schedule slots (excluding the current one) that have the same time-of-day pattern. + * + * @throws NotFoundException If the schedule slot or event is not found. + * @throws AccessDeniedException If the user doesn't have permission. + */ + static async previewScheduleSlotRecurringEdits( + submitter: User, + scheduleSlotId: string, + organization: Organization + ): Promise { + // Validate schedule slot exists and get its eventId + const scheduleSlot = await prisma.schedule_Slot.findUnique({ + where: { scheduleSlotId }, + select: { + scheduleSlotId: true, + eventId: true, + startTime: true, + endTime: true, + allDay: true + } + }); + + if (!scheduleSlot) throw new NotFoundException('Schedule Slot', scheduleSlotId); + + // Now fetch the event separately to check permissions + const event = await prisma.event.findUnique({ + where: { eventId: scheduleSlot.eventId }, + select: { + eventId: true, + userCreatedId: true, + location: true, + dateDeleted: true + } + }); + + if (!event) throw new NotFoundException('Event', scheduleSlot.eventId); + if (event.dateDeleted) throw new DeletedException('Event', scheduleSlot.eventId); + + // Check permissions + const hasPermission = + (await userHasPermission(submitter.userId, organization.organizationId, isHead)) || + submitter.userId === event.userCreatedId; + + if (!hasPermission) { + throw new AccessDeniedException( + 'Only admins, heads, or the event creator can see how editing this schedule slot will affect the event.' + ); + } + + // Fetch all schedule slots for this event + const allSlots = await prisma.schedule_Slot.findMany({ + where: { eventId: scheduleSlot.eventId }, + select: { + scheduleSlotId: true, + startTime: true, + endTime: true, + allDay: true + } + }); + + // Find all slots with matching time-of-day pattern + const matchingSlots = findMatchingTimeOfDaySlots(allSlots, scheduleSlotId); + + // Get today's date at midnight for comparison (day portion only) + const today = new Date(); + today.setHours(0, 0, 0, 0); + + // Exclude the current slot and any slots in the past (based on day only) + const otherAffectedSlots = matchingSlots.filter((slot) => { + if (slot.scheduleSlotId === scheduleSlotId) return false; + + const slotDate = new Date(slot.startTime); + slotDate.setHours(0, 0, 0, 0); + return slotDate >= today; + }); + + return otherAffectedSlots; + } + /** * Edits a specific schedule slot of an event. * Used when a user wants to change the time/date of a single occurrence in a recurring event. @@ -907,31 +996,14 @@ export default class CalendarService { select: { scheduleSlotId: true, startTime: true, - endTime: true + endTime: true, + allDay: true } }); - // Get the original slot's time-of-day - const originalSlot = allSlots.find((s) => s.scheduleSlotId === scheduleSlotId); - if (originalSlot && originalSlot.startTime && originalSlot.endTime) { - const originalStartHour = originalSlot.startTime.getHours(); - const originalStartMinute = originalSlot.startTime.getMinutes(); - const originalEndHour = originalSlot.endTime.getHours(); - const originalEndMinute = originalSlot.endTime.getMinutes(); - - // Find all slots that have the same time-of-day - slotsToUpdate = allSlots - .filter((slot) => { - if (!slot.startTime || !slot.endTime) return false; - return ( - slot.startTime.getHours() === originalStartHour && - slot.startTime.getMinutes() === originalStartMinute && - slot.endTime.getHours() === originalEndHour && - slot.endTime.getMinutes() === originalEndMinute - ); - }) - .map((slot) => slot.scheduleSlotId); - } + // Use helper function to find all slots with matching time-of-day + const matchingSlots = findMatchingTimeOfDaySlots(allSlots, scheduleSlotId); + slotsToUpdate = matchingSlots.map((slot) => slot.scheduleSlotId); } // Calculate the time offset from the original slot to the new time diff --git a/src/backend/src/utils/calendar.utils.ts b/src/backend/src/utils/calendar.utils.ts index df86da66b1..34c4ed603f 100644 --- a/src/backend/src/utils/calendar.utils.ts +++ b/src/backend/src/utils/calendar.utils.ts @@ -6,8 +6,7 @@ import { Document, ConflictStatus, Event, - EventWithMembers, - DayOfWeek + EventWithMembers } from 'shared'; import { InvalidEventTypeConfigurationException } from './errors.utils.js'; import prisma from '../prisma/prisma.js'; @@ -264,7 +263,6 @@ export async function checkEventConflicts( allDayDate.setHours(0, 0, 0, 0); const timedStart = new Date(timedSlot.startTime!); - const timedEnd = new Date(timedSlot.endTime!); const timedDate = new Date(timedStart); timedDate.setHours(0, 0, 0, 0); @@ -319,3 +317,41 @@ export const removeDeletedEventDocuments = async ( } }); }; + +/** + * Finds all schedule slots that have the same time-of-day pattern as the original slot. + * This is used for "edit all in series" functionality where we want to update all slots + * that were created with the same recurring time pattern. + * + * @param allSlots All schedule slots for an event + * @param originalSlotId The ID of the slot being edited + * @returns Array of schedule slots that match the original slot's time-of-day pattern + */ +export const findMatchingTimeOfDaySlots = ( + allSlots: T[], + originalSlotId: string +): T[] => { + const originalSlot = allSlots.find((s) => s.scheduleSlotId === originalSlotId); + + if (!originalSlot || !originalSlot.startTime || !originalSlot.endTime) { + // If we can't find the original slot or it has no times, return just that slot + const slot = allSlots.find((s) => s.scheduleSlotId === originalSlotId); + return slot ? [slot] : []; + } + + const originalStartHour = originalSlot.startTime.getHours(); + const originalStartMinute = originalSlot.startTime.getMinutes(); + const originalEndHour = originalSlot.endTime.getHours(); + const originalEndMinute = originalSlot.endTime.getMinutes(); + + // Find all slots that have the same time-of-day + return allSlots.filter((slot) => { + if (!slot.startTime || !slot.endTime) return false; + return ( + slot.startTime.getHours() === originalStartHour && + slot.startTime.getMinutes() === originalStartMinute && + slot.endTime.getHours() === originalEndHour && + slot.endTime.getMinutes() === originalEndMinute + ); + }); +}; diff --git a/src/frontend/src/apis/calendar.api.ts b/src/frontend/src/apis/calendar.api.ts index feec988c46..a223a67da5 100644 --- a/src/frontend/src/apis/calendar.api.ts +++ b/src/frontend/src/apis/calendar.api.ts @@ -9,7 +9,8 @@ import { EventStatus, EventTypeCreateArgs, Calendar, - FilterArgs + FilterArgs, + ScheduleSlot } from 'shared'; import { eventTransformer } from './transformers/calendar.transformer'; import { EditEventArgs, EditScheduleSlotArgs, EventCreateArgs } from '../hooks/calendar.hooks'; @@ -206,6 +207,17 @@ export const postEditScheduleSlot = async (eventId: string, scheduleSlotId: stri }); }; +export const previewScheduleSlotRecurringEdits = async (eventId: string, scheduleSlotId: string) => { + return axios.get(apiUrls.calendarPreviewScheduleSlotRecurringEdits(eventId, scheduleSlotId), { + transformResponse: (data) => + JSON.parse(data).map((slot: { scheduleSlotId: string; startTime: string; endTime: string; allDay: boolean }) => ({ + ...slot, + startTime: new Date(slot.startTime), + endTime: new Date(slot.endTime) + })) + }); +}; + /** * Upload a document * diff --git a/src/frontend/src/hooks/calendar.hooks.ts b/src/frontend/src/hooks/calendar.hooks.ts index 809c889caf..9a83451722 100644 --- a/src/frontend/src/hooks/calendar.hooks.ts +++ b/src/frontend/src/hooks/calendar.hooks.ts @@ -10,7 +10,8 @@ import { EventType, FilterArgs, ScheduleSlotCreateArgs, - EventWithMembers + EventWithMembers, + ScheduleSlot } from 'shared'; import { getAllShops, @@ -44,7 +45,8 @@ import { downloadDocumentPdf, postEditEvent, postEditScheduleSlot, - getSingleEventWithMembers + getSingleEventWithMembers, + previewScheduleSlotRecurringEdits } from '../apis/calendar.api'; import { useCurrentUser } from './users.hooks'; import { PDFDocument } from 'pdf-lib'; @@ -506,6 +508,23 @@ export const useEditScheduleSlot = (eventId: string, scheduleSlotId: string) => ); }; +/** + * Hook to get a preview of other schedule slots that would be affected + * when editing a schedule slot with "edit all in series" enabled. + */ +export const usePreviewScheduleSlotRecurringEdits = (eventId: string, scheduleSlotId: string, enabled: boolean = true) => { + return useQuery( + ['events', 'schedule-slot-recurring-edits-preview', eventId, scheduleSlotId], + async () => { + const { data } = await previewScheduleSlotRecurringEdits(eventId, scheduleSlotId); + return data; + }, + { + enabled: enabled && !!eventId && !!scheduleSlotId + } + ); +}; + export const useDenyEvent = (id: string) => { const queryClient = useQueryClient(); return useMutation( diff --git a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx index a4c9fa3177..b9af5fcbd9 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx @@ -406,11 +406,7 @@ const CalendarDayCard: React.FC = ({ onMouseLeave={() => setIsHovered(false)} sx={{ position: 'relative', - backgroundColor: !isCurrentMonth - ? '#1f1f1f' - : isHovered - ? '#383838' - : '#2a2a2a', + backgroundColor: !isCurrentMonth ? '#1f1f1f' : isHovered ? '#383838' : '#2a2a2a', borderRadius: 2, width: '100%', height: '100%', diff --git a/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx index 48af6347f5..62c1b78806 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EditEventModal.tsx @@ -76,6 +76,7 @@ const EditEventModal: React.FC = ({ open, onClose, event, e onSubmit={handleSubmit} initialValues={initialValues} eventTypes={eventTypes} + eventId={event.eventId} /> ); }; diff --git a/src/frontend/src/pages/CalendarPage/Components/EditSeriesConfirmationModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EditSeriesConfirmationModal.tsx new file mode 100644 index 0000000000..ea388a8e46 --- /dev/null +++ b/src/frontend/src/pages/CalendarPage/Components/EditSeriesConfirmationModal.tsx @@ -0,0 +1,205 @@ +import React, { useState, useMemo } from 'react'; +import { + Dialog, + DialogTitle, + DialogContent, + DialogActions, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + Typography, + Box +} from '@mui/material'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import NERFailButton from '../../../components/NERFailButton'; +import NERSuccessButton from '../../../components/NERSuccessButton'; +import { ScheduleSlot } from 'shared'; + +const headerBackground = '#ef4345'; + +export interface EditSeriesConfirmationModalProps { + open: boolean; + onCancel: () => void; + onConfirm: (editAllInSeries: boolean) => void; + affectedSlots?: ScheduleSlot[]; + originalStartTime?: Date; + originalEndTime?: Date; + newStartTime?: Date; + newEndTime?: Date; +} + +/** + * Formats a date for display (e.g., "Mon, Jan 15") + */ +const formatDate = (date: Date): string => { + return date.toLocaleDateString('en-US', { + weekday: 'short', + month: 'short', + day: 'numeric' + }); +}; + +/** + * Formats a time for display (e.g., "2:30 PM") + */ +const formatTime = (date: Date): string => { + return date.toLocaleTimeString('en-US', { + hour: 'numeric', + minute: '2-digit', + hour12: true + }); +}; + +/** + * Formats a time range for display (e.g., "2:30 PM - 4:00 PM") + */ +const formatTimeRange = (start: Date, end: Date): string => { + return `${formatTime(start)} - ${formatTime(end)}`; +}; + +const EditSeriesConfirmationModal: React.FC = ({ + open, + onCancel, + onConfirm, + affectedSlots = [], + originalStartTime, + originalEndTime, + newStartTime, + newEndTime +}) => { + const [editAllInSeries, setEditAllInSeries] = useState(false); + + // Calculate new times for each affected slot based on the time offset + const affectedSlotsWithNewTimes = useMemo(() => { + if (!originalStartTime || !originalEndTime || !newStartTime || !newEndTime) { + return []; + } + + // Get the new time-of-day to apply to each slot + const newStartHours = newStartTime.getHours(); + const newStartMinutes = newStartTime.getMinutes(); + const newEndHours = newEndTime.getHours(); + const newEndMinutes = newEndTime.getMinutes(); + + return affectedSlots.map((slot) => { + const slotStart = new Date(slot.startTime); + const slotEnd = new Date(slot.endTime); + + // Apply the time-of-day change to each slot + const newSlotStart = new Date(slotStart); + newSlotStart.setHours(newStartHours, newStartMinutes, 0, 0); + + const newSlotEnd = new Date(slotEnd); + newSlotEnd.setHours(newEndHours, newEndMinutes, 0, 0); + + return { + ...slot, + originalStartTime: slotStart, + originalEndTime: slotEnd, + newStartTime: newSlotStart, + newEndTime: newSlotEnd + }; + }); + }, [affectedSlots, originalStartTime, originalEndTime, newStartTime, newEndTime]); + + const handleConfirm = () => { + onConfirm(editAllInSeries); + setEditAllInSeries(false); + }; + + const handleCancel = () => { + onCancel(); + setEditAllInSeries(false); + }; + + return ( + + Edit Time + + + You have changed the time for this event. Would you like to apply this change to all events in this series? + + + setEditAllInSeries(e.target.value === 'true')}> + } + label="This event only" + /> + } + label={`All events in the series (${affectedSlots.length + 1} events)`} + /> + + + + {/* Show affected events when "all events in series" is selected */} + {editAllInSeries && affectedSlotsWithNewTimes.length > 0 && ( + + + The following events will also be updated: + + + {affectedSlotsWithNewTimes + .sort((a, b) => a.originalStartTime.getTime() - b.originalStartTime.getTime()) + .map((slot) => ( + + + {formatDate(slot.originalStartTime)} + + + {formatTimeRange(slot.originalStartTime, slot.originalEndTime)} + + + + {formatTimeRange(slot.newStartTime, slot.newEndTime)} + + + ))} + + + )} + + + + + Cancel + + + Confirm + + + + + ); +}; + +export default EditSeriesConfirmationModal; diff --git a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx index 43b8184b16..64ef244630 100644 --- a/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx +++ b/src/frontend/src/pages/CalendarPage/Components/EventModal.tsx @@ -27,7 +27,8 @@ import { EventType, isHead, MAX_FILE_SIZE, - getNextSevenDays + getNextSevenDays, + ScheduleSlot } from 'shared'; import { useToast } from '../../../hooks/toasts.hooks'; import { useAllUsers, useCurrentUser } from '../../../hooks/users.hooks'; @@ -45,7 +46,7 @@ import DescriptionIcon from '@mui/icons-material/Description'; import BusinessIcon from '@mui/icons-material/Business'; import { useAllTeamTypes } from '../../../hooks/team-types.hooks'; import { ClearIcon } from '@mui/x-date-pickers'; -import { useAllMachines, useAllShops } from '../../../hooks/calendar.hooks'; +import { useAllMachines, useAllShops, usePreviewScheduleSlotRecurringEdits } from '../../../hooks/calendar.hooks'; import StoreIcon from '@mui/icons-material/Store'; import PrecisionManufacturingIcon from '@mui/icons-material/PrecisionManufacturing'; import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; @@ -53,6 +54,7 @@ import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; import Tooltip from '@mui/material/Tooltip'; import { convertDayToInt, convertIntToDay } from '../../../utils/calendar.utils'; import { getDay } from 'date-fns'; +import EditSeriesConfirmationModal from './EditSeriesConfirmationModal'; export interface EventFormValues { title: string; @@ -144,15 +146,35 @@ export interface BaseEventModalProps { initialValues?: Partial; eventTypes: EventType[]; defaultDate?: Date; + eventId?: string; // Required for edit mode to fetch preview of affected schedule slots } +/** + * Checks if the time has changed between initial values and current form data + */ +const hasTimeChanged = (initialValues: Partial | undefined, currentData: EventFormValues): boolean => { + if (!initialValues?.startTime || !initialValues?.endTime) return false; + + const originalStartTime = new Date(initialValues.startTime).getTime(); + const originalEndTime = new Date(initialValues.endTime).getTime(); + const currentStartTime = new Date(currentData.startTime).getTime(); + const currentEndTime = new Date(currentData.endTime).getTime(); + + return ( + originalStartTime !== currentStartTime || + originalEndTime !== currentEndTime || + initialValues.allDay !== currentData.allDay + ); +}; + const EventModal: React.FC = ({ open, onClose, onSubmit, initialValues, eventTypes, - defaultDate = new Date() + defaultDate = new Date(), + eventId }) => { const toast = useToast(); const user = useCurrentUser(); @@ -164,6 +186,20 @@ const EventModal: React.FC = ({ const [optionalMembers, setOptionalMembers] = useState>([]); const [selectedTeams, setSelectedTeams] = useState>([]); + // State for the series confirmation modal (only used in edit mode when time changes) + const [showSeriesConfirmModal, setShowSeriesConfirmModal] = useState(false); + const [pendingPayload, setPendingPayload] = useState(null); + const [pendingFormData, setPendingFormData] = useState(null); + + // Fetch preview of other schedule slots that would be affected when editing with "edit all in series" + const isEditMode = !!initialValues; + const scheduleSlotId = initialValues?.selectedScheduleSlotId; + const { data: affectedSlots = [] } = usePreviewScheduleSlotRecurringEdits( + eventId ?? '', + scheduleSlotId ?? '', + isEditMode && !!eventId && !!scheduleSlotId + ); + // Lazy load all data needed for the form so users can start filling out instantly const { isLoading: usersLoading, isError: usersError, error: usersErrorMsg, data: users } = useAllUsers(); const { isLoading: shopsLoading, isError: shopsError, error: shopsErrorMsg, data: shops } = useAllShops(); @@ -285,7 +321,6 @@ const EventModal: React.FC = ({ } }, [initialValues, users, teams]); - const isEditMode = !!initialValues; const computedTitle = isEditMode ? 'Edit Event' : 'Add Event'; // Handle recurring dropdown toggle @@ -400,7 +435,10 @@ const EventModal: React.FC = ({ } }; - const onFormSubmit = async (data: EventFormValues) => { + /** + * Builds the payload from form data + */ + const buildPayload = (data: EventFormValues, editAllInSeries: boolean = false): EventPayload => { const requiresConfirmation = selectedEventType?.requiresConfirmation ?? false; const payload: EventPayload = { @@ -430,7 +468,7 @@ const EventModal: React.FC = ({ newStartTime: data.startTime, newEndTime: data.endTime, newAllDay: data.allDay, - editAllInSeries: false // Always false for now as per requirements + editAllInSeries }; } else if (!isEditMode) { // For create mode, populate createScheduleSlotArgs @@ -443,10 +481,62 @@ const EventModal: React.FC = ({ }; } + return payload; + }; + + const onFormSubmit = async (data: EventFormValues) => { + // In edit mode, check if time has changed AND there are other affected slots + // Only show the confirmation modal if there are other slots that would be affected + if (isEditMode && data.selectedScheduleSlotId && hasTimeChanged(initialValues, data) && affectedSlots.length > 0) { + const payload = buildPayload(data, false); + setPendingPayload(payload); + setPendingFormData(data); + setShowSeriesConfirmModal(true); + // Return early - form stays open, confirmation modal will handle submission + return; + } + + // No time change, not in edit mode, or no other affected slots - submit directly + const payload = buildPayload(data, false); await onSubmit(payload); handleClose(); }; + /** + * Handles confirmation from the series confirmation modal + */ + const handleSeriesConfirmation = async (editAllInSeries: boolean) => { + if (!pendingPayload) return; + + // Update the payload with the user's choice + const updatedPayload: EventPayload = { + ...pendingPayload, + editScheduleSlotArgs: pendingPayload.editScheduleSlotArgs + ? { + ...pendingPayload.editScheduleSlotArgs, + editAllInSeries + } + : undefined + }; + + setShowSeriesConfirmModal(false); + setPendingPayload(null); + setPendingFormData(null); + + await onSubmit(updatedPayload); + handleClose(); + }; + + /** + * Handles cancellation of the series confirmation modal + */ + const handleSeriesCancelConfirmation = () => { + setShowSeriesConfirmModal(false); + setPendingPayload(null); + setPendingFormData(null); + // Form stays open with user's changes preserved + }; + // When data loads from endpoint, update the options for the autocomplete fields const memberOptions = useMemo(() => { if (usersLoading || !users) return [{ id: 'loading', label: 'Loading users...' }]; @@ -486,850 +576,862 @@ const EventModal: React.FC = ({ }); return ( - - - {/* Title Input with red placeholder styling */} - - ( - + + {}} + handleUseFormSubmit={handleSubmit} + onFormSubmit={onFormSubmit} + formId="event-form" + showCloseButton + > + + {/* Title Input with red placeholder styling */} + + ( + - )} - /> - {errors.title?.message} - - {/* Event Type Tabs */} - - - {allowedEventTypes.map((et) => ( - - ))} - - {errors.eventTypeId?.message} - - {/* Date and Time Section - Only show when event type is selected */} - {selectedEventType && ( - - {selectedEventType.requiresConfirmation ? ( - - {/* Header with info tooltip */} - - - - - - To be scheduled within: - - - - - ( - setDatePickerOpen(false)} - onOpen={() => setDatePickerOpen(true)} - onChange={(newValue) => onChange(newValue ?? defaultDate)} - slotProps={{ - textField: { - variant: 'standard', - error: !!errors.scheduleDate, - onClick: () => setDatePickerOpen(true), - sx: { minWidth: 150 } - }, - day: { - sx: { - '&.Mui-selected': { - backgroundColor: '#EF4345 !important', - '&:hover': { - backgroundColor: '#d32f2f !important' - }, - '&:focus': { - backgroundColor: '#EF4345 !important' - } - } - } - } - }} - /> - )} - /> - - { - const weekDates = getNextSevenDays(value); - const endDate = weekDates.at(-1); - return ( + }} + /> + )} + /> + {errors.title?.message} + + {/* Event Type Tabs */} + + + {allowedEventTypes.map((et) => ( + + ))} + + {errors.eventTypeId?.message} + + {/* Date and Time Section - Only show when event type is selected */} + {selectedEventType && ( + + {selectedEventType.requiresConfirmation ? ( + + {/* Header with info tooltip */} + + + + + + To be scheduled within: + + + + + ( setDatePickerOpen(false)} + onOpen={() => setDatePickerOpen(true)} + onChange={(newValue) => onChange(newValue ?? defaultDate)} slotProps={{ textField: { variant: 'standard', + error: !!errors.scheduleDate, + onClick: () => setDatePickerOpen(true), sx: { minWidth: 150 } }, day: { sx: { '&.Mui-selected': { - backgroundColor: '#EF4345 !important' + backgroundColor: '#EF4345 !important', + '&:hover': { + backgroundColor: '#d32f2f !important' + }, + '&:focus': { + backgroundColor: '#EF4345 !important' + } } } } }} /> - ); - }} - /> - - - ) : ( - /* Normal Event Type - Full date/time selection */ - <> - {/* Date and Time Row */} - - - ( - setDatePickerOpen(false)} - onOpen={() => setDatePickerOpen(true)} - onChange={(newValue) => onChange(newValue ?? defaultDate)} - slotProps={{ - textField: { - variant: 'standard', - error: !!errors.scheduleDate, - onClick: () => setDatePickerOpen(true), - sx: { minWidth: 150 } - }, - day: { - sx: { - '&.Mui-selected': { - backgroundColor: '#EF4345 !important', - '&:hover': { - backgroundColor: '#d32f2f !important' - }, - '&:focus': { - backgroundColor: '#EF4345 !important' - } - } - } - } - }} - /> - )} - /> - - {!watch('allDay') && ( - <> - ( - setStartTimePickerOpen(false)} - onOpen={() => setStartTimePickerOpen(true)} - onChange={(newValue) => onChange(newValue)} + )} + /> + + { + const weekDates = getNextSevenDays(value); + const endDate = weekDates.at(-1); + return ( + setStartTimePickerOpen(true), - sx: { width: 100 } + sx: { minWidth: 150 } }, - layout: { + day: { sx: { - '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { - backgroundColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { - backgroundColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { - backgroundColor: '#EF4345', - borderColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { + '&.Mui-selected': { backgroundColor: '#EF4345 !important' - }, - '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { - backgroundColor: '#EF4345 !important', - color: 'white' - }, - '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { - backgroundColor: '#EF4345 !important', - color: 'white' } } } }} /> - )} - /> - - - ( - setEndTimePickerOpen(false)} - onOpen={() => setEndTimePickerOpen(true)} - onChange={(newValue) => onChange(newValue)} - slotProps={{ - textField: { - variant: 'standard', - error: !!errors.endTime, - onClick: () => setEndTimePickerOpen(true), - sx: { width: 100 } - }, - layout: { - sx: { - '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { - backgroundColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { - backgroundColor: '#EF4345' - }, - '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { - backgroundColor: '#EF4345', - borderColor: '#EF4345' + ); + }} + /> + + + ) : ( + /* Normal Event Type - Full date/time selection */ + <> + {/* Date and Time Row */} + + + ( + setDatePickerOpen(false)} + onOpen={() => setDatePickerOpen(true)} + onChange={(newValue) => onChange(newValue ?? defaultDate)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.scheduleDate, + onClick: () => setDatePickerOpen(true), + sx: { minWidth: 150 } + }, + day: { + sx: { + '&.Mui-selected': { + backgroundColor: '#EF4345 !important', + '&:hover': { + backgroundColor: '#d32f2f !important' }, - '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { + '&:focus': { backgroundColor: '#EF4345 !important' - }, - '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { - backgroundColor: '#EF4345 !important', - color: 'white' - }, - '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { - backgroundColor: '#EF4345 !important', - color: 'white' } } } - }} - /> - )} - /> - - )} - + } + }} + /> + )} + /> - {/* All Day and Recurring Row */} - - ( - onChange(e.target.checked)} />} - label="All Day" - /> + {!watch('allDay') && ( + <> + ( + setStartTimePickerOpen(false)} + onOpen={() => setStartTimePickerOpen(true)} + onChange={(newValue) => onChange(newValue)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.startTime, + onClick: () => setStartTimePickerOpen(true), + sx: { width: 100 } + }, + layout: { + sx: { + '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { + backgroundColor: '#EF4345', + borderColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { + backgroundColor: '#EF4345 !important' + }, + '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + }, + '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + } + } + } + }} + /> + )} + /> + - + ( + setEndTimePickerOpen(false)} + onOpen={() => setEndTimePickerOpen(true)} + onChange={(newValue) => onChange(newValue)} + slotProps={{ + textField: { + variant: 'standard', + error: !!errors.endTime, + onClick: () => setEndTimePickerOpen(true), + sx: { width: 100 } + }, + layout: { + sx: { + '& .MuiPickersLayout-contentWrapper .MuiClock-pin': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-root': { + backgroundColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockPointer-thumb': { + backgroundColor: '#EF4345', + borderColor: '#EF4345' + }, + '& .MuiPickersLayout-contentWrapper .MuiClockNumber-root.Mui-selected': { + backgroundColor: '#EF4345 !important' + }, + '& .MuiPickersLayout-contentWrapper .MuiPickersArrowSwitcher-button.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + }, + '& .MuiMultiSectionDigitalClock-root .MuiMenuItem-root.Mui-selected': { + backgroundColor: '#EF4345 !important', + color: 'white' + } + } + } + }} + /> + )} + /> + )} - /> + - {/* Hide recurring options when editing */} - {!isEditMode && ( - + )} + + + {/* Recurring Options */} + {showRecurringOptions && ( + 0 ? 'grey.400' : 'transparent' + border: '1px solid', + borderColor: 'grey.300' }} > - Recurring ▼ - - )} - + + + Repeat + + ( + + )} + /> + + more time(s) + + - {/* Recurring Options */} - {showRecurringOptions && ( - - - - Repeat + + Repeat on: ( - - )} - /> - - more time(s) - - + render={({ field: { onChange, value } }) => { + const weekDays: DayOfWeek[] = [ + DayOfWeek.SUNDAY, + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SATURDAY + ]; + const dayLabels = ['S', 'M', 'T', 'W', 'TH', 'F', 'S']; - - Repeat on: - - { - const weekDays: DayOfWeek[] = [ - DayOfWeek.SUNDAY, - DayOfWeek.MONDAY, - DayOfWeek.TUESDAY, - DayOfWeek.WEDNESDAY, - DayOfWeek.THURSDAY, - DayOfWeek.FRIDAY, - DayOfWeek.SATURDAY - ]; - const dayLabels = ['S', 'M', 'T', 'W', 'TH', 'F', 'S']; - - const toggleDay = (day: DayOfWeek) => { - const currentDays = value || []; - if (currentDays.includes(day)) { - onChange(currentDays.filter((d) => d !== day)); - } else { - onChange([...currentDays, day]); - } - }; + const toggleDay = (day: DayOfWeek) => { + const currentDays = value || []; + if (currentDays.includes(day)) { + onChange(currentDays.filter((d) => d !== day)); + } else { + onChange([...currentDays, day]); + } + }; - return ( - - {weekDays.map((day, index) => { - const isSelected = (value || []).includes(day); - return ( - - ); - })} - - ); - }} - /> + return ( + + {weekDays.map((day, index) => { + const isSelected = (value || []).includes(day); + return ( + + ); + })} + + ); + }} + /> - {errors.days && ( - - {errors.days.message} - - )} + {errors.days && ( + + {errors.days.message} + + )} - {/* Last Occurrence Info */} - {watch('recurrenceNumber') > 0 && watch('days').length > 0 ? ( - + {/* Last Occurrence Info */} + {watch('recurrenceNumber') > 0 && watch('days').length > 0 ? ( + + + Last occurrence:{' '} + {calculateLastOccurrenceDate()?.toLocaleDateString('en-US', { + weekday: 'long', + month: 'long', + day: 'numeric', + year: 'numeric' + })} + + + ) : ( - Last occurrence:{' '} - {calculateLastOccurrenceDate()?.toLocaleDateString('en-US', { - weekday: 'long', - month: 'long', - day: 'numeric', - year: 'numeric' - })} + {watch('days').length === 0 + ? 'Select at least one day to see the last occurrence date.' + : "Select the number of times you'd like this event to recur."} - - ) : ( - - {watch('days').length === 0 - ? 'Select at least one day to see the last occurrence date.' - : "Select the number of times you'd like this event to recur."} - - )} - - )} - - )} - - )} - {/* Required Members Section */} - {selectedEventType?.requiredMembers && ( - - - - - - {requiredMembers.map((member) => ( - setRequiredMembers((prev) => prev.filter((m) => m.id !== member.id))} - sx={{ bgcolor: 'grey.700' }} + )} + + )} + + )} + + )} + {/* Required Members Section */} + {selectedEventType?.requiredMembers && ( + + + + + + {requiredMembers.map((member) => ( + setRequiredMembers((prev) => prev.filter((m) => m.id !== member.id))} + sx={{ bgcolor: 'grey.700' }} + /> + ))} + !requiredMembers.find((rm) => rm.id === m.id))} + onChange={(_, newValue) => { + if (newValue) setRequiredMembers((prev) => [...prev, newValue]); + }} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + sx={{ flex: 1, minWidth: 150 }} /> - ))} - !requiredMembers.find((rm) => rm.id === m.id))} - onChange={(_, newValue) => { - if (newValue) setRequiredMembers((prev) => [...prev, newValue]); - }} - getOptionLabel={(option) => option.label} - renderInput={(params) => ( - - )} - sx={{ flex: 1, minWidth: 150 }} - /> + - - )} - {/* Optional Members Section */} - {selectedEventType?.optionalMembers && ( - - - - - - {optionalMembers.map((member) => ( - setOptionalMembers((prev) => prev.filter((m) => m.id !== member.id))} - sx={{ bgcolor: 'grey.700', opacity: 0.7 }} + )} + {/* Optional Members Section */} + {selectedEventType?.optionalMembers && ( + + + + + + {optionalMembers.map((member) => ( + setOptionalMembers((prev) => prev.filter((m) => m.id !== member.id))} + sx={{ bgcolor: 'grey.700', opacity: 0.7 }} + /> + ))} + !optionalMembers.find((om) => om.id === m.id))} + onChange={(_, newValue) => { + if (newValue) setOptionalMembers((prev) => [...prev, newValue]); + }} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + sx={{ flex: 1, minWidth: 150 }} /> - ))} - !optionalMembers.find((om) => om.id === m.id))} - onChange={(_, newValue) => { - if (newValue) setOptionalMembers((prev) => [...prev, newValue]); - }} - getOptionLabel={(option) => option.label} - renderInput={(params) => ( - - )} - sx={{ flex: 1, minWidth: 150 }} - /> + - - )} - {/* Teams Section */} - {selectedEventType?.teams && ( - - - - - - {selectedTeams.map((team) => ( - setSelectedTeams((prev) => prev.filter((t) => t.id !== team.id))} - sx={{ bgcolor: 'grey.700', opacity: 0.7 }} + )} + {/* Teams Section */} + {selectedEventType?.teams && ( + + + + + + {selectedTeams.map((team) => ( + setSelectedTeams((prev) => prev.filter((t) => t.id !== team.id))} + sx={{ bgcolor: 'grey.700', opacity: 0.7 }} + /> + ))} + !selectedTeams.find((st) => st.id === t.id))} + onChange={(_, newValue) => { + if (newValue) setSelectedTeams((prev) => [...prev, newValue]); + }} + getOptionLabel={(option) => option.label} + renderInput={(params) => ( + + )} + sx={{ flex: 1, minWidth: 150 }} /> - ))} - !selectedTeams.find((st) => st.id === t.id))} - onChange={(_, newValue) => { - if (newValue) setSelectedTeams((prev) => [...prev, newValue]); - }} - getOptionLabel={(option) => option.label} - renderInput={(params) => ( - - )} - sx={{ flex: 1, minWidth: 150 }} - /> + - - )} - {/* Team Type */} - {selectedEventType?.teamType && ( - - - ( - onChange(e.target.value)} + variant="standard" + displayEmpty + sx={{ flex: 1 }} + > + + Select Team Type - ))} - - )} - /> - - )} - {/* Location */} - {selectedEventType?.location && ( - - - ( - - )} - /> - - )} - {/* Zoom Link */} - {selectedEventType?.zoomLink && ( - - - + {teamTypes?.map((tt) => ( + + {tt.name} + + ))} + + )} + /> + + )} + {/* Location */} + {selectedEventType?.location && ( + + ( )} /> - {errors.zoomLink?.message} - - - )} - {selectedEventType?.shop && ( - + + )} + {/* Zoom Link */} + {selectedEventType?.zoomLink && ( + + + + ( + + )} + /> + {errors.zoomLink?.message} + + + )} + {selectedEventType?.shop && ( + + + + ( + value?.[0] === s.id) || null} + onChange={(_, newValue) => onChange(newValue ? [newValue.id] : [])} + getOptionLabel={(option) => option.label} + renderInput={(params) => } + sx={{ flex: 1 }} + /> + )} + /> + + {shopIds.length > 0 && ( + + {(() => { + const shop = shops?.find((s) => s.shopId === shopIds[0]); + if (!shop || !shop.description) return null; + return ( + + + Reserve on Robin: + + + {shop.description} + + + ); + })()} + + )} + + )} + {selectedEventType?.machinery && ( - + ( value?.[0] === s.id) || null} + options={filteredMachineryOptions} + value={filteredMachineryOptions.find((m) => value?.[0] === m.id) || null} onChange={(_, newValue) => onChange(newValue ? [newValue.id] : [])} getOptionLabel={(option) => option.label} - renderInput={(params) => } + renderInput={(params) => } sx={{ flex: 1 }} /> )} /> - {shopIds.length > 0 && ( - - {(() => { - const shop = shops?.find((s) => s.shopId === shopIds[0]); - if (!shop || !shop.description) return null; - return ( - - - Reserve on Robin: - - - {shop.description} - - - ); - })()} - - )} - - )} - {selectedEventType?.machinery && ( - - - ( - value?.[0] === m.id) || null} - onChange={(_, newValue) => onChange(newValue ? [newValue.id] : [])} - getOptionLabel={(option) => option.label} - renderInput={(params) => } - sx={{ flex: 1 }} - /> - )} - /> - - )} - {selectedEventType?.workPackage && ( - - - ( - value?.[0] === wp.id) || null} - onChange={(_, newValue) => { - if (newValue?.id !== 'loading') { - onChange(newValue ? [newValue.id] : []); - } - }} - getOptionLabel={(option) => option.label} - getOptionDisabled={(option) => option.id === 'loading'} - renderInput={(params) => } - sx={{ flex: 1 }} - /> - )} - /> - - )} - {/* Question Document Link */} - {selectedEventType?.questionDocument && ( - - - ( - - )} - /> - - )} - {/* Documents */} - {selectedEventType?.documents && ( - - - - - Documents - - -
      - {documentFiles.map((docFile, index) => ( -
    • - - - {docFile.name} - - handleDocumentRemove(index)} - sx={{ - padding: '0px', - marginLeft: '2px' + )} + {selectedEventType?.workPackage && ( + + + ( + value?.[0] === wp.id) || null} + onChange={(_, newValue) => { + if (newValue?.id !== 'loading') { + onChange(newValue ? [newValue.id] : []); + } + }} + getOptionLabel={(option) => option.label} + getOptionDisabled={(option) => option.id === 'loading'} + renderInput={(params) => } + sx={{ flex: 1 }} + /> + )} + /> + + )} + {/* Question Document Link */} + {selectedEventType?.questionDocument && ( + + + ( + + )} + /> + + )} + {/* Documents */} + {selectedEventType?.documents && ( + + + + + Documents + + +
        + {documentFiles.map((docFile, index) => ( +
      • + - - - -
      • - ))} -
      -
    • + ))} +
    + + {errors.documentFiles?.message} +
    +
    +
    + )} + {/* Description */} + {selectedEventType?.description && ( + + + ( + - - {errors.documentFiles?.message} - + )} + /> -
    - )} - {/* Description */} - {selectedEventType?.description && ( - - - ( - - )} - /> - - )} -
    - + )} +
    + + ); }; export default EventModal; diff --git a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx index dbce29e4e7..12e84b5a95 100644 --- a/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx +++ b/src/frontend/src/pages/CalendarPage/NewCalendarPage.tsx @@ -475,9 +475,8 @@ const NewCalendarPage: React.FC = ({ cardDate={cardDate} displayMonth={displayMonthYear} events={ - eventDict.get( - datePipe(new Date(cardDate.getTime() + cardDate.getTimezoneOffset() * 60000)) - ) ?? [] + eventDict.get(datePipe(new Date(cardDate.getTime() + cardDate.getTimezoneOffset() * 60000))) ?? + [] } eventTypes={allEventTypes ?? []} calendars={allCalendars ?? []} diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index 304d1687e2..ab9a8569d6 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -479,6 +479,8 @@ const calendarCreateEvent = () => `${calendar()}/event/create`; const calendarEditEvent = (eventId: string) => `${calendar()}/event/${eventId}/edit`; const calendarEditScheduleSlot = (eventId: string, scheduleSlotId: string) => `${calendar()}/event/${eventId}/schedule-slot/${scheduleSlotId}/edit`; +const calendarPreviewScheduleSlotRecurringEdits = (eventId: string, scheduleSlotId: string) => + `${calendar()}/event/${eventId}/schedule-slot/${scheduleSlotId}/preview-recurring-edits`; const calendarUploadDocument = (eventId: string) => `${calendar()}/event/${eventId}/upload-document`; const calendarPDFById = (fileId: string) => `${calendar()}/document/${fileId}`; @@ -823,6 +825,7 @@ export const apiUrls = { calendarDenyEvent, calendarEditEvent, calendarEditScheduleSlot, + calendarPreviewScheduleSlotRecurringEdits, version }; From 70589ba69dec0f8736e887eac118f8ebbf8a64fb Mon Sep 17 00:00:00 2001 From: Chris Pyle Date: Sat, 24 Jan 2026 16:54:12 -0500 Subject: [PATCH 476/477] default date times for events --- .../pages/CalendarPage/CalendarDayCard.tsx | 4 +- .../src/pages/CalendarPage/CalendarTab.tsx | 8 ++-- .../CalendarPage/Components/EventModal.tsx | 38 +++++++++++++++---- .../pages/CalendarPage/NewCalendarPage.tsx | 2 +- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx index b9af5fcbd9..2b56118fda 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarDayCard.tsx @@ -43,7 +43,7 @@ interface CalendarDayCardProps { eventTypes?: EventType[]; calendars?: Calendar[]; dayOfWeek?: DayOfWeek; - onCreateEventClick: () => void; + onCreateEventClick: (date: Date) => void; } const CalendarDayCard: React.FC = ({ @@ -418,7 +418,7 @@ const CalendarDayCard: React.FC = ({ > { - if (isClickable) onCreateEventClick(); + if (isClickable) onCreateEventClick(cardDate); }} sx={{ position: 'absolute', diff --git a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx index 04ebcac277..5ee0ed3a25 100644 --- a/src/frontend/src/pages/CalendarPage/CalendarTab.tsx +++ b/src/frontend/src/pages/CalendarPage/CalendarTab.tsx @@ -18,6 +18,7 @@ import { useHistory } from 'react-router-dom'; const CalendarTab: React.FC = () => { const [tabIndex, setTabIndex] = useState(0); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); + const [createModalDate, setCreateModalDate] = useState(new Date()); const user = useCurrentUser(); const history = useHistory(); const canViewReviews = isHead(user.role) || isLead(user.role); @@ -88,10 +89,11 @@ const CalendarTab: React.FC = () => { if (canViewReviews) tabs.push({ tabUrlValue: 'reviews', tabName: 'Review Bookings' }); - const handleNewEventClick = () => { + const handleNewEventClick = (date?: Date) => { if (tabIndex !== 0) { history.push(`${routes.NEW_CALENDAR}/mainCalendar`); } + setCreateModalDate(date || new Date()); setIsCreateModalOpen(true); }; @@ -115,7 +117,7 @@ const CalendarTab: React.FC = () => { @@ -701,11 +769,12 @@ const NewCalendarPage: React.FC = ({ setOpenFilterModal(false)} - filterValues={{ memberIds, teamIds, showInvited: showInvitedEvents, showTeam: showTeamEvents }} + filterValues={{ memberIds, teamIds, showInvited: showInvitedEvents, showTeam: showTeamEvents, allEventsMode }} setMemberIds={(ids: string[]) => setMemberIds(ids)} setTeamIds={(ids: string[]) => setTeamIds(ids)} setShowInvited={(changed: boolean) => updateAdditionalMemberIds(changed)} setShowTeam={(changed: boolean) => updateAdditionalTeamIds(changed)} + setAllEventsMode={(enabled: boolean) => setAllEventsMode(enabled)} />
    diff --git a/src/frontend/src/pages/CalendarPage/UpcomingMeetingsCard.tsx b/src/frontend/src/pages/CalendarPage/UpcomingMeetingsCard.tsx index bdf0f235c6..ca4896a6dc 100644 --- a/src/frontend/src/pages/CalendarPage/UpcomingMeetingsCard.tsx +++ b/src/frontend/src/pages/CalendarPage/UpcomingMeetingsCard.tsx @@ -3,6 +3,8 @@ import BuildOutlinedIcon from '@mui/icons-material/BuildOutlined'; import RoomOutlinedIcon from '@mui/icons-material/RoomOutlined'; import GroupsOutlinedIcon from '@mui/icons-material/GroupsOutlined'; import { Calendar, EventInstance, EventType } from 'shared'; +import { datePipe } from '../../utils/pipes'; +import { formatTime } from '../../utils/datetime.utils'; interface UpcomingMeetingProp { calendars: Calendar[]; @@ -41,14 +43,21 @@ const UpcomingMeetingsCard: React.FC = ({ event, calendars {/* Event Time */} - {new Date(event.startTime).toLocaleTimeString()} + {datePipe(event.startTime)}
    - {/* Event Location */} - - {event.location ? event.location : event.zoomLink ? event.zoomLink : 'N/A'} - + + {/* Event Location */} + + {event.location ? event.location : event.zoomLink ? event.zoomLink : 'N/A'} + + + {/* Event Time */} + + {formatTime(new Date(event.startTime))} + + {/* Event Members */} diff --git a/src/frontend/src/utils/urls.ts b/src/frontend/src/utils/urls.ts index ab9a8569d6..d3d2af692e 100644 --- a/src/frontend/src/utils/urls.ts +++ b/src/frontend/src/utils/urls.ts @@ -481,6 +481,8 @@ const calendarEditScheduleSlot = (eventId: string, scheduleSlotId: string) => `${calendar()}/event/${eventId}/schedule-slot/${scheduleSlotId}/edit`; const calendarPreviewScheduleSlotRecurringEdits = (eventId: string, scheduleSlotId: string) => `${calendar()}/event/${eventId}/schedule-slot/${scheduleSlotId}/preview-recurring-edits`; +const calendarDeleteScheduleSlot = (eventId: string, scheduleSlotId: string) => + `${calendar()}/event/${eventId}/schedule-slot/${scheduleSlotId}/delete`; const calendarUploadDocument = (eventId: string) => `${calendar()}/event/${eventId}/upload-document`; const calendarPDFById = (fileId: string) => `${calendar()}/document/${fileId}`; @@ -826,6 +828,7 @@ export const apiUrls = { calendarEditEvent, calendarEditScheduleSlot, calendarPreviewScheduleSlotRecurringEdits, + calendarDeleteScheduleSlot, version }; diff --git a/src/shared/src/types/calendar-types.ts b/src/shared/src/types/calendar-types.ts index 6c718f7d03..938a72beff 100644 --- a/src/shared/src/types/calendar-types.ts +++ b/src/shared/src/types/calendar-types.ts @@ -215,7 +215,11 @@ export interface Event { initialDateScheduled?: Date; } -export type EventInstance = Omit & ScheduleSlot; +export type EventInstance = Omit & + ScheduleSlot & { + recurring: boolean; + totalScheduledSlots: number; + }; export type EventPreview = { eventId: string;