From 060af501f25ea416c2cabd98bcfed976fa3bb966 Mon Sep 17 00:00:00 2001 From: Alex Mickelson Date: Mon, 23 Sep 2024 18:47:26 -0600 Subject: [PATCH] removed pages --- nextjs-pages/.env.test | 1 - nextjs-pages/.eslintrc.json | 3 - nextjs-pages/.gitignore | 39 - nextjs-pages/README.md | 40 - nextjs-pages/next.config.mjs | 6 - nextjs-pages/package-lock.json | 7971 ----------------- nextjs-pages/package.json | 37 - nextjs-pages/postcss.config.mjs | 8 - nextjs-pages/public/favicon.ico | Bin 25931 -> 0 bytes nextjs-pages/src/components/Spinner.tsx | 10 - .../contexts/CourseContextProvider.tsx | 21 - .../contexts/DraggingContextProvider.tsx | 120 - .../src/components/contexts/courseContext.ts | 18 - .../components/contexts/draggingContext.tsx | 21 - .../src/components/courses/CourseList.tsx | 17 - .../src/components/courses/CourseSettings.tsx | 8 - .../courses/calendar/CalendarMonth.tsx | 65 - .../courses/calendar/CourseCalendar.tsx | 40 - .../src/components/courses/calendar/Day.tsx | 38 - .../courses/calendar/DayItemsInModule.tsx | 215 - .../courses/calendar/calendarMonthUtils.ts | 76 - .../components/editor/InnerMonacoEditor.tsx | 54 - .../components/editor/MonacoEditor.module.css | 4 - .../src/components/editor/MonacoEditor.tsx | 13 - .../components/modules/ExpandableModule.tsx | 91 - .../src/components/modules/ModuleList.tsx | 14 - .../modules/assignments/AssignmentPreview.tsx | 58 - .../modules/assignments/EditAssignment.tsx | 78 - .../src/components/modules/page/EditPage.tsx | 40 - .../components/modules/page/PagePreview.tsx | 13 - .../src/components/modules/quiz/EditQuiz.tsx | 66 - .../components/modules/quiz/QuizPreview.tsx | 133 - nextjs-pages/src/components/providers.tsx | 24 - .../components/providersQueryClientUtils.ts | 31 - nextjs-pages/src/components/spinner.css | 56 - .../src/components/undefinedToNull.ts | 12 - nextjs-pages/src/hooks/cavnasCouresHooks.ts | 12 - nextjs-pages/src/hooks/hookHydration.ts | 141 - .../src/hooks/localCourse/assignmentHooks.ts | 120 - .../src/hooks/localCourse/localCourseKeys.ts | 70 - .../hooks/localCourse/localCoursesHooks.ts | 91 - .../src/hooks/localCourse/pageHooks.ts | 108 - .../src/hooks/localCourse/quizHooks.ts | 104 - .../canvas/assignments/canvasAssignment.ts | 82 - .../assignments/canvasAssignmentDate.ts | 8 - .../assignments/canvasAssignmentOverride.ts | 13 - .../canvasExternalToolTagAttributes.ts | 5 - .../canvas/assignments/canvasLockInfo.ts | 7 - .../models/canvas/assignments/canvasRubric.ts | 13 - .../assignments/canvasRubricAssociation.ts | 12 - .../assignments/canvasRubricCriteria.ts | 16 - .../assignments/canvasTurnitinSettings.ts | 10 - .../canvas/courses/canvasCalendarLinkModel.ts | 3 - .../canvas/courses/canvasCourseModel.ts | 56 - .../courses/canvasCourseProgressModel.ts | 6 - .../courses/canvasCourseSettingsModel.ts | 16 - .../models/canvas/courses/canvasTermModel.ts | 6 - .../discussions/canvasDiscussionModelTopic.ts | 40 - .../discussions/canvasFileAttachmentModel.ts | 6 - .../canvasEnrollmentTermModel.ts | 16 - .../enrollments/canvasEnrollmentModel.ts | 48 - .../canvas/enrollments/canvasGradeModel.ts | 11 - .../src/models/canvas/modules/canvasModule.ts | 18 - .../canvas/modules/canvasModuleItems.ts | 26 - .../models/canvas/pages/canvasPageModel.ts | 16 - .../models/canvas/quizzes/canvasQuizModel.ts | 44 - .../canvas/quizzes/canvasQuizPermission.ts | 9 - .../submissions/canvasSubmissionModel.ts | 50 - .../models/canvas/users/canvasUserModel.ts | 21 - .../models/canvas/users/userDisplayModel.ts | 9 - nextjs-pages/src/models/local/IModuleItem.ts | 4 - .../assignment/assignmentSubmissionType.ts | 8 - .../local/assignment/localAssignment.ts | 21 - .../local/assignment/localAssignmentGroup.ts | 6 - .../src/models/local/assignment/rubricItem.ts | 10 - .../utils/assignmentMarkdownParser.ts | 146 - .../utils/assignmentMarkdownSerializer.ts | 48 - .../local/assignment/utils/markdownUtils.ts | 10 - nextjs-pages/src/models/local/localCourse.ts | 63 - nextjs-pages/src/models/local/localModules.ts | 75 - .../src/models/local/page/localCoursePage.ts | 33 - .../src/models/local/quiz/localQuiz.ts | 22 - .../models/local/quiz/localQuizQuestion.ts | 18 - .../local/quiz/localQuizQuestionAnswer.ts | 5 - .../local/quiz/utils/quizMarkdownUtils.ts | 142 - .../utils/quizQuestionAnswerMarkdownUtils.ts | 39 - .../quiz/utils/quizQuestionMarkdownUtils.ts | 229 - .../local/tests/assignmentMarkdown.test.ts | 159 - .../models/local/tests/pageMarkdown.test.ts | 18 - .../quizMarkdown/matchingAnswers.test.ts | 134 - .../quizMarkdown/multipleAnswers.test.ts | 126 - .../tests/quizMarkdown/multipleChoice.test.ts | 75 - .../quizDeterministicChecks.test.ts | 198 - .../tests/quizMarkdown/quizMarkdown.test.ts | 256 - .../tests/quizMarkdown/testAnswer.test.ts | 112 - .../models/local/tests/rubricMarkdown.test.ts | 97 - .../src/models/local/tests/timeUtils.test.ts | 50 - nextjs-pages/src/models/local/timeUtils.ts | 93 - nextjs-pages/src/pages/_app.tsx | 14 - nextjs-pages/src/pages/_document.tsx | 13 - nextjs-pages/src/pages/api/hello.ts | 13 - .../src/pages/course/[courseName]/index.tsx | 72 - .../assignment/[assignmentName]/index.tsx | 20 - .../[moduleName]/page/[pageName]/EditPage.tsx | 40 - .../page/[pageName]/PagePreview.tsx | 13 - .../[moduleName]/page/[pageName]/layout.tsx | 5 - .../[moduleName]/page/[pageName]/loading.tsx | 10 - .../[moduleName]/page/[pageName]/page.tsx | 12 - .../[moduleName]/quiz/[quizName]/EditQuiz.tsx | 66 - .../quiz/[quizName]/QuizPreview.tsx | 133 - .../[moduleName]/quiz/[quizName]/layout.tsx | 5 - .../[moduleName]/quiz/[quizName]/loading.tsx | 10 - .../[moduleName]/quiz/[quizName]/page.tsx | 12 - nextjs-pages/src/pages/index.tsx | 31 - .../canvas/canvasAssignmentService.ts | 18 - .../src/services/canvas/canvasService.ts | 125 - .../src/services/canvas/canvasServiceUtils.ts | 58 - .../src/services/canvas/webRequestor.ts | 177 - .../fileStorage/fileStorageService.ts | 226 - .../fileStorage/utils/courseDifferences.ts | 152 - .../fileStorage/utils/courseMarkdownLoader.ts | 177 - .../fileStorage/utils/courseMarkdownSaver.ts | 245 - .../fileStorage/utils/fileSystemUtils.ts | 20 - .../src/services/htmlMarkdownUtils.ts | 10 - .../tests/courseDifferenceChanges.test.ts | 587 -- .../tests/courseDifferencesDeletions.test.ts | 451 - .../src/services/tests/fileStorage.test.ts | 293 - .../src/services/utils/queryClient.tsx | 145 - nextjs-pages/src/styles/globals.css | 60 - nextjs-pages/tailwind.config.ts | 21 - nextjs-pages/tsconfig.json | 21 - nextjs-pages/vitest.config.ts | 17 - 132 files changed, 16123 deletions(-) delete mode 100644 nextjs-pages/.env.test delete mode 100644 nextjs-pages/.eslintrc.json delete mode 100644 nextjs-pages/.gitignore delete mode 100644 nextjs-pages/README.md delete mode 100644 nextjs-pages/next.config.mjs delete mode 100644 nextjs-pages/package-lock.json delete mode 100644 nextjs-pages/package.json delete mode 100644 nextjs-pages/postcss.config.mjs delete mode 100644 nextjs-pages/public/favicon.ico delete mode 100644 nextjs-pages/src/components/Spinner.tsx delete mode 100644 nextjs-pages/src/components/contexts/CourseContextProvider.tsx delete mode 100644 nextjs-pages/src/components/contexts/DraggingContextProvider.tsx delete mode 100644 nextjs-pages/src/components/contexts/courseContext.ts delete mode 100644 nextjs-pages/src/components/contexts/draggingContext.tsx delete mode 100644 nextjs-pages/src/components/courses/CourseList.tsx delete mode 100644 nextjs-pages/src/components/courses/CourseSettings.tsx delete mode 100644 nextjs-pages/src/components/courses/calendar/CalendarMonth.tsx delete mode 100644 nextjs-pages/src/components/courses/calendar/CourseCalendar.tsx delete mode 100644 nextjs-pages/src/components/courses/calendar/Day.tsx delete mode 100644 nextjs-pages/src/components/courses/calendar/DayItemsInModule.tsx delete mode 100644 nextjs-pages/src/components/courses/calendar/calendarMonthUtils.ts delete mode 100644 nextjs-pages/src/components/editor/InnerMonacoEditor.tsx delete mode 100644 nextjs-pages/src/components/editor/MonacoEditor.module.css delete mode 100755 nextjs-pages/src/components/editor/MonacoEditor.tsx delete mode 100644 nextjs-pages/src/components/modules/ExpandableModule.tsx delete mode 100644 nextjs-pages/src/components/modules/ModuleList.tsx delete mode 100644 nextjs-pages/src/components/modules/assignments/AssignmentPreview.tsx delete mode 100644 nextjs-pages/src/components/modules/assignments/EditAssignment.tsx delete mode 100644 nextjs-pages/src/components/modules/page/EditPage.tsx delete mode 100644 nextjs-pages/src/components/modules/page/PagePreview.tsx delete mode 100644 nextjs-pages/src/components/modules/quiz/EditQuiz.tsx delete mode 100644 nextjs-pages/src/components/modules/quiz/QuizPreview.tsx delete mode 100644 nextjs-pages/src/components/providers.tsx delete mode 100644 nextjs-pages/src/components/providersQueryClientUtils.ts delete mode 100644 nextjs-pages/src/components/spinner.css delete mode 100644 nextjs-pages/src/components/undefinedToNull.ts delete mode 100644 nextjs-pages/src/hooks/cavnasCouresHooks.ts delete mode 100644 nextjs-pages/src/hooks/hookHydration.ts delete mode 100644 nextjs-pages/src/hooks/localCourse/assignmentHooks.ts delete mode 100644 nextjs-pages/src/hooks/localCourse/localCourseKeys.ts delete mode 100644 nextjs-pages/src/hooks/localCourse/localCoursesHooks.ts delete mode 100644 nextjs-pages/src/hooks/localCourse/pageHooks.ts delete mode 100644 nextjs-pages/src/hooks/localCourse/quizHooks.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasAssignment.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasAssignmentDate.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasAssignmentOverride.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasExternalToolTagAttributes.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasLockInfo.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasRubric.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasRubricAssociation.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasRubricCriteria.ts delete mode 100644 nextjs-pages/src/models/canvas/assignments/canvasTurnitinSettings.ts delete mode 100644 nextjs-pages/src/models/canvas/courses/canvasCalendarLinkModel.ts delete mode 100644 nextjs-pages/src/models/canvas/courses/canvasCourseModel.ts delete mode 100644 nextjs-pages/src/models/canvas/courses/canvasCourseProgressModel.ts delete mode 100644 nextjs-pages/src/models/canvas/courses/canvasCourseSettingsModel.ts delete mode 100644 nextjs-pages/src/models/canvas/courses/canvasTermModel.ts delete mode 100644 nextjs-pages/src/models/canvas/discussions/canvasDiscussionModelTopic.ts delete mode 100644 nextjs-pages/src/models/canvas/discussions/canvasFileAttachmentModel.ts delete mode 100644 nextjs-pages/src/models/canvas/enrollmentTerms/canvasEnrollmentTermModel.ts delete mode 100644 nextjs-pages/src/models/canvas/enrollments/canvasEnrollmentModel.ts delete mode 100644 nextjs-pages/src/models/canvas/enrollments/canvasGradeModel.ts delete mode 100644 nextjs-pages/src/models/canvas/modules/canvasModule.ts delete mode 100644 nextjs-pages/src/models/canvas/modules/canvasModuleItems.ts delete mode 100644 nextjs-pages/src/models/canvas/pages/canvasPageModel.ts delete mode 100644 nextjs-pages/src/models/canvas/quizzes/canvasQuizModel.ts delete mode 100644 nextjs-pages/src/models/canvas/quizzes/canvasQuizPermission.ts delete mode 100644 nextjs-pages/src/models/canvas/submissions/canvasSubmissionModel.ts delete mode 100644 nextjs-pages/src/models/canvas/users/canvasUserModel.ts delete mode 100644 nextjs-pages/src/models/canvas/users/userDisplayModel.ts delete mode 100644 nextjs-pages/src/models/local/IModuleItem.ts delete mode 100644 nextjs-pages/src/models/local/assignment/assignmentSubmissionType.ts delete mode 100644 nextjs-pages/src/models/local/assignment/localAssignment.ts delete mode 100644 nextjs-pages/src/models/local/assignment/localAssignmentGroup.ts delete mode 100644 nextjs-pages/src/models/local/assignment/rubricItem.ts delete mode 100644 nextjs-pages/src/models/local/assignment/utils/assignmentMarkdownParser.ts delete mode 100644 nextjs-pages/src/models/local/assignment/utils/assignmentMarkdownSerializer.ts delete mode 100644 nextjs-pages/src/models/local/assignment/utils/markdownUtils.ts delete mode 100644 nextjs-pages/src/models/local/localCourse.ts delete mode 100644 nextjs-pages/src/models/local/localModules.ts delete mode 100644 nextjs-pages/src/models/local/page/localCoursePage.ts delete mode 100644 nextjs-pages/src/models/local/quiz/localQuiz.ts delete mode 100644 nextjs-pages/src/models/local/quiz/localQuizQuestion.ts delete mode 100644 nextjs-pages/src/models/local/quiz/localQuizQuestionAnswer.ts delete mode 100644 nextjs-pages/src/models/local/quiz/utils/quizMarkdownUtils.ts delete mode 100644 nextjs-pages/src/models/local/quiz/utils/quizQuestionAnswerMarkdownUtils.ts delete mode 100644 nextjs-pages/src/models/local/quiz/utils/quizQuestionMarkdownUtils.ts delete mode 100644 nextjs-pages/src/models/local/tests/assignmentMarkdown.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/pageMarkdown.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/quizMarkdown/matchingAnswers.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/quizMarkdown/multipleAnswers.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/quizMarkdown/multipleChoice.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/quizMarkdown/quizDeterministicChecks.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/quizMarkdown/quizMarkdown.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/quizMarkdown/testAnswer.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/rubricMarkdown.test.ts delete mode 100644 nextjs-pages/src/models/local/tests/timeUtils.test.ts delete mode 100644 nextjs-pages/src/models/local/timeUtils.ts delete mode 100644 nextjs-pages/src/pages/_app.tsx delete mode 100644 nextjs-pages/src/pages/_document.tsx delete mode 100644 nextjs-pages/src/pages/api/hello.ts delete mode 100644 nextjs-pages/src/pages/course/[courseName]/index.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/index.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/EditPage.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/PagePreview.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/layout.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/loading.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/page.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/EditQuiz.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/QuizPreview.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/layout.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/loading.tsx delete mode 100644 nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/page.tsx delete mode 100644 nextjs-pages/src/pages/index.tsx delete mode 100644 nextjs-pages/src/services/canvas/canvasAssignmentService.ts delete mode 100644 nextjs-pages/src/services/canvas/canvasService.ts delete mode 100644 nextjs-pages/src/services/canvas/canvasServiceUtils.ts delete mode 100644 nextjs-pages/src/services/canvas/webRequestor.ts delete mode 100644 nextjs-pages/src/services/fileStorage/fileStorageService.ts delete mode 100644 nextjs-pages/src/services/fileStorage/utils/courseDifferences.ts delete mode 100644 nextjs-pages/src/services/fileStorage/utils/courseMarkdownLoader.ts delete mode 100644 nextjs-pages/src/services/fileStorage/utils/courseMarkdownSaver.ts delete mode 100644 nextjs-pages/src/services/fileStorage/utils/fileSystemUtils.ts delete mode 100644 nextjs-pages/src/services/htmlMarkdownUtils.ts delete mode 100644 nextjs-pages/src/services/tests/courseDifferenceChanges.test.ts delete mode 100644 nextjs-pages/src/services/tests/courseDifferencesDeletions.test.ts delete mode 100644 nextjs-pages/src/services/tests/fileStorage.test.ts delete mode 100644 nextjs-pages/src/services/utils/queryClient.tsx delete mode 100644 nextjs-pages/src/styles/globals.css delete mode 100644 nextjs-pages/tailwind.config.ts delete mode 100644 nextjs-pages/tsconfig.json delete mode 100644 nextjs-pages/vitest.config.ts diff --git a/nextjs-pages/.env.test b/nextjs-pages/.env.test deleted file mode 100644 index 72a67cb..0000000 --- a/nextjs-pages/.env.test +++ /dev/null @@ -1 +0,0 @@ -STORAGE_DIRECTORY="./temp/canvasManagerStorage" \ No newline at end of file diff --git a/nextjs-pages/.eslintrc.json b/nextjs-pages/.eslintrc.json deleted file mode 100644 index 3722418..0000000 --- a/nextjs-pages/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["next/core-web-vitals", "next/typescript"] -} diff --git a/nextjs-pages/.gitignore b/nextjs-pages/.gitignore deleted file mode 100644 index 6259ca6..0000000 --- a/nextjs-pages/.gitignore +++ /dev/null @@ -1,39 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - - -storage/* \ No newline at end of file diff --git a/nextjs-pages/README.md b/nextjs-pages/README.md deleted file mode 100644 index a75ac52..0000000 --- a/nextjs-pages/README.md +++ /dev/null @@ -1,40 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. - -[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. - -The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/nextjs-pages/next.config.mjs b/nextjs-pages/next.config.mjs deleted file mode 100644 index d5456a1..0000000 --- a/nextjs-pages/next.config.mjs +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, -}; - -export default nextConfig; diff --git a/nextjs-pages/package-lock.json b/nextjs-pages/package-lock.json deleted file mode 100644 index 8720222..0000000 --- a/nextjs-pages/package-lock.json +++ /dev/null @@ -1,7971 +0,0 @@ -{ - "name": "canvas-manager", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "canvas-manager", - "version": "0.1.0", - "dependencies": { - "@monaco-editor/react": "^4.6.0", - "@tanstack/react-query": "^5.54.1", - "axios": "^1.7.5", - "isomorphic-dompurify": "^2.15.0", - "marked": "^14.1.0", - "next": "14.2.8", - "react": "^18", - "react-dom": "^18", - "react-error-boundary": "^4.0.13", - "react-hot-toast": "^2.4.1", - "yaml": "^2.5.0" - }, - "devDependencies": { - "@tanstack/react-query-devtools": "^5.54.1", - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "@vitejs/plugin-react": "^4.3.1", - "eslint": "^8", - "eslint-config-next": "14.2.8", - "postcss": "^8", - "tailwindcss": "^3.4.1", - "typescript": "^5", - "vitest": "^2.0.5" - } - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", - "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.6", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", - "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.6" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", - "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", - "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", - "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@monaco-editor/loader": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", - "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", - "license": "MIT", - "dependencies": { - "state-local": "^1.0.6" - }, - "peerDependencies": { - "monaco-editor": ">= 0.21.0 < 1" - } - }, - "node_modules/@monaco-editor/react": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", - "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", - "license": "MIT", - "dependencies": { - "@monaco-editor/loader": "^1.4.0" - }, - "peerDependencies": { - "monaco-editor": ">= 0.25.0 < 1", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@next/env": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.8.tgz", - "integrity": "sha512-L44a+ynqkolyNBnYfF8VoCiSrjSZWgEHYKkKLGcs/a80qh7AkfVUD/MduVPgdsWZ31tgROR+yJRA0PZjSVBXWQ==", - "license": "MIT" - }, - "node_modules/@next/eslint-plugin-next": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.8.tgz", - "integrity": "sha512-ue5vcq9Fjk3asACRDrzYjcGMEN7pMMDQ5zUD+FenkqvlPCVUD1x7PxBNOLfPYDZOrk/Vnl4GHmjj2mZDqPW8TQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "10.3.10" - } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.8.tgz", - "integrity": "sha512-1VrQlG8OzdyvvGZhGJFnaNE2P10Jjy/2FopnqbY0nSa/gr8If3iINxvOEW3cmVeoAYkmW0RsBazQecA2dBFOSw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.8.tgz", - "integrity": "sha512-87t3I86rNRSOJB1gXIUzaQWWSWrkWPDyZGsR0Z7JAPtLeX3uUOW2fHxl7dNWD2BZvbvftctTQjgtfpp7nMtmWg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.8.tgz", - "integrity": "sha512-ta2sfVzbOpTbgBrF9HM5m+U58dv6QPuwU4n5EX4LLyCJGKc433Z0D9h9gay/HSOjLEXJ2fJYrMP5JYYbHdxhtw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.8.tgz", - "integrity": "sha512-+IoLTPK6Z5uIgDhgeWnQF5/o5GBN7+zyUNrs4Bes1W3g9++YELb8y0unFybS8s87ntAKMDl6jeQ+mD7oNwp/Ng==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.8.tgz", - "integrity": "sha512-pO+hVXC+mvzUOQJJRG4RX4wJsRJ5BkURSf6dD6EjUXAX4Ml9es1WsEfkaZ4lcpmFzFvY47IkDaffks/GdCn9ag==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.8.tgz", - "integrity": "sha512-bCat9izctychCtf3uL1nqHq31N5e1VxvdyNcBQflkudPMLbxVnlrw45Vi87K+lt1CwrtVayHqzo4ie0Szcpwzg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.8.tgz", - "integrity": "sha512-gbxfUaSPV7EyUobpavida2Hwi62GhSJaSg7iBjmBWoxkxlmETOD7U4tWt763cGIsyE6jM7IoNavq0BXqwdW2QA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.8.tgz", - "integrity": "sha512-PUXzEzjTTlUh3b5VAn1nlpwvujTnuCMMwbiCnaTazoVlN1nA3kWjlmp42IfURA2N/nyrlVEw7pURa/o4Qxj1cw==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.8.tgz", - "integrity": "sha512-EnPKv0ttq02E9/1KZ/8Dn7kuutv6hy1CKc0HlNcvzOQcm4/SQtvfws5gY0zrG9tuupd3HfC2L/zcTrnBhpjTuQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz", - "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz", - "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz", - "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz", - "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz", - "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz", - "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz", - "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz", - "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz", - "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz", - "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz", - "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz", - "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz", - "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz", - "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz", - "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", - "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", - "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "license": "Apache-2.0" - }, - "node_modules/@swc/helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", - "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "tslib": "^2.4.0" - } - }, - "node_modules/@tanstack/query-core": { - "version": "5.54.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.54.1.tgz", - "integrity": "sha512-hKS+WRpT5zBFip21pB6Jx1C0hranWQrbv5EJ7qPoiV5MYI3C8rTCqWC9DdBseiPT1JgQWh8Y55YthuYZNiw3Xw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/query-devtools": { - "version": "5.54.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.54.0.tgz", - "integrity": "sha512-B8Sa6mh7/4m2fyk2/YnUXeOZ1/us7G/C/i1It8YcCbieXc8vf1AdSYjR+mZIoJeKOKLqA741hZqfj8d4F1NCVg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/react-query": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.55.0.tgz", - "integrity": "sha512-2uYuxEbRQD8TORUiTUacEOwt1e8aoSqUOJFGY5TUrh6rQ3U85zrMS2wvbNhBhXGh6Vj69QDCP2yv8tIY7joo6Q==", - "license": "MIT", - "dependencies": { - "@tanstack/query-core": "5.54.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^18 || ^19" - } - }, - "node_modules/@tanstack/react-query-devtools": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.55.0.tgz", - "integrity": "sha512-omUloSS7Ru+LNmXeK56ygtAgMXMR5M74v8kn4lRjMkjT/aTJHWGI2yJh0I1EE1a8tjwXyviqy+qWfJaeqQcTIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tanstack/query-devtools": "5.54.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "@tanstack/react-query": "^5.55.0", - "react": "^18 || ^19" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/dompurify": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", - "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", - "license": "MIT", - "dependencies": { - "@types/trusted-types": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.16.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", - "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz", - "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz", - "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/type-utils": "7.2.0", - "@typescript-eslint/utils": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", - "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz", - "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/utils": "7.2.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", - "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.2.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@vitejs/plugin-react": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", - "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.24.5", - "@babel/plugin-transform-react-jsx-self": "^7.24.5", - "@babel/plugin-transform-react-jsx-source": "^7.24.1", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.14.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0" - } - }, - "node_modules/@vitest/expect": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", - "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", - "chai": "^5.1.1", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/pretty-format": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", - "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz", - "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "2.0.5", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz", - "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "2.0.5", - "magic-string": "^0.30.10", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", - "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", - "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "2.0.5", - "estree-walker": "^3.0.3", - "loupe": "^3.1.1", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlast": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", - "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", - "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "es-errors": "^1.3.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz", - "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==", - "dev": true, - "license": "MPL-2.0", - "engines": { - "node": ">=4" - } - }, - "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001658", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001658.tgz", - "integrity": "sha512-N2YVqWbJELVdrnsW5p+apoQyYt51aBMSsBZki1XZEfeBCexcM/sf4xiAHcXQBkuOwJBXtWF7aW1sYX6tKebPHw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chai": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", - "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssstyle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", - "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", - "license": "MIT", - "dependencies": { - "rrweb-cssom": "^0.6.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/cssstyle/node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "license": "MIT" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "license": "MIT" - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, - "license": "MIT" - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dompurify": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", - "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==", - "license": "(MPL-2.0 OR Apache-2.0)" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.17", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.17.tgz", - "integrity": "sha512-Q6Q+04tjC2KJ8qsSOSgovvhWcv5t+SmpH6/YfAWmhpE5/r+zw6KQy1/yWVFFNyEBvy68twTTXr2d5eLfCq7QIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dev": true, - "license": "MIT", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-iterator-helpers": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", - "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3", - "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" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@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" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-next": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.8.tgz", - "integrity": "sha512-gRqxHkSuCrQro6xqXnmXphcq8rdiw7FI+nLXpWmIlp/AfUzHCgXNQE7mOK+oco+SRaJbhqCg/68uRln1qjkF+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@next/eslint-plugin-next": "14.2.8", - "@rushstack/eslint-patch": "^1.3.3", - "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-jsx-a11y": "^6.7.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" - }, - "peerDependencies": { - "eslint": "^7.23.0 || ^8.0.0", - "typescript": ">=3.3.1" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz", - "integrity": "sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.3.5", - "enhanced-resolve": "^5.15.0", - "eslint-module-utils": "^2.8.1", - "fast-glob": "^3.3.2", - "get-tsconfig": "^4.7.5", - "is-bun-module": "^1.0.2", - "is-glob": "^4.0.3" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz", - "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", - "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "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.9.0", - "hasown": "^2.0.2", - "is-core-module": "^2.15.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.0", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", - "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "aria-query": "~5.1.3", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "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.19", - "hasown": "^2.0.2", - "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.0" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.35.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz", - "integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.8", - "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", - "array.prototype.tosorted": "^1.1.4", - "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.19", - "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.8", - "object.fromentries": "^2.0.8", - "object.values": "^1.2.0", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.5", - "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11", - "string.prototype.repeat": "^1.0.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz", - "integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/goober": { - "version": "2.1.14", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", - "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", - "license": "MIT", - "peerDependencies": { - "csstype": "^3.0.10" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bun-module": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.1.0.tgz", - "integrity": "sha512-4mTAVPlrXpaN3jtF0lsnPCMGnq4+qZjVIKq0HCpfcqf8OC1SM5oATCIAPM5V5FN05qp2NNnFndphmdZS9CV3hA==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.6.3" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "license": "MIT" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/isomorphic-dompurify": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.15.0.tgz", - "integrity": "sha512-RDHlyeVmwEDAPZuX1VaaBzSn9RrsfvswxH7faEQK9cTHC1dXeNuK6ElUeSr7locFyeLguut8ASfhQWxHB4Ttug==", - "license": "MIT", - "dependencies": { - "@types/dompurify": "^3.0.5", - "dompurify": "^3.1.6", - "jsdom": "^25.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", - "dev": true, - "license": "MIT", - "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" - } - }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz", - "integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==", - "license": "MIT", - "dependencies": { - "cssstyle": "^4.0.1", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.12", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.4", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^2.11.2" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", - "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "object.assign": "^4.1.4", - "object.values": "^1.1.6" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dev": true, - "license": "MIT", - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/marked": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-14.1.1.tgz", - "integrity": "sha512-eS59oxof5eBVDCKTs+mJbvB/6Vq137GbimF9wkTIlto2/B2ppY5nigUUQgKVmA3bI2mPTIshUyDj5j612ZxlQQ==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/monaco-editor": { - "version": "0.51.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.51.0.tgz", - "integrity": "sha512-xaGwVV1fq343cM7aOYB6lVE4Ugf0UyimdD/x5PWcWBMKENwectaEu77FAN7c5sFiyumqeJdX1RPTh1ocioyDjw==", - "license": "MIT", - "peer": true - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/next": { - "version": "14.2.8", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.8.tgz", - "integrity": "sha512-EyEyJZ89r8C5FPlS/401AiF3O8jeMtHIE+bLom9MwcdWJJFBgRl+MR/2VgO0v5bI6tQORNY0a0DR5sjpFNrjbg==", - "license": "MIT", - "dependencies": { - "@next/env": "14.2.8", - "@swc/helpers": "0.5.5", - "busboy": "1.6.0", - "caniuse-lite": "^1.0.30001579", - "graceful-fs": "^4.2.11", - "postcss": "8.4.31", - "styled-jsx": "5.1.1" - }, - "bin": { - "next": "dist/bin/next" - }, - "engines": { - "node": ">=18.17.0" - }, - "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.8", - "@next/swc-darwin-x64": "14.2.8", - "@next/swc-linux-arm64-gnu": "14.2.8", - "@next/swc-linux-arm64-musl": "14.2.8", - "@next/swc-linux-x64-gnu": "14.2.8", - "@next/swc-linux-x64-musl": "14.2.8", - "@next/swc-win32-arm64-msvc": "14.2.8", - "@next/swc-win32-ia32-msvc": "14.2.8", - "@next/swc-win32-x64-msvc": "14.2.8" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "@playwright/test": "^1.41.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@playwright/test": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nwsapi": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", - "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", - "license": "MIT" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "license": "MIT", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.4.45", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", - "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "license": "MIT" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-error-boundary": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.13.tgz", - "integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "peerDependencies": { - "react": ">=16.13.1" - } - }, - "node_modules/react-hot-toast": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", - "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==", - "license": "MIT", - "dependencies": { - "goober": "^2.1.10" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=16", - "react-dom": ">=16" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", - "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.1", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "license": "MIT" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz", - "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.2", - "@rollup/rollup-android-arm64": "4.21.2", - "@rollup/rollup-darwin-arm64": "4.21.2", - "@rollup/rollup-darwin-x64": "4.21.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", - "@rollup/rollup-linux-arm-musleabihf": "4.21.2", - "@rollup/rollup-linux-arm64-gnu": "4.21.2", - "@rollup/rollup-linux-arm64-musl": "4.21.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", - "@rollup/rollup-linux-riscv64-gnu": "4.21.2", - "@rollup/rollup-linux-s390x-gnu": "4.21.2", - "@rollup/rollup-linux-x64-gnu": "4.21.2", - "@rollup/rollup-linux-x64-musl": "4.21.2", - "@rollup/rollup-win32-arm64-msvc": "4.21.2", - "@rollup/rollup-win32-ia32-msvc": "4.21.2", - "@rollup/rollup-win32-x64-msvc": "4.21.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/rrweb-cssom": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", - "license": "MIT" - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/state-local": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", - "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", - "license": "MIT" - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/string.prototype.includes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", - "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", - "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "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", - "set-function-name": "^2.0.2", - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.repeat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", - "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/styled-jsx": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", - "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", - "license": "MIT", - "dependencies": { - "client-only": "0.0.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "license": "MIT" - }, - "node_modules/tailwindcss": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz", - "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinypool": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", - "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", - "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT" - }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz", - "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz", - "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.5", - "pathe": "^1.1.2", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vitest": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz", - "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.5", - "@vitest/pretty-format": "^2.0.5", - "@vitest/runner": "2.0.5", - "@vitest/snapshot": "2.0.5", - "@vitest/spy": "2.0.5", - "@vitest/utils": "2.0.5", - "chai": "^5.1.1", - "debug": "^4.3.5", - "execa": "^8.0.1", - "magic-string": "^0.30.10", - "pathe": "^1.1.2", - "std-env": "^3.7.0", - "tinybench": "^2.8.0", - "tinypool": "^1.0.0", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.0.5", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.0.5", - "@vitest/ui": "2.0.5", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "license": "MIT", - "dependencies": { - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", - "license": "MIT", - "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "license": "MIT", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", - "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", - "dev": true, - "license": "MIT", - "dependencies": { - "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-generator-function": "^1.0.10", - "is-regex": "^1.1.4", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "license": "Apache-2.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "license": "MIT" - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/nextjs-pages/package.json b/nextjs-pages/package.json deleted file mode 100644 index 43eb53b..0000000 --- a/nextjs-pages/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "canvas-manager", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@monaco-editor/react": "^4.6.0", - "@tanstack/react-query": "^5.54.1", - "axios": "^1.7.5", - "isomorphic-dompurify": "^2.15.0", - "marked": "^14.1.0", - "react": "^18", - "react-dom": "^18", - "next": "14.2.8", - "react-error-boundary": "^4.0.13", - "react-hot-toast": "^2.4.1", - "yaml": "^2.5.0" - }, - "devDependencies": { - "@tanstack/react-query-devtools": "^5.54.1", - "typescript": "^5", - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "@vitejs/plugin-react": "^4.3.1", - "postcss": "^8", - "tailwindcss": "^3.4.1", - "eslint": "^8", - "eslint-config-next": "14.2.8", - "vitest": "^2.0.5" - } -} diff --git a/nextjs-pages/postcss.config.mjs b/nextjs-pages/postcss.config.mjs deleted file mode 100644 index 1a69fd2..0000000 --- a/nextjs-pages/postcss.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -/** @type {import('postcss-load-config').Config} */ -const config = { - plugins: { - tailwindcss: {}, - }, -}; - -export default config; diff --git a/nextjs-pages/public/favicon.ico b/nextjs-pages/public/favicon.ico deleted file mode 100644 index 718d6fea4835ec2d246af9800eddb7ffb276240c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25931 zcmeHv30#a{`}aL_*G&7qml|y<+KVaDM2m#dVr!KsA!#An?kSQM(q<_dDNCpjEux83 zLb9Z^XxbDl(w>%i@8hT6>)&Gu{h#Oeyszu?xtw#Zb1mO{pgX9699l+Qppw7jXaYf~-84xW z)w4x8?=youko|}Vr~(D$UXIbiXABHh`p1?nn8Po~fxRJv}|0e(BPs|G`(TT%kKVJAdg5*Z|x0leQq0 zkdUBvb#>9F()jo|T~kx@OM8$9wzs~t2l;K=woNssA3l6|sx2r3+kdfVW@e^8e*E}v zA1y5{bRi+3Z`uD3{F7LgFJDdvm;nJilkzDku>BwXH(8ItVCXk*-lSJnR?-2UN%hJ){&rlvg`CDTj z)Bzo!3v7Ou#83zEDEFcKt(f1E0~=rqeEbTnMvWR#{+9pg%7G8y>u1OVRUSoox-ovF z2Ydma(;=YuBY(eI|04{hXzZD6_f(v~H;C~y5=DhAC{MMS>2fm~1H_t2$56pc$NH8( z5bH|<)71dV-_oCHIrzrT`2s-5w_+2CM0$95I6X8p^r!gHp+j_gd;9O<1~CEQQGS8) zS9Qh3#p&JM-G8rHekNmKVewU;pJRcTAog68KYo^dRo}(M>36U4Us zfgYWSiHZL3;lpWT=zNAW>Dh#mB!_@Lg%$ms8N-;aPqMn+C2HqZgz&9~Eu z4|Kp<`$q)Uw1R?y(~S>ePdonHxpV1#eSP1B;Ogo+-Pk}6#0GsZZ5!||ev2MGdh}_m z{DeR7?0-1^zVs&`AV6Vt;r3`I`OI_wgs*w=eO%_#7Kepl{B@xiyCANc(l zzIyd4y|c6PXWq9-|KM8(zIk8LPk(>a)zyFWjhT!$HJ$qX1vo@d25W<fvZQ2zUz5WRc(UnFMKHwe1| zWmlB1qdbiA(C0jmnV<}GfbKtmcu^2*P^O?MBLZKt|As~ge8&AAO~2K@zbXelK|4T<{|y4`raF{=72kC2Kn(L4YyenWgrPiv z@^mr$t{#X5VuIMeL!7Ab6_kG$&#&5p*Z{+?5U|TZ`B!7llpVmp@skYz&n^8QfPJzL z0G6K_OJM9x+Wu2gfN45phANGt{7=C>i34CV{Xqlx(fWpeAoj^N0Biu`w+MVcCUyU* zDZuzO0>4Z6fbu^T_arWW5n!E45vX8N=bxTVeFoep_G#VmNlQzAI_KTIc{6>c+04vr zx@W}zE5JNSU>!THJ{J=cqjz+4{L4A{Ob9$ZJ*S1?Ggg3klFp!+Y1@K+pK1DqI|_gq z5ZDXVpge8-cs!o|;K73#YXZ3AShj50wBvuq3NTOZ`M&qtjj#GOFfgExjg8Gn8>Vq5 z`85n+9|!iLCZF5$HJ$Iu($dm?8~-ofu}tEc+-pyke=3!im#6pk_Wo8IA|fJwD&~~F zc16osQ)EBo58U7XDuMexaPRjU@h8tXe%S{fA0NH3vGJFhuyyO!Uyl2^&EOpX{9As0 zWj+P>{@}jxH)8|r;2HdupP!vie{sJ28b&bo!8`D^x}TE$%zXNb^X1p@0PJ86`dZyj z%ce7*{^oo+6%&~I!8hQy-vQ7E)0t0ybH4l%KltWOo~8cO`T=157JqL(oq_rC%ea&4 z2NcTJe-HgFjNg-gZ$6!Y`SMHrlj}Etf7?r!zQTPPSv}{so2e>Fjs1{gzk~LGeesX%r(Lh6rbhSo_n)@@G-FTQy93;l#E)hgP@d_SGvyCp0~o(Y;Ee8{ zdVUDbHm5`2taPUOY^MAGOw*>=s7=Gst=D+p+2yON!0%Hk` zz5mAhyT4lS*T3LS^WSxUy86q&GnoHxzQ6vm8)VS}_zuqG?+3td68_x;etQAdu@sc6 zQJ&5|4(I?~3d-QOAODHpZ=hlSg(lBZ!JZWCtHHSj`0Wh93-Uk)_S%zsJ~aD>{`A0~ z9{AG(e|q3g5B%wYKRxiL2Y$8(4w6bzchKuloQW#e&S3n+P- z8!ds-%f;TJ1>)v)##>gd{PdS2Oc3VaR`fr=`O8QIO(6(N!A?pr5C#6fc~Ge@N%Vvu zaoAX2&(a6eWy_q&UwOhU)|P3J0Qc%OdhzW=F4D|pt0E4osw;%<%Dn58hAWD^XnZD= z>9~H(3bmLtxpF?a7su6J7M*x1By7YSUbxGi)Ot0P77`}P3{)&5Un{KD?`-e?r21!4vTTnN(4Y6Lin?UkSM z`MXCTC1@4A4~mvz%Rh2&EwY))LeoT=*`tMoqcEXI>TZU9WTP#l?uFv+@Dn~b(>xh2 z;>B?;Tz2SR&KVb>vGiBSB`@U7VIWFSo=LDSb9F{GF^DbmWAfpms8Sx9OX4CnBJca3 zlj9(x!dIjN?OG1X4l*imJNvRCk}F%!?SOfiOq5y^mZW)jFL@a|r-@d#f7 z2gmU8L3IZq0ynIws=}~m^#@&C%J6QFo~Mo4V`>v7MI-_!EBMMtb%_M&kvAaN)@ZVw z+`toz&WG#HkWDjnZE!6nk{e-oFdL^$YnbOCN}JC&{$#$O27@|Tn-skXr)2ml2~O!5 zX+gYoxhoc7qoU?C^3~&!U?kRFtnSEecWuH0B0OvLodgUAi}8p1 zrO6RSXHH}DMc$&|?D004DiOVMHV8kXCP@7NKB zgaZq^^O<7PoKEp72kby@W0Z!Y*Ay{&vfg#C&gG@YVR9g?FEocMUi1gSN$+V+ayF45{a zuDZDTN}mS|;BO%gEf}pjBfN2-gIrU#G5~cucA;dokXW89%>AyXJJI z9X4UlIWA|ZYHgbI z5?oFk@A=Ik7lrEQPDH!H+b`7_Y~aDb_qa=B2^Y&Ow41cU=4WDd40dp5(QS-WMN-=Y z9g;6_-JdNU;|6cPwf$ak*aJIcwL@1n$#l~zi{c{EW?T;DaW*E8DYq?Umtz{nJ&w-M zEMyTDrC&9K$d|kZe2#ws6)L=7K+{ zQw{XnV6UC$6-rW0emqm8wJoeZK)wJIcV?dST}Z;G0Arq{dVDu0&4kd%N!3F1*;*pW zR&qUiFzK=@44#QGw7k1`3t_d8&*kBV->O##t|tonFc2YWrL7_eqg+=+k;!F-`^b8> z#KWCE8%u4k@EprxqiV$VmmtiWxDLgnGu$Vs<8rppV5EajBXL4nyyZM$SWVm!wnCj-B!Wjqj5-5dNXukI2$$|Bu3Lrw}z65Lc=1G z^-#WuQOj$hwNGG?*CM_TO8Bg-1+qc>J7k5c51U8g?ZU5n?HYor;~JIjoWH-G>AoUP ztrWWLbRNqIjW#RT*WqZgPJXU7C)VaW5}MiijYbABmzoru6EmQ*N8cVK7a3|aOB#O& zBl8JY2WKfmj;h#Q!pN%9o@VNLv{OUL?rixHwOZuvX7{IJ{(EdPpuVFoQqIOa7giLVkBOKL@^smUA!tZ1CKRK}#SSM)iQHk)*R~?M!qkCruaS!#oIL1c z?J;U~&FfH#*98^G?i}pA{ z9Jg36t4=%6mhY(quYq*vSxptes9qy|7xSlH?G=S@>u>Ebe;|LVhs~@+06N<4CViBk zUiY$thvX;>Tby6z9Y1edAMQaiH zm^r3v#$Q#2T=X>bsY#D%s!bhs^M9PMAcHbCc0FMHV{u-dwlL;a1eJ63v5U*?Q_8JO zT#50!RD619#j_Uf))0ooADz~*9&lN!bBDRUgE>Vud-i5ck%vT=r^yD*^?Mp@Q^v+V zG#-?gKlr}Eeqifb{|So?HM&g91P8|av8hQoCmQXkd?7wIJwb z_^v8bbg`SAn{I*4bH$u(RZ6*xUhuA~hc=8czK8SHEKTzSxgbwi~9(OqJB&gwb^l4+m`k*Q;_?>Y-APi1{k zAHQ)P)G)f|AyjSgcCFps)Fh6Bca*Xznq36!pV6Az&m{O8$wGFD? zY&O*3*J0;_EqM#jh6^gMQKpXV?#1?>$ml1xvh8nSN>-?H=V;nJIwB07YX$e6vLxH( zqYwQ>qxwR(i4f)DLd)-$P>T-no_c!LsN@)8`e;W@)-Hj0>nJ-}Kla4-ZdPJzI&Mce zv)V_j;(3ERN3_@I$N<^|4Lf`B;8n+bX@bHbcZTopEmDI*Jfl)-pFDvo6svPRoo@(x z);_{lY<;);XzT`dBFpRmGrr}z5u1=pC^S-{ce6iXQlLGcItwJ^mZx{m$&DA_oEZ)B{_bYPq-HA zcH8WGoBG(aBU_j)vEy+_71T34@4dmSg!|M8Vf92Zj6WH7Q7t#OHQqWgFE3ARt+%!T z?oLovLVlnf?2c7pTc)~cc^($_8nyKwsN`RA-23ed3sdj(ys%pjjM+9JrctL;dy8a( z@en&CQmnV(()bu|Y%G1-4a(6x{aLytn$T-;(&{QIJB9vMox11U-1HpD@d(QkaJdEb zG{)+6Dos_L+O3NpWo^=gR?evp|CqEG?L&Ut#D*KLaRFOgOEK(Kq1@!EGcTfo+%A&I z=dLbB+d$u{sh?u)xP{PF8L%;YPPW53+@{>5W=Jt#wQpN;0_HYdw1{ksf_XhO4#2F= zyPx6Lx2<92L-;L5PD`zn6zwIH`Jk($?Qw({erA$^bC;q33hv!d!>%wRhj# zal^hk+WGNg;rJtb-EB(?czvOM=H7dl=vblBwAv>}%1@{}mnpUznfq1cE^sgsL0*4I zJ##!*B?=vI_OEVis5o+_IwMIRrpQyT_Sq~ZU%oY7c5JMIADzpD!Upz9h@iWg_>>~j zOLS;wp^i$-E?4<_cp?RiS%Rd?i;f*mOz=~(&3lo<=@(nR!_Rqiprh@weZlL!t#NCc zO!QTcInq|%#>OVgobj{~ixEUec`E25zJ~*DofsQdzIa@5^nOXj2T;8O`l--(QyU^$t?TGY^7#&FQ+2SS3B#qK*k3`ye?8jUYSajE5iBbJls75CCc(m3dk{t?- zopcER9{Z?TC)mk~gpi^kbbu>b-+a{m#8-y2^p$ka4n60w;Sc2}HMf<8JUvhCL0B&Btk)T`ctE$*qNW8L$`7!r^9T+>=<=2qaq-;ll2{`{Rg zc5a0ZUI$oG&j-qVOuKa=*v4aY#IsoM+1|c4Z)<}lEDvy;5huB@1RJPquU2U*U-;gu z=En2m+qjBzR#DEJDO`WU)hdd{Vj%^0V*KoyZ|5lzV87&g_j~NCjwv0uQVqXOb*QrQ zy|Qn`hxx(58c70$E;L(X0uZZ72M1!6oeg)(cdKO ze0gDaTz+ohR-#d)NbAH4x{I(21yjwvBQfmpLu$)|m{XolbgF!pmsqJ#D}(ylp6uC> z{bqtcI#hT#HW=wl7>p!38sKsJ`r8}lt-q%Keqy%u(xk=yiIJiUw6|5IvkS+#?JTBl z8H5(Q?l#wzazujH!8o>1xtn8#_w+397*_cy8!pQGP%K(Ga3pAjsaTbbXJlQF_+m+-UpUUent@xM zg%jqLUExj~o^vQ3Gl*>wh=_gOr2*|U64_iXb+-111aH}$TjeajM+I20xw(((>fej-@CIz4S1pi$(#}P7`4({6QS2CaQS4NPENDp>sAqD z$bH4KGzXGffkJ7R>V>)>tC)uax{UsN*dbeNC*v}#8Y#OWYwL4t$ePR?VTyIs!wea+ z5Urmc)X|^`MG~*dS6pGSbU+gPJoq*^a=_>$n4|P^w$sMBBy@f*Z^Jg6?n5?oId6f{ z$LW4M|4m502z0t7g<#Bx%X;9<=)smFolV&(V^(7Cv2-sxbxopQ!)*#ZRhTBpx1)Fc zNm1T%bONzv6@#|dz(w02AH8OXe>kQ#1FMCzO}2J_mST)+ExmBr9cva-@?;wnmWMOk z{3_~EX_xadgJGv&H@zK_8{(x84`}+c?oSBX*Ge3VdfTt&F}yCpFP?CpW+BE^cWY0^ zb&uBN!Ja3UzYHK-CTyA5=L zEMW{l3Usky#ly=7px648W31UNV@K)&Ub&zP1c7%)`{);I4b0Q<)B}3;NMG2JH=X$U zfIW4)4n9ZM`-yRj67I)YSLDK)qfUJ_ij}a#aZN~9EXrh8eZY2&=uY%2N0UFF7<~%M zsB8=erOWZ>Ct_#^tHZ|*q`H;A)5;ycw*IcmVxi8_0Xk}aJA^ath+E;xg!x+As(M#0=)3!NJR6H&9+zd#iP(m0PIW8$ z1Y^VX`>jm`W!=WpF*{ioM?C9`yOR>@0q=u7o>BP-eSHqCgMDj!2anwH?s%i2p+Q7D zzszIf5XJpE)IG4;d_(La-xenmF(tgAxK`Y4sQ}BSJEPs6N_U2vI{8=0C_F?@7<(G; zo$~G=8p+076G;`}>{MQ>t>7cm=zGtfbdDXm6||jUU|?X?CaE?(<6bKDYKeHlz}DA8 zXT={X=yp_R;HfJ9h%?eWvQ!dRgz&Su*JfNt!Wu>|XfU&68iRikRrHRW|ZxzRR^`eIGt zIeiDgVS>IeExKVRWW8-=A=yA`}`)ZkWBrZD`hpWIxBGkh&f#ijr449~m`j6{4jiJ*C!oVA8ZC?$1RM#K(_b zL9TW)kN*Y4%^-qPpMP7d4)o?Nk#>aoYHT(*g)qmRUb?**F@pnNiy6Fv9rEiUqD(^O zzyS?nBrX63BTRYduaG(0VVG2yJRe%o&rVrLjbxTaAFTd8s;<<@Qs>u(<193R8>}2_ zuwp{7;H2a*X7_jryzriZXMg?bTuegABb^87@SsKkr2)0Gyiax8KQWstw^v#ix45EVrcEhr>!NMhprl$InQMzjSFH54x5k9qHc`@9uKQzvL4ihcq{^B zPrVR=o_ic%Y>6&rMN)hTZsI7I<3&`#(nl+3y3ys9A~&^=4?PL&nd8)`OfG#n zwAMN$1&>K++c{^|7<4P=2y(B{jJsQ0a#U;HTo4ZmWZYvI{+s;Td{Yzem%0*k#)vjpB zia;J&>}ICate44SFYY3vEelqStQWFihx%^vQ@Do(sOy7yR2@WNv7Y9I^yL=nZr3mb zXKV5t@=?-Sk|b{XMhA7ZGB@2hqsx}4xwCW!in#C zI@}scZlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7 zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S zb+9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2`1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc- zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I zgg{b=Iz}WkhCGj1M=hu4#Aw173YxIVbISaoc z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S(O(a0e7oY=E( zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef LrJugUA?W`A8`#=m diff --git a/nextjs-pages/src/components/Spinner.tsx b/nextjs-pages/src/components/Spinner.tsx deleted file mode 100644 index b40fa5e..0000000 --- a/nextjs-pages/src/components/Spinner.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from "react"; -import "./spinner.css" - -export const Spinner = () => { - return ( -
- -
- ); -}; diff --git a/nextjs-pages/src/components/contexts/CourseContextProvider.tsx b/nextjs-pages/src/components/contexts/CourseContextProvider.tsx deleted file mode 100644 index 9386943..0000000 --- a/nextjs-pages/src/components/contexts/CourseContextProvider.tsx +++ /dev/null @@ -1,21 +0,0 @@ -"use client" -import { ReactNode } from "react"; -import { CourseContext } from "./courseContext"; - -export default function CourseContextProvider({ - localCourseName, - children, -}: { - children: ReactNode; - localCourseName: string; -}) { - return ( - - {children} - - ); -} diff --git a/nextjs-pages/src/components/contexts/DraggingContextProvider.tsx b/nextjs-pages/src/components/contexts/DraggingContextProvider.tsx deleted file mode 100644 index 2caeb8c..0000000 --- a/nextjs-pages/src/components/contexts/DraggingContextProvider.tsx +++ /dev/null @@ -1,120 +0,0 @@ -"use client"; -import { ReactNode, useCallback, DragEvent } from "react"; -import { DraggingContext } from "./draggingContext"; -import { useUpdateQuizMutation } from "@/hooks/localCourse/quizHooks"; -import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; -import { LocalQuiz } from "@/models/local/quiz/localQuiz"; -import { - getDateFromStringOrThrow, - dateToMarkdownString, -} from "@/models/local/timeUtils"; -import { LocalAssignment } from "@/models/local/assignment/localAssignment"; -import { useUpdateAssignmentMutation } from "@/hooks/localCourse/assignmentHooks"; -import { useUpdatePageMutation } from "@/hooks/localCourse/pageHooks"; -import { LocalCoursePage } from "@/models/local/page/localCoursePage"; - -export default function DraggingContextProvider({ - children, -}: { - children: ReactNode; -}) { - const updateQuizMutation = useUpdateQuizMutation(); - const updateAssignmentMutation = useUpdateAssignmentMutation(); - const updatePageMutation = useUpdatePageMutation(); - const { data: settings } = useLocalCourseSettingsQuery(); - - const itemDrop = useCallback( - (e: DragEvent, day: string | undefined) => { - const itemBeingDragged = JSON.parse( - e.dataTransfer.getData("draggableItem") - ); - - if (itemBeingDragged && day) { - const dayAsDate = getDateFromStringOrThrow(day, "in drop callback"); - dayAsDate.setHours(settings.defaultDueTime.hour); - dayAsDate.setMinutes(settings.defaultDueTime.minute); - dayAsDate.setSeconds(0); - - console.log("dropped on day", dayAsDate, day); - if (itemBeingDragged.type === "quiz") { - console.log("dropping quiz"); - const previousQuiz = itemBeingDragged.item as LocalQuiz; - - const quiz: LocalQuiz = { - ...previousQuiz, - dueAt: dateToMarkdownString(dayAsDate), - lockAt: getLaterDate(previousQuiz.lockAt, dayAsDate), - }; - updateQuizMutation.mutate({ - quiz: quiz, - quizName: quiz.name, - moduleName: itemBeingDragged.sourceModuleName, - }); - } else if (itemBeingDragged.type === "assignment") { - updateAssignment(dayAsDate); - } else if (itemBeingDragged.type === "page") { - console.log("dropped page"); - const previousPage = itemBeingDragged.item as LocalCoursePage; - const page: LocalCoursePage = { - ...previousPage, - dueAt: dateToMarkdownString(dayAsDate), - }; - updatePageMutation.mutate({ - page, - moduleName: itemBeingDragged.sourceModuleName, - pageName: page.name, - }); - } - } - - function updateAssignment(dayAsDate: Date) { - const previousAssignment = itemBeingDragged.item as LocalAssignment; - const assignment: LocalAssignment = { - ...previousAssignment, - dueAt: dateToMarkdownString(dayAsDate), - lockAt: - previousAssignment.lockAt && - (getDateFromStringOrThrow( - previousAssignment.lockAt, - "lockAt date" - ) > dayAsDate - ? previousAssignment.lockAt - : dateToMarkdownString(dayAsDate)), - }; - updateAssignmentMutation.mutate({ - assignment, - moduleName: itemBeingDragged.sourceModuleName, - assignmentName: assignment.name, - }); - } - }, - [ - settings.defaultDueTime.hour, - settings.defaultDueTime.minute, - updateAssignmentMutation, - updatePageMutation, - updateQuizMutation, - ] - ); - - return ( - - {children} - - ); -} -function getLaterDate( - firstDate: string | undefined, - dayAsDate: Date -): string | undefined { - return ( - firstDate && - (getDateFromStringOrThrow(firstDate, "lockAt date") > dayAsDate - ? firstDate - : dateToMarkdownString(dayAsDate)) - ); -} diff --git a/nextjs-pages/src/components/contexts/courseContext.ts b/nextjs-pages/src/components/contexts/courseContext.ts deleted file mode 100644 index 9cdd222..0000000 --- a/nextjs-pages/src/components/contexts/courseContext.ts +++ /dev/null @@ -1,18 +0,0 @@ -"use client"; -import { createContext, useContext } from "react"; - -export interface CourseContextInterface { - courseName: string; -} - -const defaultValue: CourseContextInterface = { - courseName: "", -}; - -export const CourseContext = - createContext(defaultValue); - -export function useCourseContext() { - return useContext(CourseContext); -} - diff --git a/nextjs-pages/src/components/contexts/draggingContext.tsx b/nextjs-pages/src/components/contexts/draggingContext.tsx deleted file mode 100644 index bd42bfb..0000000 --- a/nextjs-pages/src/components/contexts/draggingContext.tsx +++ /dev/null @@ -1,21 +0,0 @@ -"use client"; -import { IModuleItem } from "@/models/local/IModuleItem"; -import { createContext, useContext, DragEvent } from "react"; - -export interface DraggableItem { - item: IModuleItem; - sourceModuleName: string; - type: "quiz" | "assignment" | "page"; -} - -export interface DraggingContextInterface { - itemDrop: (e: DragEvent,droppedOnDay?: string) => void; -} -const defaultDraggingValue: DraggingContextInterface = { - itemDrop: () => { }, -}; -export const DraggingContext = createContext(defaultDraggingValue); - -export function useDraggingContext() { - return useContext(DraggingContext); -} diff --git a/nextjs-pages/src/components/courses/CourseList.tsx b/nextjs-pages/src/components/courses/CourseList.tsx deleted file mode 100644 index 4da794f..0000000 --- a/nextjs-pages/src/components/courses/CourseList.tsx +++ /dev/null @@ -1,17 +0,0 @@ -"use client"; -import { useLocalCourseNamesQuery } from "@/hooks/localCourse/localCoursesHooks"; -import Link from "next/link"; - -export default function CourseList() { - const { data: courses } = useLocalCourseNamesQuery(); - console.log(courses); - return ( -
- {courses.map((c) => ( - - {c}{" "} - - ))} -
- ); -} diff --git a/nextjs-pages/src/components/courses/CourseSettings.tsx b/nextjs-pages/src/components/courses/CourseSettings.tsx deleted file mode 100644 index 6407da9..0000000 --- a/nextjs-pages/src/components/courses/CourseSettings.tsx +++ /dev/null @@ -1,8 +0,0 @@ -"use client"; - -import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; - -export default function CourseSettings() { - const { data: settings } = useLocalCourseSettingsQuery(); - return
{settings.name}
; -} diff --git a/nextjs-pages/src/components/courses/calendar/CalendarMonth.tsx b/nextjs-pages/src/components/courses/calendar/CalendarMonth.tsx deleted file mode 100644 index 6397f5b..0000000 --- a/nextjs-pages/src/components/courses/calendar/CalendarMonth.tsx +++ /dev/null @@ -1,65 +0,0 @@ -"use client"; -import { useState } from "react"; -import { CalendarMonthModel } from "./calendarMonthUtils"; -import { DayOfWeek } from "@/models/local/localCourse"; -import Day from "./Day"; - -export const CalendarMonth = ({ month }: { month: CalendarMonthModel }) => { - const [isCollapsed, setIsCollapsed] = useState(false); - - const isInPast = - new Date(month.year, month.month - 1, 1) < new Date(Date.now()); - const monthName = new Date(month.year, month.month - 1, 1).toLocaleString( - "default", - { month: "long" } - ); - const toggleCollapse = () => setIsCollapsed(!isCollapsed); - // const collapseClass = isInPast ? "collapse _hide" : "collapse _show"; - const weekDaysList: DayOfWeek[] = Object.values(DayOfWeek); - - return ( - <> -

- {/* */} -

- -
-
- {weekDaysList.map((day) => ( -
- {day} -
- ))} -
- - {month.daysByWeek.map((week, weekIndex) => ( - - ))} -
- - ); -}; - -function CalendarWeek({ - week, - monthNumber, -}: { - week: string[]; //date strings - monthNumber: number; -}) { - return ( -
- {week.map((day, dayIndex) => ( - - ))} -
- ); -} diff --git a/nextjs-pages/src/components/courses/calendar/CourseCalendar.tsx b/nextjs-pages/src/components/courses/calendar/CourseCalendar.tsx deleted file mode 100644 index c8d8d15..0000000 --- a/nextjs-pages/src/components/courses/calendar/CourseCalendar.tsx +++ /dev/null @@ -1,40 +0,0 @@ -"use client"; -import { getDateFromStringOrThrow } from "@/models/local/timeUtils"; -import { getMonthsBetweenDates } from "./calendarMonthUtils"; -import { CalendarMonth } from "./CalendarMonth"; -import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks"; -import { useMemo } from "react"; - -export default function CourseCalendar() { - const { data: settings } = useLocalCourseSettingsQuery(); - - const startDateTime = useMemo( - () => getDateFromStringOrThrow(settings.startDate, "course start date"), - [settings.startDate] - ); - const endDateTime = useMemo( - () => getDateFromStringOrThrow(settings.endDate, "course end date"), - [settings.endDate] - ); - const months = useMemo( - () => getMonthsBetweenDates(startDateTime, endDateTime), - [endDateTime, startDateTime] - ); - - return ( -
- {months.map((month) => ( - - ))} -
- ); -} diff --git a/nextjs-pages/src/components/courses/calendar/Day.tsx b/nextjs-pages/src/components/courses/calendar/Day.tsx deleted file mode 100644 index eb0bc37..0000000 --- a/nextjs-pages/src/components/courses/calendar/Day.tsx +++ /dev/null @@ -1,38 +0,0 @@ -"use client"; -import { useModuleNamesQuery } from "@/hooks/localCourse/localCoursesHooks"; -import DayItemsInModule from "./DayItemsInModule"; -import { getDateFromStringOrThrow } from "@/models/local/timeUtils"; -import { useDraggingContext } from "@/components/contexts/draggingContext"; - -export default function Day({ day, month }: { day: string; month: number }) { - const { data: moduleNames } = useModuleNamesQuery(); - - const dayAsDate = getDateFromStringOrThrow( - day, - "calculating same month in day" - ); - const isInSameMonth = dayAsDate.getMonth() + 1 != month; - const backgroundClass = isInSameMonth ? "" : "bg-slate-900"; - const { itemDrop } = useDraggingContext(); - - return ( -
{ - itemDrop(e, day); - }} - onDragOver={(e) => e.preventDefault()} - > - {dayAsDate.getDate()} - {moduleNames.map((moduleName) => ( - - ))} -
- ); -} diff --git a/nextjs-pages/src/components/courses/calendar/DayItemsInModule.tsx b/nextjs-pages/src/components/courses/calendar/DayItemsInModule.tsx deleted file mode 100644 index 1e772b9..0000000 --- a/nextjs-pages/src/components/courses/calendar/DayItemsInModule.tsx +++ /dev/null @@ -1,215 +0,0 @@ -"use client"; -import React, { useMemo } from "react"; -import { getDateFromStringOrThrow } from "@/models/local/timeUtils"; -import Link from "next/link"; -import { - usePageNamesQuery, - usePagesQueries, -} from "@/hooks/localCourse/pageHooks"; -import { - useQuizNamesQuery, - useQuizzesQueries, -} from "@/hooks/localCourse/quizHooks"; -import { - useAssignmentNamesQuery, - useAssignmentsQueries, -} from "@/hooks/localCourse/assignmentHooks"; -import { useCourseContext } from "@/components/contexts/courseContext"; - -export default function DayItemsInModule({ - day, - moduleName, -}: { - day: string; - moduleName: string; -}) { - return ( -
    - - - -
- ); -} - -function Pages({ moduleName, day }: { moduleName: string; day: string }) { - const { courseName } = useCourseContext(); - const { data: pageNames } = usePageNamesQuery(moduleName); - const { data: pages } = usePagesQueries(moduleName, pageNames); - const todaysPages = useMemo( - () => - pages.filter((p) => { - const dueDate = getDateFromStringOrThrow( - p.dueAt, - "due at for page in day" - ); - const dayAsDate = getDateFromStringOrThrow( - day, - "in pages in DayItemsInModule" - ); - return ( - dueDate.getFullYear() === dayAsDate.getFullYear() && - dueDate.getMonth() === dayAsDate.getMonth() && - dueDate.getDate() === dayAsDate.getDate() - ); - }), - [day, pages] - ); - return ( - <> - {todaysPages.map((p) => ( -
  • { - e.dataTransfer.setData( - "draggableItem", - JSON.stringify({ - type: "page", - item: p, - sourceModuleName: moduleName, - }) - ); - }} - > - - {p.name} - -
  • - ))} - - ); -} - -function Quizzes({ moduleName, day }: { moduleName: string; day: string }) { - const { data: quizNames } = useQuizNamesQuery(moduleName); - const { data: quizzes } = useQuizzesQueries(moduleName, quizNames); - const { courseName } = useCourseContext(); - - const todaysQuizzes = useMemo( - () => - quizzes.filter((q) => { - const dueDate = getDateFromStringOrThrow( - q.dueAt, - "due at for quiz in day" - ); - const dayAsDate = getDateFromStringOrThrow( - day, - "in quizzes in DayItemsInModule" - ); - return ( - dueDate.getFullYear() === dayAsDate.getFullYear() && - dueDate.getMonth() === dayAsDate.getMonth() && - dueDate.getDate() === dayAsDate.getDate() - ); - }), - [day, quizzes] - ); - return ( - <> - {todaysQuizzes.map((q) => ( -
  • { - e.dataTransfer.setData( - "draggableItem", - JSON.stringify({ - type: "quiz", - item: q, - sourceModuleName: moduleName, - }) - ); - }} - onDragEnd={(e) => e.preventDefault()} - > - - {q.name} - -
  • - ))} - - ); -} - -function Assignments({ moduleName, day }: { moduleName: string; day: string }) { - const { data: assignmentNames } = useAssignmentNamesQuery(moduleName); - const { courseName } = useCourseContext(); - const { data: assignments } = useAssignmentsQueries( - moduleName, - assignmentNames - ); - const todaysAssignments = useMemo( - () => - assignments.filter((a) => { - const dueDate = getDateFromStringOrThrow( - a.dueAt, - "due at for assignment in day" - ); - const dayAsDate = getDateFromStringOrThrow( - day, - "in assignment in DayItemsInModule" - ); - return ( - dueDate.getFullYear() === dayAsDate.getFullYear() && - dueDate.getMonth() === dayAsDate.getMonth() && - dueDate.getDate() === dayAsDate.getDate() - ); - }), - [assignments, day] - ); - return ( - <> - {todaysAssignments.map((a) => ( -
  • { - e.dataTransfer.setData( - "draggableItem", - JSON.stringify({ - type: "assignment", - item: a, - sourceModuleName: moduleName, - }) - ); - }} - > - - {a.name} - -
  • - ))} - - ); -} diff --git a/nextjs-pages/src/components/courses/calendar/calendarMonthUtils.ts b/nextjs-pages/src/components/courses/calendar/calendarMonthUtils.ts deleted file mode 100644 index eb4f9c8..0000000 --- a/nextjs-pages/src/components/courses/calendar/calendarMonthUtils.ts +++ /dev/null @@ -1,76 +0,0 @@ -"use client"; - -import { - dateToMarkdownString, - getDateFromStringOrThrow, -} from "@/models/local/timeUtils"; - -export interface CalendarMonthModel { - year: number; - month: number; - weeks: number[][]; - daysByWeek: string[][]; //iso date is memo-izable -} - -function weeksInMonth(year: number, month: number): number { - const firstDayOfMonth = new Date(year, month - 1, 1).getDay(); - const daysInMonth = new Date(year, month, 0).getDate(); - const longDaysInMonth = daysInMonth + firstDayOfMonth; - let weeks = Math.floor(longDaysInMonth / 7); - if (longDaysInMonth % 7 > 0) { - weeks += 1; - } - return weeks; -} - -function createCalendarMonth(year: number, month: number): CalendarMonthModel { - const weeksNumber = weeksInMonth(year, month); - const daysInMonth = new Date(year, month, 0).getDate(); - - let currentDay = 1; - const firstDayOfMonth = new Date(year, month - 1, 1).getDay(); - - const daysByWeek = Array.from({ length: weeksNumber }).map((_, weekIndex) => - Array.from({ length: 7 }).map((_, dayIndex) => { - if (weekIndex === 0 && dayIndex < firstDayOfMonth) { - return dateToMarkdownString( - new Date(year, month - 1, dayIndex - firstDayOfMonth + 1, 12, 0, 0) - ); - } else if (currentDay <= daysInMonth) { - return dateToMarkdownString(new Date(year, month - 1, currentDay++, 12, 0, 0)); - } else { - currentDay++; - return dateToMarkdownString( - new Date(year, month, currentDay - daysInMonth - 1, 12, 0, 0) - ); - } - }) - ); - - const weeks = daysByWeek.map((week) => - week.map((day) => - getDateFromStringOrThrow(day, "calculating weeks").getDate() - ) - ); - - return { year, month, weeks, daysByWeek }; -} - -export function getMonthsBetweenDates( - startDate: Date, - endDate: Date -): CalendarMonthModel[] { - const monthsInTerm = - 1 + - (endDate.getFullYear() - startDate.getFullYear()) * 12 + - endDate.getMonth() - - startDate.getMonth(); - - return Array.from({ length: monthsInTerm }, (_, monthDiff) => { - const month = ((startDate.getMonth() + monthDiff) % 12) + 1; - const year = - startDate.getFullYear() + - Math.floor((startDate.getMonth() + monthDiff) / 12); - return createCalendarMonth(year, month); - }); -} diff --git a/nextjs-pages/src/components/editor/InnerMonacoEditor.tsx b/nextjs-pages/src/components/editor/InnerMonacoEditor.tsx deleted file mode 100644 index c926140..0000000 --- a/nextjs-pages/src/components/editor/InnerMonacoEditor.tsx +++ /dev/null @@ -1,54 +0,0 @@ -"use client"; -import React, { useRef, useEffect } from "react"; -import loader from "@monaco-editor/loader"; -import { editor } from "monaco-editor/esm/vs/editor/editor.api"; - -export default function InnerMonacoEditor({ - value, - onChange, -}: { - value: string; - onChange: (value: string) => void; // must be memoized -}) { - const editorRef = useRef(null); - const divRef = useRef(null); - - useEffect(() => { - if (divRef.current && !editorRef.current) { - loader.init().then((monaco) => { - if (divRef.current && !editorRef.current) { - const properties: editor.IStandaloneEditorConstructionOptions = { - value: value, - language: "markdown", - tabSize: 2, - theme: "vs-dark", - minimap: { - enabled: false, - }, - lineNumbers: "off", - wordWrap: "on", - automaticLayout: true, - fontFamily: "Roboto-mono", - fontSize: 16, - padding: { - top: 10, - }, - }; - - editorRef.current = monaco.editor.create(divRef.current, properties); - editorRef.current.onDidChangeModelContent((e) => { - onChange(editorRef.current?.getModel()?.getValue() ?? ""); - }); - } - }); - } - }, [onChange, value]); - - return ( -
    - ); -} diff --git a/nextjs-pages/src/components/editor/MonacoEditor.module.css b/nextjs-pages/src/components/editor/MonacoEditor.module.css deleted file mode 100644 index bc41e26..0000000 --- a/nextjs-pages/src/components/editor/MonacoEditor.module.css +++ /dev/null @@ -1,4 +0,0 @@ -.Editor { - width: 100vw; - height: 100vh; -} \ No newline at end of file diff --git a/nextjs-pages/src/components/editor/MonacoEditor.tsx b/nextjs-pages/src/components/editor/MonacoEditor.tsx deleted file mode 100755 index a9ef3cc..0000000 --- a/nextjs-pages/src/components/editor/MonacoEditor.tsx +++ /dev/null @@ -1,13 +0,0 @@ -"use client"; -import dynamic from "next/dynamic"; - -const InnerMonacoEditor = dynamic(() => import("./InnerMonacoEditor"), { - ssr: false, -}); - -export const MonacoEditor: React.FC<{ - value: string; - onChange: (value: string) => void; -}> = ({ value, onChange }) => { - return ; -}; diff --git a/nextjs-pages/src/components/modules/ExpandableModule.tsx b/nextjs-pages/src/components/modules/ExpandableModule.tsx deleted file mode 100644 index b0222eb..0000000 --- a/nextjs-pages/src/components/modules/ExpandableModule.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { - useAssignmentNamesQuery, - useAssignmentsQueries, -} from "@/hooks/localCourse/assignmentHooks"; -import { - usePageNamesQuery, - usePagesQueries, -} from "@/hooks/localCourse/pageHooks"; -import { - useQuizNamesQuery, - useQuizzesQueries, -} from "@/hooks/localCourse/quizHooks"; -import { IModuleItem } from "@/models/local/IModuleItem"; -import { getDateFromStringOrThrow } from "@/models/local/timeUtils"; -import { useState } from "react"; - -export default function ExpandableModule({ - moduleName, -}: { - moduleName: string; -}) { - const { data: assignmentNames } = useAssignmentNamesQuery(moduleName); - const { data: quizNames } = useQuizNamesQuery(moduleName); - const { data: pageNames } = usePageNamesQuery(moduleName); - - const { data: assignments } = useAssignmentsQueries( - moduleName, - assignmentNames - ); - const { data: quizzes } = useQuizzesQueries(moduleName, quizNames); - const { data: pages } = usePagesQueries(moduleName, pageNames); - - const [expanded, setExpanded] = useState(false); - - const moduleItems: { - type: "assignment" | "quiz" | "page"; - item: IModuleItem; - }[] = assignments - .map( - ( - a - ): { - type: "assignment" | "quiz" | "page"; - item: IModuleItem; - } => ({ - type: "assignment", - item: a, - }) - ) - .concat(quizzes.map((q) => ({ type: "quiz", item: q }))) - .concat(pages.map((p) => ({ type: "page", item: p }))) - .sort( - (a, b) => - getDateFromStringOrThrow( - a.item.dueAt, - "item due date in expandable module" - ).getTime() - - getDateFromStringOrThrow( - b.item.dueAt, - "item due date in expandable module" - ).getTime() - ); - - return ( -
    -
    setExpanded((e) => !e)} - > - {moduleName} -
    -
    -
    - {moduleItems.map(({ type, item }) => ( -
    {item.name}
    - ))} -
    -
    - ); -} diff --git a/nextjs-pages/src/components/modules/ModuleList.tsx b/nextjs-pages/src/components/modules/ModuleList.tsx deleted file mode 100644 index ab389a8..0000000 --- a/nextjs-pages/src/components/modules/ModuleList.tsx +++ /dev/null @@ -1,14 +0,0 @@ -"use client"; -import { useModuleNamesQuery } from "@/hooks/localCourse/localCoursesHooks"; -import ExpandableModule from "./ExpandableModule"; - -export default function ModuleList() { - const { data: moduleNames } = useModuleNamesQuery(); - return ( -
    - {moduleNames.map((m) => ( - - ))} -
    - ); -} diff --git a/nextjs-pages/src/components/modules/assignments/AssignmentPreview.tsx b/nextjs-pages/src/components/modules/assignments/AssignmentPreview.tsx deleted file mode 100644 index eea7fe5..0000000 --- a/nextjs-pages/src/components/modules/assignments/AssignmentPreview.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { LocalAssignment } from "@/models/local/assignment/localAssignment"; -import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils"; -import React from "react"; - -export default function AssignmentPreview({ - assignment, -}: { - assignment: LocalAssignment; -}) { - return ( -
    -
    -
    -
    Due Date
    -
    {assignment.dueAt}
    -
    -
    -
    Lock Date
    -
    {assignment.lockAt}
    -
    -
    -
    Assignment Group Name
    -
    {assignment.localAssignmentGroupName}
    -
    -
    -
    Submission Types
    -
    -
      - {assignment.submissionTypes.map((t) => ( -
    • {t}
    • - ))} -
    -
    -
    -
    -
    File Upload Types
    -
    -
      - {assignment.allowedFileUploadExtensions.map((t) => ( -
    • {t}
    • - ))} -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - ); -} diff --git a/nextjs-pages/src/components/modules/assignments/EditAssignment.tsx b/nextjs-pages/src/components/modules/assignments/EditAssignment.tsx deleted file mode 100644 index 05cb016..0000000 --- a/nextjs-pages/src/components/modules/assignments/EditAssignment.tsx +++ /dev/null @@ -1,78 +0,0 @@ -"use client"; -import { MonacoEditor } from "@/components/editor/MonacoEditor"; -import { - useAssignmentQuery, - useUpdateAssignmentMutation, -} from "@/hooks/localCourse/assignmentHooks"; -import { localAssignmentMarkdown } from "@/models/local/assignment/localAssignment"; -import { useEffect, useState } from "react"; -import AssignmentPreview from "./AssignmentPreview"; - -export default function EditAssignment({ - moduleName, - assignmentName, -}: { - assignmentName: string; - moduleName: string; -}) { - const { data: assignment } = useAssignmentQuery(moduleName, assignmentName); - const updateAssignment = useUpdateAssignmentMutation(); - - const [assignmentText, setAssignmentText] = useState( - localAssignmentMarkdown.toMarkdown(assignment) - ); - console.log(assignmentText); - const [error, setError] = useState(""); - - useEffect(() => { - const delay = 500; - const handler = setTimeout(() => { - const updatedAssignment = - localAssignmentMarkdown.parseMarkdown(assignmentText); - if ( - localAssignmentMarkdown.toMarkdown(assignment) !== - localAssignmentMarkdown.toMarkdown(updatedAssignment) - ) { - console.log("updating assignment"); - try { - updateAssignment.mutate({ - assignment: updatedAssignment, - moduleName, - assignmentName, - }); - } catch (e: any) { - setError(e.toString()); - } - } - }, delay); - - return () => { - clearTimeout(handler); - }; - }, [ - assignment, - assignmentName, - assignmentText, - moduleName, - updateAssignment, - ]); - - return ( -
    -
    -
    - -
    -
    -
    {error && error}
    - -
    -
    -
    - -
    -
    - ); -} diff --git a/nextjs-pages/src/components/modules/page/EditPage.tsx b/nextjs-pages/src/components/modules/page/EditPage.tsx deleted file mode 100644 index 136b9a1..0000000 --- a/nextjs-pages/src/components/modules/page/EditPage.tsx +++ /dev/null @@ -1,40 +0,0 @@ -"use client"; - -import { MonacoEditor } from "@/components/editor/MonacoEditor"; -import { usePageQuery } from "@/hooks/localCourse/pageHooks"; -import { localPageMarkdownUtils } from "@/models/local/page/localCoursePage"; -import { useState } from "react"; -import PagePreview from "./PagePreview"; - -export default function EditPage({ - moduleName, - pageName, -}: { - pageName: string; - moduleName: string; -}) { - const { data: page } = usePageQuery(moduleName, pageName); - const [pageText, setPageText] = useState( - localPageMarkdownUtils.toMarkdown(page) - ); - const [error, setError] = useState(""); - - return ( -
    -
    -
    - -
    -
    -
    {error && error}
    - -
    -
    -
    - -
    -
    - ); -} diff --git a/nextjs-pages/src/components/modules/page/PagePreview.tsx b/nextjs-pages/src/components/modules/page/PagePreview.tsx deleted file mode 100644 index 8f06b50..0000000 --- a/nextjs-pages/src/components/modules/page/PagePreview.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { LocalCoursePage } from "@/models/local/page/localCoursePage"; -import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils"; -import React from "react"; - -export default function PagePreview({ page }: { page: LocalCoursePage }) { - return ( -
    - ); -} diff --git a/nextjs-pages/src/components/modules/quiz/EditQuiz.tsx b/nextjs-pages/src/components/modules/quiz/EditQuiz.tsx deleted file mode 100644 index 3bbc3d6..0000000 --- a/nextjs-pages/src/components/modules/quiz/EditQuiz.tsx +++ /dev/null @@ -1,66 +0,0 @@ -"use client"; -import { MonacoEditor } from "@/components/editor/MonacoEditor"; -import { - useQuizQuery, - useUpdateQuizMutation, -} from "@/hooks/localCourse/quizHooks"; -import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; -import { useEffect, useState } from "react"; -import QuizPreview from "./QuizPreview"; - -export default function EditQuiz({ - moduleName, - quizName, -}: { - quizName: string; - moduleName: string; -}) { - const { data: quiz } = useQuizQuery(moduleName, quizName); - const updateQuizMutation = useUpdateQuizMutation(); - const [quizText, setQuizText] = useState(quizMarkdownUtils.toMarkdown(quiz)); - const [error, setError] = useState(""); - - useEffect(() => { - const delay = 500; - const handler = setTimeout(() => { - if ( - quizMarkdownUtils.toMarkdown(quiz) !== - quizMarkdownUtils.toMarkdown(quizMarkdownUtils.parseMarkdown(quizText)) - ) { - try { - const updatedQuiz = quizMarkdownUtils.parseMarkdown(quizText); - updateQuizMutation.mutate({ - quiz: updatedQuiz, - moduleName, - quizName, - }); - } catch (e: any) { - setError(e.toString()); - } - } - }, delay); - - return () => { - clearTimeout(handler); - }; - }, [moduleName, quiz, quizName, quizText, updateQuizMutation]); - - return ( -
    -
    -
    - -
    -
    -
    {error && error}
    - -
    -
    -
    - -
    -
    - ); -} diff --git a/nextjs-pages/src/components/modules/quiz/QuizPreview.tsx b/nextjs-pages/src/components/modules/quiz/QuizPreview.tsx deleted file mode 100644 index d398ac3..0000000 --- a/nextjs-pages/src/components/modules/quiz/QuizPreview.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import { LocalQuiz } from "@/models/local/quiz/localQuiz"; -import { - LocalQuizQuestion, - QuestionType, -} from "@/models/local/quiz/localQuizQuestion"; -import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; -import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils"; - -export default function QuizPreview({ quiz }: { quiz: LocalQuiz }) { - return ( -
    -
    -
    Name
    -
    {quiz.name}
    -
    -
    -
    Due Date
    -
    {quiz.dueAt}
    -
    -
    -
    Lock At
    -
    {quiz.lockAt}
    -
    -
    -
    Shuffle Answers
    -
    {quiz.shuffleAnswers}
    -
    -
    -
    Allowed Attempts
    -
    {quiz.allowedAttempts}
    -
    -
    -
    One Question at a Time
    -
    {quiz.oneQuestionAtATime}
    -
    -
    -
    Assignment Group Name
    -
    {quiz.localAssignmentGroupName}
    -
    -
    - {quiz.description} -
    -
    - {quiz.questions.map((question, i) => ( - - ))} -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - ); -} - -function QuizQuestionPreview({ question }: { question: LocalQuizQuestion }) { - return ( -
    -
    Points: {question.points}
    -
    Type: {question.questionType}
    -
    - {question.questionType === QuestionType.MATCHING && ( -
    - {question.answers.map((answer) => ( -
    -
    {answer.text} -
    -
    {answer.matchedText}
    -
    - ))} - {question.matchDistractors.map((distractor) => ( -
    - DISTRACTOR: {distractor} -
    - ))} -
    - )} - {question.questionType !== QuestionType.MATCHING && ( -
    - {question.answers.map((answer) => ( -
    - {answer.correct ? ( - - - - ) : ( -
    - {question.questionType === QuestionType.MULTIPLE_ANSWERS && ( - [ ] - )} -
    - )} -
    -
    - ))} -
    - )} -
    - ); -} diff --git a/nextjs-pages/src/components/providers.tsx b/nextjs-pages/src/components/providers.tsx deleted file mode 100644 index 01f17c9..0000000 --- a/nextjs-pages/src/components/providers.tsx +++ /dev/null @@ -1,24 +0,0 @@ -"use client"; -import { - QueryClientProvider, -} from "@tanstack/react-query"; -import { ReactNode } from "react"; -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; -import { getQueryClient } from "./providersQueryClientUtils"; - - -export default function Providers({ children }: { children: ReactNode }) { - // NOTE: Avoid useState when initializing the query client if you don't - // have a suspense boundary between this and the code that may - // suspend because React will throw away the client on the initial - // render if it suspends and there is no boundary - - const queryClient = getQueryClient(); - - return ( - - - {children} - - ); -} diff --git a/nextjs-pages/src/components/providersQueryClientUtils.ts b/nextjs-pages/src/components/providersQueryClientUtils.ts deleted file mode 100644 index f141e37..0000000 --- a/nextjs-pages/src/components/providersQueryClientUtils.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { isServer, QueryClient } from "@tanstack/react-query"; - -export function makeQueryClient() { - return new QueryClient({ - defaultOptions: { - queries: { - // With SSR, we usually want to set some default staleTime - // above 0 to avoid refetching immediately on the client - staleTime: 60_000, - refetchOnWindowFocus: false, - retry: 0, - }, - }, - }); -} - -let browserQueryClient: QueryClient | undefined = undefined; - -export function getQueryClient() { - if (isServer) { - // Server: always make a new query client - return makeQueryClient(); - } else { - // Browser: make a new query client if we don't already have one - // This is very important, so we don't re-make a new client if React - // suspends during the initial render. This may not be needed if we - // have a suspense boundary BELOW the creation of the query client - if (!browserQueryClient) browserQueryClient = makeQueryClient(); - return browserQueryClient; - } -} diff --git a/nextjs-pages/src/components/spinner.css b/nextjs-pages/src/components/spinner.css deleted file mode 100644 index c0d6049..0000000 --- a/nextjs-pages/src/components/spinner.css +++ /dev/null @@ -1,56 +0,0 @@ -.loader { - width: 48px; - height: 48px; - border-radius: 50%; - display: inline-block; - position: relative; - border: 3px solid; - border-color: #6c757d #6c757d transparent transparent; - box-sizing: border-box; - animation: rotation 2s linear infinite; -} -.loader::after, -.loader::before { - content: ''; - box-sizing: border-box; - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - margin: auto; - border: 3px solid; - border-color: transparent transparent #092565 #092565; - width: 40px; - height: 40px; - border-radius: 50%; - box-sizing: border-box; - animation: rotationBack 1s linear infinite; - transform-origin: center center; -} -/* #092565 */ -/* #3a0647 */ -.loader::before { - width: 32px; - height: 32px; - border-color: #6c757d #6c757d transparent transparent; - animation: rotation 3s linear infinite; -} - -@keyframes rotation { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } -} -@keyframes rotationBack { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(-360deg); - } -} - \ No newline at end of file diff --git a/nextjs-pages/src/components/undefinedToNull.ts b/nextjs-pages/src/components/undefinedToNull.ts deleted file mode 100644 index 612c2b0..0000000 --- a/nextjs-pages/src/components/undefinedToNull.ts +++ /dev/null @@ -1,12 +0,0 @@ -export function undefinedWithNull(obj: T): T { - if (Array.isArray(obj)) { - return obj.map(undefinedWithNull) as unknown as T; - } else if (obj && typeof obj === 'object') { - return Object.keys(obj).reduce((acc, key) => { - const value = (obj as Record)[key]; - acc[key] = value === undefined ? null : undefinedWithNull(value); - return acc; - }, {} as Record) as T; - } - return obj; -} diff --git a/nextjs-pages/src/hooks/cavnasCouresHooks.ts b/nextjs-pages/src/hooks/cavnasCouresHooks.ts deleted file mode 100644 index a9f3e12..0000000 --- a/nextjs-pages/src/hooks/cavnasCouresHooks.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { canvasService } from "@/services/canvas/canvasService"; -import { useSuspenseQuery } from "@tanstack/react-query"; - -export const canvasCourseKeys = { - courseDetails: (canavasId: number) => ["canvas course", canavasId] as const, -}; - -export const useCanvasCourseQuery = (canvasId: number) => - useSuspenseQuery({ - queryKey: canvasCourseKeys.courseDetails(canvasId), - queryFn: async () => await canvasService.getCourse(canvasId), - }); diff --git a/nextjs-pages/src/hooks/hookHydration.ts b/nextjs-pages/src/hooks/hookHydration.ts deleted file mode 100644 index e5bc4dd..0000000 --- a/nextjs-pages/src/hooks/hookHydration.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { QueryClient } from "@tanstack/react-query"; -import { localCourseKeys } from "./localCourse/localCourseKeys"; -import { fileStorageService } from "@/services/fileStorage/fileStorageService"; -// https://tanstack.com/query/latest/docs/framework/react/guides/ssr -export const hydrateCourses = async (queryClient: QueryClient) => { - const allCourseNames = await fileStorageService.getCourseNames(); - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.allCourses, - queryFn: () => allCourseNames, - }); - await Promise.all( - allCourseNames.map(async (c) => await hydrateCourse(queryClient, c)) - ); -}; - -export const hydrateCourse = async ( - queryClient: QueryClient, - courseName: string -) => { - const settings = await fileStorageService.getCourseSettings(courseName); - const moduleNames = await fileStorageService.getModuleNames(courseName); - const modulesData = await Promise.all( - moduleNames.map(async (moduleName) => { - const [assignmentNames, pageNames, quizNames] = await Promise.all([ - await fileStorageService.getAssignmentNames(courseName, moduleName), - await fileStorageService.getPageNames(courseName, moduleName), - await fileStorageService.getQuizNames(courseName, moduleName), - ]); - - const [assignments, quizzes, pages] = await Promise.all([ - await Promise.all( - assignmentNames.map( - async (assignmentName) => - await fileStorageService.getAssignment( - courseName, - moduleName, - assignmentName - ) - ) - ), - await Promise.all( - quizNames.map( - async (quizName) => - await fileStorageService.getQuiz(courseName, moduleName, quizName) - ) - ), - await Promise.all( - pageNames.map( - async (pageName) => - await fileStorageService.getPage(courseName, moduleName, pageName) - ) - ), - ]); - - return { - moduleName, - assignmentNames, - pageNames, - quizNames, - assignments, - quizzes, - pages, - }; - }) - ); - - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.settings(courseName), - queryFn: () => settings, - }); - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.moduleNames(courseName), - queryFn: () => moduleNames, - }); - - await Promise.all( - modulesData.map( - async ({ - moduleName, - assignmentNames, - pageNames, - quizNames, - assignments, - quizzes, - pages, - }) => { - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.assignmentNames(courseName, moduleName), - queryFn: () => assignmentNames, - }); - await Promise.all( - assignments.map( - async (assignment) => - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.assignment( - courseName, - moduleName, - assignment.name - ), - queryFn: () => assignment, - }) - ) - ); - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.quizNames(courseName, moduleName), - queryFn: () => quizNames, - }); - await Promise.all( - quizzes.map( - async (quiz) => - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.quiz( - courseName, - moduleName, - quiz.name - ), - queryFn: () => quiz, - }) - ) - ); - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.pageNames(courseName, moduleName), - queryFn: () => pageNames, - }); - await Promise.all( - pages.map( - async (page) => - await queryClient.prefetchQuery({ - queryKey: localCourseKeys.page( - courseName, - moduleName, - page.name - ), - queryFn: () => page, - }) - ) - ); - } - ) - ); -}; diff --git a/nextjs-pages/src/hooks/localCourse/assignmentHooks.ts b/nextjs-pages/src/hooks/localCourse/assignmentHooks.ts deleted file mode 100644 index 293fc4d..0000000 --- a/nextjs-pages/src/hooks/localCourse/assignmentHooks.ts +++ /dev/null @@ -1,120 +0,0 @@ -"use client"; -import axios from "axios"; -import { localCourseKeys } from "./localCourseKeys"; -import { LocalAssignment } from "@/models/local/assignment/localAssignment"; -import { - useSuspenseQuery, - useSuspenseQueries, - useQueryClient, - useMutation, -} from "@tanstack/react-query"; -import { useCourseContext } from "@/components/contexts/courseContext"; - -export const useAssignmentNamesQuery = (moduleName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery({ - queryKey: localCourseKeys.assignmentNames(courseName, moduleName), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/assignments"; - const response = await axios.get(url); - return response.data; - }, - }); -}; - -const getAssignmentQueryConfig = ( - courseName: string, - moduleName: string, - assignmentName: string -) => { - return { - queryKey: localCourseKeys.assignment( - courseName, - moduleName, - assignmentName - ), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/assignments/" + - encodeURIComponent(assignmentName); - const response = await axios.get(url); - return response.data; - }, - }; -}; -export const useAssignmentQuery = ( - moduleName: string, - assignmentName: string -) => { - const { courseName } = useCourseContext(); - - return useSuspenseQuery( - getAssignmentQueryConfig(courseName, moduleName, assignmentName) - ); -}; - -export const useAssignmentsQueries = ( - moduleName: string, - assignmentNames: string[] -) => { - const { courseName } = useCourseContext(); - return useSuspenseQueries({ - queries: assignmentNames.map((name) => - getAssignmentQueryConfig(courseName, moduleName, name) - ), - combine: (results) => ({ - data: results.map((r) => r.data), - pending: results.some((r) => r.isPending), - }), - }); -}; - -export const useUpdateAssignmentMutation = () => { - const { courseName } = useCourseContext(); - const queryClient = useQueryClient(); - return useMutation({ - mutationFn: async ({ - assignment, - moduleName, - assignmentName, - }: { - assignment: LocalAssignment; - moduleName: string; - assignmentName: string; - }) => { - queryClient.setQueryData( - localCourseKeys.assignment(courseName, moduleName, assignmentName), - assignment - ); - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/assignments/" + - encodeURIComponent(assignmentName); - await axios.put(url, assignment); - }, - onSuccess: (_, { moduleName, assignmentName }) => { - queryClient.invalidateQueries({ - queryKey: localCourseKeys.assignment( - courseName, - moduleName, - assignmentName - ), - }); - queryClient.invalidateQueries({ - queryKey: localCourseKeys.assignmentNames(courseName, moduleName), - }); - }, - }); -}; diff --git a/nextjs-pages/src/hooks/localCourse/localCourseKeys.ts b/nextjs-pages/src/hooks/localCourse/localCourseKeys.ts deleted file mode 100644 index 7e8baf7..0000000 --- a/nextjs-pages/src/hooks/localCourse/localCourseKeys.ts +++ /dev/null @@ -1,70 +0,0 @@ -export const localCourseKeys = { - allCourses: ["all courses"] as const, - settings: (courseName: string) => - ["course details", courseName, "settings"] as const, - moduleNames: (courseName: string) => - [ - "course details", - courseName, - "modules", - { type: "names" } as const, - ] as const, - assignmentNames: (courseName: string, moduleName: string) => - [ - "course details", - courseName, - "modules", - moduleName, - "assignments", - { type: "names" }, - ] as const, - quizNames: (courseName: string, moduleName: string) => - [ - "course details", - courseName, - "modules", - moduleName, - "quizzes", - { type: "names" }, - ] as const, - pageNames: (courseName: string, moduleName: string) => - [ - "course details", - courseName, - "modules", - moduleName, - "pages", - { type: "names" }, - ] as const, - assignment: ( - courseName: string, - moduleName: string, - assignmentName: string - ) => - [ - "course details", - courseName, - "modules", - moduleName, - "assignments", - assignmentName, - ] as const, - quiz: (courseName: string, moduleName: string, quizName: string) => - [ - "course details", - courseName, - "modules", - moduleName, - "quizzes", - quizName, - ] as const, - page: (courseName: string, moduleName: string, pageName: string) => - [ - "course details", - courseName, - "modules", - moduleName, - "pages", - pageName, - ] as const, -}; diff --git a/nextjs-pages/src/hooks/localCourse/localCoursesHooks.ts b/nextjs-pages/src/hooks/localCourse/localCoursesHooks.ts deleted file mode 100644 index 70747fc..0000000 --- a/nextjs-pages/src/hooks/localCourse/localCoursesHooks.ts +++ /dev/null @@ -1,91 +0,0 @@ -"use client"; -import { LocalCourseSettings } from "@/models/local/localCourse"; -import { useSuspenseQuery } from "@tanstack/react-query"; -import axios from "axios"; -import { localCourseKeys } from "./localCourseKeys"; -import { useCourseContext } from "@/components/contexts/courseContext"; - -export const useLocalCourseNamesQuery = () => - useSuspenseQuery({ - queryKey: localCourseKeys.allCourses, - queryFn: async (): Promise => { - const url = `/api/courses`; - const response = await axios.get(url); - return response.data; - }, - }); - -export const useLocalCourseSettingsQuery = () => { - const { courseName } = useCourseContext(); - return useSuspenseQuery({ - queryKey: localCourseKeys.settings(courseName), - queryFn: async (): Promise => { - const url = `/api/courses/${courseName}/settings`; - const response = await axios.get(url); - return response.data; - }, - }); -}; - -export const useModuleNamesQuery = () => { - const { courseName } = useCourseContext(); - return useSuspenseQuery({ - queryKey: localCourseKeys.moduleNames(courseName), - queryFn: async (): Promise => { - const url = `/api/courses/${courseName}/modules`; - const response = await axios.get(url); - return response.data; - }, - }); -}; - -// dangerous? really slowed down page... -// maybe it only slowed down with react query devtools... -// export const useModuleDataQuery = (moduleName: string) => { -// console.log("running"); -// const { data: assignmentNames } = useAssignmentNamesQuery(moduleName); -// const { data: quizNames } = useQuizNamesQuery(moduleName); -// const { data: pageNames } = usePageNamesQuery(moduleName); - -// const { data: assignments } = useAssignmentsQueries( -// moduleName, -// assignmentNames -// ); -// const { data: quizzes } = useQuizzesQueries(moduleName, quizNames); -// const { data: pages } = usePagesQueries(moduleName, pageNames); - -// return { -// assignments, -// quizzes, -// pages, -// }; -// // return useMemo( -// // () => ({ -// // assignments, -// // quizzes, -// // pages, -// // }), -// // [assignments, pages, quizzes] -// // ); -// }; - -// export const useUpdateCourseMutation = (courseName: string) => { -// const queryClient = useQueryClient(); -// return useMutation({ -// mutationFn: async (body: { -// updatedCourse: LocalCourse; -// previousCourse: LocalCourse; -// }) => { -// const url = `/api/courses/${courseName}`; -// await axios.put(url, body); -// }, -// onSuccess: () => { -// queryClient.invalidateQueries({ -// queryKey: localCourseKeys.settings(courseName), -// }); -// }, -// scope: { -// id: "all courses", -// }, -// }); -// }; diff --git a/nextjs-pages/src/hooks/localCourse/pageHooks.ts b/nextjs-pages/src/hooks/localCourse/pageHooks.ts deleted file mode 100644 index a055046..0000000 --- a/nextjs-pages/src/hooks/localCourse/pageHooks.ts +++ /dev/null @@ -1,108 +0,0 @@ -"use client"; -import { LocalCoursePage } from "@/models/local/page/localCoursePage"; -import { - useMutation, - useQueryClient, - useSuspenseQueries, - useSuspenseQuery, -} from "@tanstack/react-query"; -import axios from "axios"; -import { localCourseKeys } from "./localCourseKeys"; -import { useCourseContext } from "@/components/contexts/courseContext"; - -export const usePageNamesQuery = (moduleName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery({ - queryKey: localCourseKeys.pageNames(courseName, moduleName), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/pages"; - const response = await axios.get(url); - return response.data; - }, - }); -}; -export const usePageQuery = (moduleName: string, pageName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery(getPageQueryConfig(courseName, moduleName, pageName)); -}; - -export const usePagesQueries = (moduleName: string, pageNames: string[]) => { - const { courseName } = useCourseContext(); - return useSuspenseQueries({ - queries: pageNames.map((name) => - getPageQueryConfig(courseName, moduleName, name) - ), - combine: (results) => ({ - data: results.map((r) => r.data), - pending: results.some((r) => r.isPending), - }), - }); -}; - -function getPageQueryConfig( - courseName: string, - moduleName: string, - pageName: string -) { - return { - queryKey: localCourseKeys.page(courseName, moduleName, pageName), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/pages/" + - encodeURIComponent(pageName); - try { - const response = await axios.get(url); - return response.data; - } catch (e) { - console.log("error getting page", e, url); - throw e; - } - }, - }; -} - -export const useUpdatePageMutation = () => { - const { courseName } = useCourseContext(); - const queryClient = useQueryClient(); - return useMutation({ - mutationFn: async ({ - page, - moduleName, - pageName, - }: { - page: LocalCoursePage; - moduleName: string; - pageName: string; - }) => { - queryClient.setQueryData( - localCourseKeys.page(courseName, moduleName, pageName), - page - ); - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/pages/" + - encodeURIComponent(pageName); - await axios.put(url, page); - }, - onSuccess: (_, { moduleName, pageName }) => { - queryClient.invalidateQueries({ - queryKey: localCourseKeys.page(courseName, moduleName, pageName), - }); - queryClient.invalidateQueries({ - queryKey: localCourseKeys.pageNames(courseName, moduleName), - }); - }, - }); -}; diff --git a/nextjs-pages/src/hooks/localCourse/quizHooks.ts b/nextjs-pages/src/hooks/localCourse/quizHooks.ts deleted file mode 100644 index a4a7ad5..0000000 --- a/nextjs-pages/src/hooks/localCourse/quizHooks.ts +++ /dev/null @@ -1,104 +0,0 @@ -"use client"; -import { LocalQuiz } from "@/models/local/quiz/localQuiz"; -import { - useMutation, - useQueryClient, - useSuspenseQueries, - useSuspenseQuery, -} from "@tanstack/react-query"; -import axios from "axios"; -import { localCourseKeys } from "./localCourseKeys"; -import { useCourseContext } from "@/components/contexts/courseContext"; - -export const useQuizNamesQuery = (moduleName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery({ - queryKey: localCourseKeys.quizNames(courseName, moduleName), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/quizzes"; - const response = await axios.get(url); - return response.data; - }, - }); -}; - -export const useQuizQuery = (moduleName: string, quizName: string) => { - const { courseName } = useCourseContext(); - return useSuspenseQuery(getQuizQueryConfig(courseName, moduleName, quizName)); -}; - -export const useQuizzesQueries = (moduleName: string, quizNames: string[]) => { - const { courseName } = useCourseContext(); - return useSuspenseQueries({ - queries: quizNames.map((name) => - getQuizQueryConfig(courseName, moduleName, name) - ), - combine: (results) => ({ - data: results.map((r) => r.data), - pending: results.some((r) => r.isPending), - }), - }); -}; - -function getQuizQueryConfig( - courseName: string, - moduleName: string, - quizName: string -) { - return { - queryKey: localCourseKeys.quiz(courseName, moduleName, quizName), - queryFn: async (): Promise => { - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/quizzes/" + - encodeURIComponent(quizName); - const response = await axios.get(url); - return response.data; - }, - }; -} - -export const useUpdateQuizMutation = () => { - const { courseName } = useCourseContext(); - const queryClient = useQueryClient(); - return useMutation({ - mutationFn: async ({ - quiz, - moduleName, - quizName, - }: { - quiz: LocalQuiz; - moduleName: string; - quizName: string; - }) => { - queryClient.setQueryData( - localCourseKeys.quiz(courseName, moduleName, quizName), - quiz - ); - const url = - "/api/courses/" + - encodeURIComponent(courseName) + - "/modules/" + - encodeURIComponent(moduleName) + - "/quizzes/" + - encodeURIComponent(quizName); - await axios.put(url, quiz); - }, - onSuccess: (_, { moduleName, quizName }) => { - queryClient.invalidateQueries({ - queryKey: localCourseKeys.quiz(courseName, moduleName, quizName), - }); - queryClient.invalidateQueries({ - queryKey: localCourseKeys.quizNames(courseName, moduleName), - }); - }, - }); -}; diff --git a/nextjs-pages/src/models/canvas/assignments/canvasAssignment.ts b/nextjs-pages/src/models/canvas/assignments/canvasAssignment.ts deleted file mode 100644 index ae791f2..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasAssignment.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { CanvasDiscussionTopicModel } from "../discussions/canvasDiscussionModelTopic"; -import { CanvasSubmissionModel } from "../submissions/canvasSubmissionModel"; -import { CanvasAssignmentDate } from "./canvasAssignmentDate"; -import { CanvasAssignmentOverride } from "./canvasAssignmentOverride"; -import { CanvasExternalToolTagAttributes } from "./canvasExternalToolTagAttributes"; -import { CanvasLockInfo } from "./canvasLockInfo"; -import { CanvasRubricCriteria } from "./canvasRubricCriteria"; -import { CanvasTurnitinSettings } from "./canvasTurnitinSettings"; - -export interface CanvasAssignment { - id: number; - name: string; - description: string; - created_at: string; // ISO 8601 date string - has_overrides: boolean; - course_id: number; - html_url: string; - submissions_download_url: string; - assignment_group_id: number; - due_date_required: boolean; - max_name_length: number; - peer_reviews: boolean; - automatic_peer_reviews: boolean; - position: number; - grading_type: string; - published: boolean; - unpublishable: boolean; - only_visible_to_overrides: boolean; - locked_for_user: boolean; - moderated_grading: boolean; - grader_count: number; - allowed_attempts: number; - is_quiz_assignment: boolean; - submission_types: string[]; - updated_at?: string; // ISO 8601 date string - due_at?: string; // ISO 8601 date string - lock_at?: string; // ISO 8601 date string - unlock_at?: string; // ISO 8601 date string - all_dates?: CanvasAssignmentDate[]; - allowed_extensions?: string[]; - turnitin_enabled?: boolean; - vericite_enabled?: boolean; - turnitin_settings?: CanvasTurnitinSettings; - grade_group_students_individually?: boolean; - external_tool_tag_attributes?: CanvasExternalToolTagAttributes; - peer_review_count?: number; - peer_reviews_assign_at?: string; // ISO 8601 date string - intra_group_peer_reviews?: boolean; - group_category_id?: number; - needs_grading_count?: number; - needs_grading_count_by_section?: { - section_id: string; - needs_grading_count: number; - }[]; - post_to_sis?: boolean; - integration_id?: string; - integration_data?: any; - muted?: boolean; - points_possible?: number; - has_submitted_submissions?: boolean; - grading_standard_id?: number; - lock_info?: CanvasLockInfo; - lock_explanation?: string; - quiz_id?: number; - anonymous_submissions?: boolean; - discussion_topic?: CanvasDiscussionTopicModel; - freeze_on_copy?: boolean; - frozen?: boolean; - frozen_attributes?: string[]; - submission?: CanvasSubmissionModel; - use_rubric_for_grading?: boolean; - rubric_settings?: any; - rubric?: CanvasRubricCriteria[]; - assignment_visibility?: number[]; - overrides?: CanvasAssignmentOverride[]; - omit_from_final_grade?: boolean; - final_grader_id?: number; - grader_comments_visible_to_graders?: boolean; - graders_anonymous_to_graders?: boolean; - grader_names_visible_to_final_grader?: boolean; - anonymous_grading?: boolean; -} diff --git a/nextjs-pages/src/models/canvas/assignments/canvasAssignmentDate.ts b/nextjs-pages/src/models/canvas/assignments/canvasAssignmentDate.ts deleted file mode 100644 index c695b9d..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasAssignmentDate.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface CanvasAssignmentDate { - title: string; - id?: number; - base?: boolean; - due_at?: string; // ISO 8601 date string - unlock_at?: string; // ISO 8601 date string - lock_at?: string; // ISO 8601 date string -} diff --git a/nextjs-pages/src/models/canvas/assignments/canvasAssignmentOverride.ts b/nextjs-pages/src/models/canvas/assignments/canvasAssignmentOverride.ts deleted file mode 100644 index ef52463..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasAssignmentOverride.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface CanvasAssignmentOverride { - id: number; - assignment_id: number; - course_section_id: number; - title: string; - student_ids?: number[]; - group_id?: number; - due_at?: string; // ISO 8601 date string - all_day?: boolean; - all_day_date?: string; // ISO 8601 date string - unlock_at?: string; // ISO 8601 date string - lock_at?: string; // ISO 8601 date string -} diff --git a/nextjs-pages/src/models/canvas/assignments/canvasExternalToolTagAttributes.ts b/nextjs-pages/src/models/canvas/assignments/canvasExternalToolTagAttributes.ts deleted file mode 100644 index 3161d33..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasExternalToolTagAttributes.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface CanvasExternalToolTagAttributes { - url: string; - resource_link_id: string; - new_tab?: boolean; -} diff --git a/nextjs-pages/src/models/canvas/assignments/canvasLockInfo.ts b/nextjs-pages/src/models/canvas/assignments/canvasLockInfo.ts deleted file mode 100644 index ac8fb57..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasLockInfo.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface CanvasLockInfo { - asset_string: string; - unlock_at?: string; // ISO 8601 date string - lock_at?: string; // ISO 8601 date string - context_module?: any; - manually_locked?: boolean; -} diff --git a/nextjs-pages/src/models/canvas/assignments/canvasRubric.ts b/nextjs-pages/src/models/canvas/assignments/canvasRubric.ts deleted file mode 100644 index fd85498..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasRubric.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface CanvasRubric { - id?: number; - title: string; - context_id: number; - context_type: string; - points_possible: number; - reusable: boolean; - read_only: boolean; - hide_score_total?: boolean; - // Uncomment and define if needed - // data: CanvasRubricCriteria[]; - // free_form_criterion_comments?: boolean; -} diff --git a/nextjs-pages/src/models/canvas/assignments/canvasRubricAssociation.ts b/nextjs-pages/src/models/canvas/assignments/canvasRubricAssociation.ts deleted file mode 100644 index 80354dc..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasRubricAssociation.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface CanvasRubricAssociation { - id: number; - rubric_id: number; - association_id: number; - association_type: string; - use_for_grading: boolean; - summary_data?: string; - purpose: string; - hide_score_total?: boolean; - hide_points: boolean; - hide_outcome_results: boolean; -} diff --git a/nextjs-pages/src/models/canvas/assignments/canvasRubricCriteria.ts b/nextjs-pages/src/models/canvas/assignments/canvasRubricCriteria.ts deleted file mode 100644 index fc7946e..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasRubricCriteria.ts +++ /dev/null @@ -1,16 +0,0 @@ -export interface CanvasRubricCriteria { - id: string; - description: string; - long_description: string; - points?: number; - learning_outcome_id?: string; - vendor_guid?: string; - criterion_use_range?: boolean; - ratings?: { - points: number; - id: string; - description: string; - long_description: string; - }[]; - ignore_for_scoring?: boolean; -} diff --git a/nextjs-pages/src/models/canvas/assignments/canvasTurnitinSettings.ts b/nextjs-pages/src/models/canvas/assignments/canvasTurnitinSettings.ts deleted file mode 100644 index d290aa2..0000000 --- a/nextjs-pages/src/models/canvas/assignments/canvasTurnitinSettings.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface CanvasTurnitinSettings { - originality_report_visibility: string; - s_paper_check: boolean; - internet_check: boolean; - journal_check: boolean; - exclude_biblio: boolean; - exclude_quoted: boolean; - exclude_small_matches_type?: boolean; - exclude_small_matches_value?: number; -} diff --git a/nextjs-pages/src/models/canvas/courses/canvasCalendarLinkModel.ts b/nextjs-pages/src/models/canvas/courses/canvasCalendarLinkModel.ts deleted file mode 100644 index 5ed98de..0000000 --- a/nextjs-pages/src/models/canvas/courses/canvasCalendarLinkModel.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface CanvasCalendarLinkModel { - ics: string; -} diff --git a/nextjs-pages/src/models/canvas/courses/canvasCourseModel.ts b/nextjs-pages/src/models/canvas/courses/canvasCourseModel.ts deleted file mode 100644 index 0090d42..0000000 --- a/nextjs-pages/src/models/canvas/courses/canvasCourseModel.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { CanvasEnrollmentModel } from "../enrollments/canvasEnrollmentModel"; -import { CanvasCalendarLinkModel } from "./canvasCalendarLinkModel"; -import { CanvasCourseProgressModel } from "./canvasCourseProgressModel"; -import { CanvasTermModel } from "./canvasTermModel"; - -export interface CanvasCourseModel { - id: number; - sis_course_id: string; - uuid: string; - integration_id: string; - name: string; - course_code: string; - workflow_state: string; - account_id: number; - root_account_id: number; - enrollment_term_id: number; - created_at: string; // ISO 8601 date string - locale: string; - calendar: CanvasCalendarLinkModel; - default_view: string; - syllabus_body: string; - permissions: { [key: string]: boolean }; - storage_quota_mb: number; - storage_quota_used_mb: number; - license: string; - course_format: string; - time_zone: string; - sis_import_id?: number; - grading_standard_id?: number; - start_at?: string; // ISO 8601 date string - end_at?: string; // ISO 8601 date string - enrollments?: CanvasEnrollmentModel[]; - total_students?: number; - needs_grading_count?: number; - term?: CanvasTermModel; - course_progress?: CanvasCourseProgressModel; - apply_assignment_group_weights?: boolean; - is_public?: boolean; - is_public_to_auth_users?: boolean; - public_syllabus?: boolean; - public_syllabus_to_auth?: boolean; - public_description?: string; - hide_final_grades?: boolean; - allow_student_assignment_edits?: boolean; - allow_wiki_comments?: boolean; - allow_student_forum_attachments?: boolean; - open_enrollment?: boolean; - self_enrollment?: boolean; - restrict_enrollments_to_course_dates?: boolean; - access_restricted_by_date?: boolean; - blueprint?: boolean; - blueprint_restrictions?: { [key: string]: boolean }; - blueprint_restrictions_by_object_type?: { - [key: string]: { [key: string]: boolean }; - }; -} diff --git a/nextjs-pages/src/models/canvas/courses/canvasCourseProgressModel.ts b/nextjs-pages/src/models/canvas/courses/canvasCourseProgressModel.ts deleted file mode 100644 index 99b1df1..0000000 --- a/nextjs-pages/src/models/canvas/courses/canvasCourseProgressModel.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface CanvasCourseProgressModel { - requirement_count?: number; - requirement_completed_count?: number; - next_requirement_url?: string; - completed_at?: string; // ISO 8601 date string -} diff --git a/nextjs-pages/src/models/canvas/courses/canvasCourseSettingsModel.ts b/nextjs-pages/src/models/canvas/courses/canvasCourseSettingsModel.ts deleted file mode 100644 index 45d05d1..0000000 --- a/nextjs-pages/src/models/canvas/courses/canvasCourseSettingsModel.ts +++ /dev/null @@ -1,16 +0,0 @@ -export interface CanvasCourseSettingsModel { - allow_final_grade_override: boolean; - allow_student_discussion_topics: boolean; - allow_student_forum_attachments: boolean; - allow_student_discussion_editing: boolean; - grading_standard_enabled: boolean; - allow_student_organized_groups: boolean; - hide_final_grades: boolean; - hide_distribution_graphs: boolean; - lock_all_announcements: boolean; - restrict_student_past_view: boolean; - restrict_student_future_view: boolean; - show_announcements_on_home_page: boolean; - home_page_announcement_limit: number; - grading_standard_id?: number; -} diff --git a/nextjs-pages/src/models/canvas/courses/canvasTermModel.ts b/nextjs-pages/src/models/canvas/courses/canvasTermModel.ts deleted file mode 100644 index 89c889d..0000000 --- a/nextjs-pages/src/models/canvas/courses/canvasTermModel.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface CanvasTermModel { - id: number; - name: string; - start_at?: string; // ISO 8601 date string - end_at?: string; // ISO 8601 date string -} diff --git a/nextjs-pages/src/models/canvas/discussions/canvasDiscussionModelTopic.ts b/nextjs-pages/src/models/canvas/discussions/canvasDiscussionModelTopic.ts deleted file mode 100644 index c667b16..0000000 --- a/nextjs-pages/src/models/canvas/discussions/canvasDiscussionModelTopic.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { CanvasUserDisplayModel } from "../users/userDisplayModel"; -import { CanvasFileAttachmentModel } from "./canvasFileAttachmentModel"; - -export interface CanvasDiscussionTopicModel { - id: number; - title: string; - message: string; - html_url: string; - read_state: string; - subscription_hold: string; - assignment_id: number; - lock_explanation: string; - user_name: string; - topic_children: number[]; - podcast_url: string; - discussion_type: string; - attachments: CanvasFileAttachmentModel[]; - permissions: { [key: string]: boolean }; - author: CanvasUserDisplayModel; - unread_count?: number; - subscribed?: boolean; - posted_at?: string; // ISO 8601 date string - last_reply_at?: string; // ISO 8601 date string - require_initial_post?: boolean; - user_can_see_posts?: boolean; - discussion_subentry_count?: number; - delayed_post_at?: string; // ISO 8601 date string - published?: boolean; - lock_at?: string; // ISO 8601 date string - locked?: boolean; - pinned?: boolean; - locked_for_user?: boolean; - lock_info?: any; - group_topic_children?: any; - root_topic_id?: number; - group_category_id?: number; - allow_rating?: boolean; - only_graders_can_rate?: boolean; - sort_by_rating?: boolean; -} diff --git a/nextjs-pages/src/models/canvas/discussions/canvasFileAttachmentModel.ts b/nextjs-pages/src/models/canvas/discussions/canvasFileAttachmentModel.ts deleted file mode 100644 index 049c936..0000000 --- a/nextjs-pages/src/models/canvas/discussions/canvasFileAttachmentModel.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface CanvasFileAttachmentModel { - content_type: string; - url: string; - filename: string; - display_name: string; -} diff --git a/nextjs-pages/src/models/canvas/enrollmentTerms/canvasEnrollmentTermModel.ts b/nextjs-pages/src/models/canvas/enrollmentTerms/canvasEnrollmentTermModel.ts deleted file mode 100644 index 90aff4c..0000000 --- a/nextjs-pages/src/models/canvas/enrollmentTerms/canvasEnrollmentTermModel.ts +++ /dev/null @@ -1,16 +0,0 @@ -export interface CanvasEnrollmentTermModel { - id: number; - name: string; - sis_term_id?: string; - sis_import_id?: number; - start_at?: string; // ISO 8601 date string - end_at?: string; // ISO 8601 date string - grading_period_group_id?: number; - workflow_state?: string; - overrides?: { - [key: string]: { - start_at?: string; // ISO 8601 date string - end_at?: string; // ISO 8601 date string - }; - }; -} diff --git a/nextjs-pages/src/models/canvas/enrollments/canvasEnrollmentModel.ts b/nextjs-pages/src/models/canvas/enrollments/canvasEnrollmentModel.ts deleted file mode 100644 index 9c4c5a5..0000000 --- a/nextjs-pages/src/models/canvas/enrollments/canvasEnrollmentModel.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { CanvasUserDisplayModel } from "../users/userDisplayModel"; -import { CanvasGradeModel } from "./canvasGradeModel"; - -export interface CanvasEnrollmentModel { - id: number; - course_id: number; - enrollment_state: string; - type: string; - user_id: number; - role: string; - role_id: number; - html_url: string; - grades: CanvasGradeModel; - user: CanvasUserDisplayModel; - override_grade: string; - sis_course_id?: string; - course_integration_id?: string; - course_section_id?: number; - section_integration_id?: string; - sis_account_id?: string; - sis_section_id?: string; - sis_user_id?: string; - limit_privileges_to_course_section?: boolean; - sis_import_id?: number; - root_account_id?: number; - associated_user_id?: number; - created_at?: string; // ISO 8601 date string - updated_at?: string; // ISO 8601 date string - start_at?: string; // ISO 8601 date string - end_at?: string; // ISO 8601 date string - last_activity_at?: string; // ISO 8601 date string - last_attended_at?: string; // ISO 8601 date string - total_activity_time?: number; - override_score?: number; - unposted_current_grade?: string; - unposted_final_grade?: string; - unposted_current_score?: string; - unposted_final_score?: string; - has_grading_periods?: boolean; - totals_for_all_grading_periods_option?: boolean; - current_grading_period_title?: string; - current_grading_period_id?: number; - current_period_override_grade?: string; - current_period_override_score?: number; - current_period_unposted_final_score?: number; - current_period_unposted_current_grade?: string; - current_period_unposted_final_grade?: string; -} diff --git a/nextjs-pages/src/models/canvas/enrollments/canvasGradeModel.ts b/nextjs-pages/src/models/canvas/enrollments/canvasGradeModel.ts deleted file mode 100644 index caad4c3..0000000 --- a/nextjs-pages/src/models/canvas/enrollments/canvasGradeModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface CanvasGradeModel { - html_url?: string; - current_grade?: number; - final_grade?: number; - current_score?: number; - final_score?: number; - unposted_current_grade?: number; - unposted_final_grade?: number; - unposted_current_score?: number; - unposted_final_score?: number; -} diff --git a/nextjs-pages/src/models/canvas/modules/canvasModule.ts b/nextjs-pages/src/models/canvas/modules/canvasModule.ts deleted file mode 100644 index ef593c4..0000000 --- a/nextjs-pages/src/models/canvas/modules/canvasModule.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CanvasModuleItem } from "./canvasModuleItems"; - -export interface CanvasModule { - id: number; - workflow_state: string; - position: number; - name: string; - unlock_at?: string; // ISO 8601 date string - require_sequential_progress?: boolean; - prerequisite_module_ids?: number[]; - items_count: number; - items_url: string; - items?: CanvasModuleItem[]; - state?: string; - completed_at?: string; // ISO 8601 date string - publish_final_grade?: boolean; - published?: boolean; -} diff --git a/nextjs-pages/src/models/canvas/modules/canvasModuleItems.ts b/nextjs-pages/src/models/canvas/modules/canvasModuleItems.ts deleted file mode 100644 index 314f80c..0000000 --- a/nextjs-pages/src/models/canvas/modules/canvasModuleItems.ts +++ /dev/null @@ -1,26 +0,0 @@ -export interface CanvasModuleItem { - id: number; - module_id: number; - position: number; - title: string; - indent?: number; - type: string; - content_id?: number; - html_url: string; - url?: string; - page_url?: string; - external_url?: string; - new_tab: boolean; - completion_requirement?: { - type: string; - min_score?: number; - completed?: boolean; - }; - published?: boolean; - content_details?: { - due_at?: string; // ISO 8601 date string - lock_at?: string; // ISO 8601 date string - points_possible: number; - locked_for_user: boolean; - }; -} diff --git a/nextjs-pages/src/models/canvas/pages/canvasPageModel.ts b/nextjs-pages/src/models/canvas/pages/canvasPageModel.ts deleted file mode 100644 index 79683b7..0000000 --- a/nextjs-pages/src/models/canvas/pages/canvasPageModel.ts +++ /dev/null @@ -1,16 +0,0 @@ -export interface CanvasPage { - page_id: number; - url: string; - title: string; - published: boolean; - front_page: boolean; - body?: string; - // Uncomment and define if needed - // created_at: string; // ISO 8601 date string - // updated_at: string; // ISO 8601 date string - // editing_roles: string; - // last_edited_by: UserDisplayModel; - // locked_for_user: boolean; - // lock_info?: LockInfoModel; - // lock_explanation?: string; -} diff --git a/nextjs-pages/src/models/canvas/quizzes/canvasQuizModel.ts b/nextjs-pages/src/models/canvas/quizzes/canvasQuizModel.ts deleted file mode 100644 index c207dd0..0000000 --- a/nextjs-pages/src/models/canvas/quizzes/canvasQuizModel.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { CanvasLockInfo } from "../assignments/canvasLockInfo"; -import { CanvasQuizPermissions } from "./canvasQuizPermission"; - -export interface CanvasQuiz { - id: number; - title: string; - html_url: string; - mobile_url: string; - preview_url?: string; - description: string; - quiz_type: string; - assignment_group_id?: number; - time_limit?: number; - shuffle_answers?: boolean; - hide_results?: string; - show_correct_answers?: boolean; - show_correct_answers_last_attempt?: boolean; - show_correct_answers_at?: string; // ISO 8601 date string - hide_correct_answers_at?: string; // ISO 8601 date string - one_time_results?: boolean; - scoring_policy?: string; - allowed_attempts: number; - one_question_at_a_time?: boolean; - question_count?: number; - points_possible?: number; - cant_go_back?: boolean; - access_code?: string; - ip_filter?: string; - due_at?: string; // ISO 8601 date string - lock_at?: string; // ISO 8601 date string - unlock_at?: string; // ISO 8601 date string - published?: boolean; - unpublishable?: boolean; - locked_for_user?: boolean; - lock_info?: CanvasLockInfo; - lock_explanation?: string; - speedgrader_url?: string; - quiz_extensions_url?: string; - permissions: CanvasQuizPermissions; - all_dates?: any; // Depending on the structure of the dates, this could be further specified - version_number?: number; - question_types?: string[]; - anonymous_submissions?: boolean; -} diff --git a/nextjs-pages/src/models/canvas/quizzes/canvasQuizPermission.ts b/nextjs-pages/src/models/canvas/quizzes/canvasQuizPermission.ts deleted file mode 100644 index a9fe3da..0000000 --- a/nextjs-pages/src/models/canvas/quizzes/canvasQuizPermission.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface CanvasQuizPermissions { - read: boolean; - submit: boolean; - create: boolean; - manage: boolean; - read_statistics: boolean; - review_grades: boolean; - update: boolean; -} diff --git a/nextjs-pages/src/models/canvas/submissions/canvasSubmissionModel.ts b/nextjs-pages/src/models/canvas/submissions/canvasSubmissionModel.ts deleted file mode 100644 index 355a953..0000000 --- a/nextjs-pages/src/models/canvas/submissions/canvasSubmissionModel.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { CanvasAssignment } from "../assignments/canvasAssignment"; -import { CanvasCourseModel } from "../courses/canvasCourseModel"; -import { CanvasUserModel } from "../users/canvasUserModel"; -import { CanvasUserDisplayModel } from "../users/userDisplayModel"; - -export interface CanvasSubmissionModel { - assignment_id: number; - grade: string; - html_url: string; - preview_url: string; - submission_type: string; - user_id: number; - user: CanvasUserModel; - workflow_state: string; - late_policy_status: string; - assignment?: CanvasAssignment; - course?: CanvasCourseModel; - attempt?: number; - body?: string; - grade_matches_current_submission?: boolean; - score?: number; - submission_comments?: { - id: number; - author_id: number; - author_name: string; - author: CanvasUserDisplayModel; - comment: string; - created_at: string; // ISO 8601 date string - edited_at?: string; // ISO 8601 date string - media_comment?: { - content_type: string; - display_name: string; - media_id: string; - media_type: string; - url: string; - }; - }[]; - submitted_at?: string; // ISO 8601 date string - url?: string; - grader_id?: number; - graded_at?: string; // ISO 8601 date string - late?: boolean; - assignment_visible?: boolean; - excused?: boolean; - missing?: boolean; - points_deducted?: number; - seconds_late?: number; - extra_attempts?: number; - anonymous_id?: string; -} diff --git a/nextjs-pages/src/models/canvas/users/canvasUserModel.ts b/nextjs-pages/src/models/canvas/users/canvasUserModel.ts deleted file mode 100644 index 50aa8fa..0000000 --- a/nextjs-pages/src/models/canvas/users/canvasUserModel.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { CanvasEnrollmentModel } from "../enrollments/canvasEnrollmentModel"; - -export interface CanvasUserModel { - id: number; - name: string; - sortable_name: string; - short_name: string; - sis_user_id: string; - integration_id: string; - login_id: string; - avatar_url: string; - enrollments: CanvasEnrollmentModel[]; - email: string; - locale: string; - effective_locale: string; - time_zone: string; - bio: string; - permissions: { [key: string]: boolean }; - sis_import_id?: number; - last_login?: string; // ISO 8601 date string -} diff --git a/nextjs-pages/src/models/canvas/users/userDisplayModel.ts b/nextjs-pages/src/models/canvas/users/userDisplayModel.ts deleted file mode 100644 index 3c152cc..0000000 --- a/nextjs-pages/src/models/canvas/users/userDisplayModel.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface CanvasUserDisplayModel { - avatar_image_url: string; - html_url: string; - anonymous_id: string; - id?: number; - short_name?: string; - display_name?: string; - pronouns?: string; -} diff --git a/nextjs-pages/src/models/local/IModuleItem.ts b/nextjs-pages/src/models/local/IModuleItem.ts deleted file mode 100644 index 43d40f1..0000000 --- a/nextjs-pages/src/models/local/IModuleItem.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IModuleItem { - name: string; - dueAt: string; -} diff --git a/nextjs-pages/src/models/local/assignment/assignmentSubmissionType.ts b/nextjs-pages/src/models/local/assignment/assignmentSubmissionType.ts deleted file mode 100644 index 79aa64a..0000000 --- a/nextjs-pages/src/models/local/assignment/assignmentSubmissionType.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum AssignmentSubmissionType { - ONLINE_TEXT_ENTRY = "online_text_entry", - ONLINE_UPLOAD = "online_upload", - ONLINE_QUIZ = "online_quiz", - DISCUSSION_TOPIC = "discussion_topic", - ONLINE_URL = "online_url", - NONE = "none", -} diff --git a/nextjs-pages/src/models/local/assignment/localAssignment.ts b/nextjs-pages/src/models/local/assignment/localAssignment.ts deleted file mode 100644 index 9beeea1..0000000 --- a/nextjs-pages/src/models/local/assignment/localAssignment.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { IModuleItem } from "../IModuleItem"; -import { AssignmentSubmissionType } from "./assignmentSubmissionType"; -import { RubricItem } from "./rubricItem"; -import { assignmentMarkdownParser } from "./utils/assignmentMarkdownParser"; -import { assignmentMarkdownSerializer } from "./utils/assignmentMarkdownSerializer"; - -export interface LocalAssignment extends IModuleItem { - name: string; - description: string; - lockAt?: string; // 08/21/2023 23:59:00 - dueAt: string; // 08/21/2023 23:59:00 - localAssignmentGroupName?: string; - submissionTypes: AssignmentSubmissionType[]; - allowedFileUploadExtensions: string[]; - rubric: RubricItem[]; -} - -export const localAssignmentMarkdown = { - parseMarkdown: assignmentMarkdownParser.parseMarkdown, - toMarkdown: assignmentMarkdownSerializer.toMarkdown, -}; diff --git a/nextjs-pages/src/models/local/assignment/localAssignmentGroup.ts b/nextjs-pages/src/models/local/assignment/localAssignmentGroup.ts deleted file mode 100644 index f83201c..0000000 --- a/nextjs-pages/src/models/local/assignment/localAssignmentGroup.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface LocalAssignmentGroup { - canvasId?: number; - id: string; - name: string; - weight: number; -} \ No newline at end of file diff --git a/nextjs-pages/src/models/local/assignment/rubricItem.ts b/nextjs-pages/src/models/local/assignment/rubricItem.ts deleted file mode 100644 index e80d517..0000000 --- a/nextjs-pages/src/models/local/assignment/rubricItem.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface RubricItem { - label: string; - points: number; -} - - -export const rubricItemIsExtraCredit = (item: RubricItem) => { - const extraCredit = '(extra credit)'; - return item.label.toLowerCase().includes(extraCredit.toLowerCase()); -} \ No newline at end of file diff --git a/nextjs-pages/src/models/local/assignment/utils/assignmentMarkdownParser.ts b/nextjs-pages/src/models/local/assignment/utils/assignmentMarkdownParser.ts deleted file mode 100644 index f36c6ef..0000000 --- a/nextjs-pages/src/models/local/assignment/utils/assignmentMarkdownParser.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { - verifyDateOrThrow, - verifyDateStringOrUndefined, -} from "../../timeUtils"; -import { AssignmentSubmissionType } from "../assignmentSubmissionType"; -import { LocalAssignment } from "../localAssignment"; -import { RubricItem } from "../rubricItem"; -import { extractLabelValue } from "./markdownUtils"; - -const parseFileUploadExtensions = (input: string) => { - const allowedFileUploadExtensions: string[] = []; - const regex = /- (.+)/; - - const words = input.split("AllowedFileUploadExtensions:"); - if (words.length < 2) return allowedFileUploadExtensions; - - const inputAfterSubmissionTypes = words[1]; - const lines = inputAfterSubmissionTypes - .split("\n") - .map((line) => line.trim()); - - for (const line of lines) { - const match = regex.exec(line); - if (!match) { - if (line === "") continue; - else break; - } - - allowedFileUploadExtensions.push(match[1].trim()); - } - - return allowedFileUploadExtensions; -}; - -const parseIndividualRubricItemMarkdown = (rawMarkdown: string) => { - const pointsPattern = /\s*-\s*(-?\d+(?:\.\d+)?)\s*pt(s)?:/; - const match = pointsPattern.exec(rawMarkdown); - if (!match) { - throw new Error(`Points not found: ${rawMarkdown}`); - } - - const points = parseFloat(match[1]); - const label = rawMarkdown.split(": ").slice(1).join(": "); - - const item: RubricItem = { points, label }; - return item; -}; - -const parseSettings = (input: string) => { - const name = extractLabelValue(input, "Name"); - const rawLockAt = extractLabelValue(input, "LockAt"); - const rawDueAt = extractLabelValue(input, "DueAt"); - const assignmentGroupName = extractLabelValue(input, "AssignmentGroupName"); - const submissionTypes = parseSubmissionTypes(input); - const fileUploadExtensions = parseFileUploadExtensions(input); - - const dueAt = verifyDateOrThrow(rawDueAt, "DueAt"); - const lockAt = verifyDateStringOrUndefined(rawLockAt); - - return { - name, - assignmentGroupName, - submissionTypes, - fileUploadExtensions, - dueAt, - lockAt, - }; -}; - -const parseSubmissionTypes = (input: string): AssignmentSubmissionType[] => { - const submissionTypes: AssignmentSubmissionType[] = []; - const regex = /- (.+)/; - - const words = input.split("SubmissionTypes:"); - if (words.length < 2) return submissionTypes; - - const inputAfterSubmissionTypes = words[1]; // doesn't consider other settings that follow... - const lines = inputAfterSubmissionTypes - .split("\n") - .map((line) => line.trim()); - - for (const line of lines) { - const match = regex.exec(line); - if (!match) { - if (line === "") continue; - else break; - } - - const typeString = match[1].trim(); - const type = Object.values(AssignmentSubmissionType).find( - (t) => t === typeString - ); - - if (type) { - submissionTypes.push(type); - } else { - console.warn(`Unknown submission type: ${typeString}`); - } - } - - return submissionTypes; -}; - -const parseRubricMarkdown = (rawMarkdown: string) => { - if (!rawMarkdown.trim()) return []; - - const lines = rawMarkdown.trim().split("\n"); - return lines.map(parseIndividualRubricItemMarkdown); -}; - -export const assignmentMarkdownParser = { - parseRubricMarkdown, - parseMarkdown(input: string): LocalAssignment { - const settingsString = input.split("---")[0]; - const { - name, - assignmentGroupName, - submissionTypes, - fileUploadExtensions, - dueAt, - lockAt, - } = parseSettings(settingsString); - - const description = input - .split("---\n") - .slice(1) - .join("---\n") - .split("## Rubric")[0] - .trim(); - - const rubricString = input.split("## Rubric\n")[1]; - const rubric = parseRubricMarkdown(rubricString); - - const assignment: LocalAssignment = { - name: name.trim(), - localAssignmentGroupName: assignmentGroupName.trim(), - submissionTypes: submissionTypes, - allowedFileUploadExtensions: fileUploadExtensions, - dueAt: dueAt, - lockAt: lockAt, - rubric: rubric, - description: description, - }; - return assignment; - }, -}; diff --git a/nextjs-pages/src/models/local/assignment/utils/assignmentMarkdownSerializer.ts b/nextjs-pages/src/models/local/assignment/utils/assignmentMarkdownSerializer.ts deleted file mode 100644 index bbb1ece..0000000 --- a/nextjs-pages/src/models/local/assignment/utils/assignmentMarkdownSerializer.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { AssignmentSubmissionType } from "../assignmentSubmissionType"; -import { LocalAssignment } from "../localAssignment"; -import { RubricItem } from "../rubricItem"; - -const assignmentRubricToMarkdown = (assignment: LocalAssignment) => { - return assignment.rubric - .map((item: RubricItem) => { - const pointLabel = item.points > 1 ? "pts" : "pt"; - return `- ${item.points}${pointLabel}: ${item.label}`; - }) - .join("\n"); -}; - -const settingsToMarkdown = (assignment: LocalAssignment) => { - const printableDueDate = assignment.dueAt.toString().replace("\u202F", " "); - const printableLockAt = - assignment.lockAt?.toString().replace("\u202F", " ") || ""; - - const submissionTypesMarkdown = assignment.submissionTypes - .map((submissionType: AssignmentSubmissionType) => `- ${submissionType}`) - .join("\n"); - - const allowedFileUploadExtensionsMarkdown = - assignment.allowedFileUploadExtensions - .map((fileExtension: string) => `- ${fileExtension}`) - .join("\n"); - - const settingsMarkdown = [ - `Name: ${assignment.name}`, - `LockAt: ${printableLockAt}`, - `DueAt: ${printableDueDate}`, - `AssignmentGroupName: ${assignment.localAssignmentGroupName}`, - `SubmissionTypes:\n${submissionTypesMarkdown}`, - `AllowedFileUploadExtensions:\n${allowedFileUploadExtensionsMarkdown}`, - ].join("\n"); - - return settingsMarkdown; -}; - -export const assignmentMarkdownSerializer = { - toMarkdown(assignment: LocalAssignment): string { - const settingsMarkdown = settingsToMarkdown(assignment); - const rubricMarkdown = assignmentRubricToMarkdown(assignment); - const assignmentMarkdown = `${settingsMarkdown}\n---\n\n${assignment.description}\n\n## Rubric\n\n${rubricMarkdown}`; - - return assignmentMarkdown; - }, -}; diff --git a/nextjs-pages/src/models/local/assignment/utils/markdownUtils.ts b/nextjs-pages/src/models/local/assignment/utils/markdownUtils.ts deleted file mode 100644 index a65cd23..0000000 --- a/nextjs-pages/src/models/local/assignment/utils/markdownUtils.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const extractLabelValue = (input: string, label: string) => { - const pattern = new RegExp(`${label}: (.*?)\n`); - const match = pattern.exec(input); - - if (match && match[1]) { - return match[1].trim(); - } - - return ""; -}; diff --git a/nextjs-pages/src/models/local/localCourse.ts b/nextjs-pages/src/models/local/localCourse.ts deleted file mode 100644 index 057c0cd..0000000 --- a/nextjs-pages/src/models/local/localCourse.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { LocalAssignmentGroup } from "./assignment/localAssignmentGroup"; -import { LocalModule } from "./localModules"; -import { parse, stringify } from "yaml"; - -export interface LocalCourse { - modules: LocalModule[]; - settings: LocalCourseSettings; -} - -export interface SimpleTimeOnly { - hour: number; - minute: number; -} - -export interface LocalCourseSettings { - name: string; - assignmentGroups: LocalAssignmentGroup[]; - daysOfWeek: DayOfWeek[]; - canvasId?: number; - startDate: string; - endDate: string; - defaultDueTime: SimpleTimeOnly; -} - -export enum DayOfWeek { - Sunday = "Sunday", - Monday = "Monday", - Tuesday = "Tuesday", - Wednesday = "Wednesday", - Thursday = "Thursday", - Friday = "Friday", - Saturday = "Saturday", -} -export const localCourseYamlUtils = { - parseSettingYaml: (settingsString: string): LocalCourseSettings => { - const settings = parse(settingsString); - return lowercaseFirstLetter(settings); - }, - settingsToYaml: (settings: LocalCourseSettings) => { - return stringify(settings); - }, -}; - -function lowercaseFirstLetter(obj: T): T { - if (obj === null || typeof obj !== "object") return obj as T; - - if (Array.isArray(obj)) return obj.map(lowercaseFirstLetter) as unknown as T; - - const result: Record = {}; - Object.keys(obj).forEach((key) => { - const value = (obj as Record)[key]; - const newKey = key.charAt(0).toLowerCase() + key.slice(1); - - if (value && typeof value === "object") { - result[newKey] = lowercaseFirstLetter(value); - } else { - result[newKey] = value; - } - }); - - return result as T; -} diff --git a/nextjs-pages/src/models/local/localModules.ts b/nextjs-pages/src/models/local/localModules.ts deleted file mode 100644 index 29b833e..0000000 --- a/nextjs-pages/src/models/local/localModules.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { LocalAssignment } from "./assignment/localAssignment"; -import { IModuleItem } from "./IModuleItem"; -import { LocalCoursePage } from "./page/localCoursePage"; -import { LocalQuiz } from "./quiz/localQuiz"; -import { getDateFromString } from "./timeUtils"; - -export interface LocalModule { - name: string; - assignments: LocalAssignment[]; - quizzes: LocalQuiz[]; - pages: LocalCoursePage[]; -} - -export const LocalModuleUtils = { - getSortedModuleItems(module: LocalModule): IModuleItem[] { - return [...module.assignments, ...module.quizzes, ...module.pages].sort( - (a, b) => - (getDateFromString(a.dueAt)?.getTime() ?? 0) - - (getDateFromString(b.dueAt)?.getTime() ?? 0) - ); - }, - - equals(module1: LocalModule, module2: LocalModule): boolean { - return ( - module1.name.toLowerCase() === module2.name.toLowerCase() && - LocalModuleUtils.compareCollections( - module1.assignments.sort((a, b) => a.name.localeCompare(b.name)), - module2.assignments.sort((a, b) => a.name.localeCompare(b.name)) - ) && - LocalModuleUtils.compareCollections( - module1.quizzes.sort((a, b) => a.name.localeCompare(b.name)), - module2.quizzes.sort((a, b) => a.name.localeCompare(b.name)) - ) && - LocalModuleUtils.compareCollections( - module1.pages.sort((a, b) => a.name.localeCompare(b.name)), - module2.pages.sort((a, b) => a.name.localeCompare(b.name)) - ) - ); - }, - - compareCollections(first: T[], second: T[]): boolean { - if (first.length !== second.length) return false; - - for (let i = 0; i < first.length; i++) { - if (JSON.stringify(first[i]) !== JSON.stringify(second[i])) return false; - } - - return true; - }, - - getHashCode(module: LocalModule): number { - const hash = new Map(); - hash.set(module.name.toLowerCase(), 1); - LocalModuleUtils.addRangeToHash( - hash, - module.assignments.sort((a, b) => a.name.localeCompare(b.name)) - ); - LocalModuleUtils.addRangeToHash( - hash, - module.quizzes.sort((a, b) => a.name.localeCompare(b.name)) - ); - LocalModuleUtils.addRangeToHash( - hash, - module.pages.sort((a, b) => a.name.localeCompare(b.name)) - ); - - return Array.from(hash.values()).reduce((acc, val) => acc + val, 0); - }, - - addRangeToHash(hash: Map, items: T[]): void { - for (const item of items) { - hash.set(JSON.stringify(item), 1); - } - }, -}; diff --git a/nextjs-pages/src/models/local/page/localCoursePage.ts b/nextjs-pages/src/models/local/page/localCoursePage.ts deleted file mode 100644 index e41fab5..0000000 --- a/nextjs-pages/src/models/local/page/localCoursePage.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { extractLabelValue } from "../assignment/utils/markdownUtils"; -import { IModuleItem } from "../IModuleItem"; -import { verifyDateOrThrow } from "../timeUtils"; - -export interface LocalCoursePage extends IModuleItem { - name: string; - text: string; - dueAt: string; -} - -export const localPageMarkdownUtils = { - toMarkdown: (page: LocalCoursePage) => { - const printableDueDate = verifyDateOrThrow(page.dueAt, "page DueDateForOrdering") - const settingsMarkdown = `Name: ${page.name}\nDueDateForOrdering: ${printableDueDate}\n---\n`; - return settingsMarkdown + page.text; - }, - - parseMarkdown: (pageMarkdown: string) => { - const rawSettings = pageMarkdown.split("---")[0]; - const name = extractLabelValue(rawSettings, "Name"); - const rawDate = extractLabelValue(rawSettings, "DueDateForOrdering"); - const dueAt = verifyDateOrThrow(rawDate, "page DueDateForOrdering"); - - const text = pageMarkdown.split("---\n")[1]; - - const page: LocalCoursePage = { - name, - dueAt, - text, - }; - return page; - }, -}; diff --git a/nextjs-pages/src/models/local/quiz/localQuiz.ts b/nextjs-pages/src/models/local/quiz/localQuiz.ts deleted file mode 100644 index 70fd667..0000000 --- a/nextjs-pages/src/models/local/quiz/localQuiz.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { IModuleItem } from "../IModuleItem"; -import { LocalQuizQuestion } from "./localQuizQuestion"; -import { quizMarkdownUtils } from "./utils/quizMarkdownUtils"; - -export interface LocalQuiz extends IModuleItem { - name: string; - description: string; - password?: string; - lockAt?: string; // ISO 8601 date string - dueAt: string; // ISO 8601 date string - shuffleAnswers: boolean; - showCorrectAnswers: boolean; - oneQuestionAtATime: boolean; - localAssignmentGroupName?: string; - allowedAttempts: number; - questions: LocalQuizQuestion[]; -} - -export const localQuizMarkdownUtils = { - parseMarkdown: quizMarkdownUtils.parseMarkdown, - toMarkdown: quizMarkdownUtils.toMarkdown, -}; diff --git a/nextjs-pages/src/models/local/quiz/localQuizQuestion.ts b/nextjs-pages/src/models/local/quiz/localQuizQuestion.ts deleted file mode 100644 index f51c4bb..0000000 --- a/nextjs-pages/src/models/local/quiz/localQuizQuestion.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { LocalQuizQuestionAnswer } from "./localQuizQuestionAnswer"; - -export interface LocalQuizQuestion { - text: string; - questionType: QuestionType; - points: number; - answers: LocalQuizQuestionAnswer[]; - matchDistractors: string[]; -} - -export enum QuestionType { - MULTIPLE_ANSWERS = "multiple_answers", - MULTIPLE_CHOICE = "multiple_choice", - ESSAY = "essay", - SHORT_ANSWER = "short_answer", - MATCHING = "matching", - NONE = "", -} diff --git a/nextjs-pages/src/models/local/quiz/localQuizQuestionAnswer.ts b/nextjs-pages/src/models/local/quiz/localQuizQuestionAnswer.ts deleted file mode 100644 index de5850c..0000000 --- a/nextjs-pages/src/models/local/quiz/localQuizQuestionAnswer.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface LocalQuizQuestionAnswer { - correct: boolean; - text: string; - matchedText?: string; -} diff --git a/nextjs-pages/src/models/local/quiz/utils/quizMarkdownUtils.ts b/nextjs-pages/src/models/local/quiz/utils/quizMarkdownUtils.ts deleted file mode 100644 index b7fd661..0000000 --- a/nextjs-pages/src/models/local/quiz/utils/quizMarkdownUtils.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { verifyDateOrThrow, verifyDateStringOrUndefined } from "../../timeUtils"; -import { LocalQuiz } from "../localQuiz"; -import { quizQuestionMarkdownUtils } from "./quizQuestionMarkdownUtils"; - -const extractLabelValue = (input: string, label: string): string => { - const pattern = new RegExp(`${label}: (.*?)\n`); - const match = pattern.exec(input); - return match ? match[1].trim() : ""; -}; - -const extractDescription = (input: string): string => { - const pattern = new RegExp("Description: (.*?)$", "s"); - const match = pattern.exec(input); - return match ? match[1].trim() : ""; -}; - -const parseBooleanOrThrow = (value: string, label: string): boolean => { - if (value.toLowerCase() === "true") return true; - if (value.toLowerCase() === "false") return false; - throw new Error(`Error with ${label}: ${value}`); -}; - -const parseBooleanOrDefault = ( - value: string, - label: string, - defaultValue: boolean -): boolean => { - if (value.toLowerCase() === "true") return true; - if (value.toLowerCase() === "false") return false; - return defaultValue; -}; - -const parseNumberOrThrow = (value: string, label: string): number => { - const parsed = parseInt(value, 10); - if (isNaN(parsed)) { - throw new Error(`Error with ${label}: ${value}`); - } - return parsed; -}; -const getQuizWithOnlySettings = (settings: string): LocalQuiz => { - const name = extractLabelValue(settings, "Name"); - - const rawShuffleAnswers = extractLabelValue(settings, "ShuffleAnswers"); - const shuffleAnswers = parseBooleanOrThrow( - rawShuffleAnswers, - "ShuffleAnswers" - ); - - const password = extractLabelValue(settings, "Password") || undefined; - - const rawShowCorrectAnswers = extractLabelValue( - settings, - "ShowCorrectAnswers" - ); - const showCorrectAnswers = parseBooleanOrDefault( - rawShowCorrectAnswers, - "ShowCorrectAnswers", - true - ); - - const rawOneQuestionAtATime = extractLabelValue( - settings, - "OneQuestionAtATime" - ); - const oneQuestionAtATime = parseBooleanOrThrow( - rawOneQuestionAtATime, - "OneQuestionAtATime" - ); - - const rawAllowedAttempts = extractLabelValue(settings, "AllowedAttempts"); - const allowedAttempts = parseNumberOrThrow( - rawAllowedAttempts, - "AllowedAttempts" - ); - - const rawDueAt = extractLabelValue(settings, "DueAt"); - const dueAt = verifyDateOrThrow(rawDueAt, "DueAt"); - - - const rawLockAt = extractLabelValue(settings, "LockAt"); - const lockAt = verifyDateStringOrUndefined(rawLockAt); - - const description = extractDescription(settings); - const localAssignmentGroupName = extractLabelValue( - settings, - "AssignmentGroup" - ); - - const quiz: LocalQuiz = { - name, - description, - password, - lockAt, - dueAt, - shuffleAnswers, - showCorrectAnswers, - oneQuestionAtATime, - localAssignmentGroupName, - allowedAttempts, - questions: [], - }; - return quiz; -}; - -export const quizMarkdownUtils = { - toMarkdown(quiz: LocalQuiz): string { - const questionMarkdownArray = quiz.questions.map((q) => - quizQuestionMarkdownUtils.toMarkdown(q) - ); - const questionDelimiter = "\n\n---\n\n"; - const questionMarkdown = questionMarkdownArray.join(questionDelimiter); - - return `Name: ${quiz.name} -LockAt: ${quiz.lockAt ?? ""} -DueAt: ${quiz.dueAt} -Password: ${quiz.password ?? ""} -ShuffleAnswers: ${quiz.shuffleAnswers.toString().toLowerCase()} -ShowCorrectAnswers: ${quiz.showCorrectAnswers.toString().toLowerCase()} -OneQuestionAtATime: ${quiz.oneQuestionAtATime.toString().toLowerCase()} -AssignmentGroup: ${quiz.localAssignmentGroupName} -AllowedAttempts: ${quiz.allowedAttempts} -Description: ${quiz.description} ---- -${questionMarkdown}`; - }, - - parseMarkdown(input: string): LocalQuiz { - const splitInput = input.split("---\n"); - const settings = splitInput[0]; - const quizWithoutQuestions = getQuizWithOnlySettings(settings); - - const rawQuestions = splitInput.slice(1); - const questions = rawQuestions - .filter((str) => str.trim().length > 0) - .map((q, i) => quizQuestionMarkdownUtils.parseMarkdown(q, i)); - - return { - ...quizWithoutQuestions, - questions, - }; - }, -}; diff --git a/nextjs-pages/src/models/local/quiz/utils/quizQuestionAnswerMarkdownUtils.ts b/nextjs-pages/src/models/local/quiz/utils/quizQuestionAnswerMarkdownUtils.ts deleted file mode 100644 index cf70862..0000000 --- a/nextjs-pages/src/models/local/quiz/utils/quizQuestionAnswerMarkdownUtils.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { QuestionType } from "../localQuizQuestion"; -import { LocalQuizQuestionAnswer } from "../localQuizQuestionAnswer"; - -export const quizQuestionAnswerMarkdownUtils = { - // getHtmlText(): string { - // return MarkdownService.render(this.text); - // } - - parseMarkdown(input: string, questionType: string): LocalQuizQuestionAnswer { - const isCorrect = input.startsWith("*") || input[1] === "*"; - - if (questionType === QuestionType.MATCHING) { - const matchingPattern = /^\^ ?/; - const textWithoutMatchDelimiter = input - .replace(matchingPattern, "") - .trim(); - const [text, ...matchedParts] = textWithoutMatchDelimiter.split("-"); - const answer: LocalQuizQuestionAnswer = { - correct: true, - text: text.trim(), - matchedText: matchedParts.join("-").trim(), - }; - return answer; - } - - const startingQuestionPattern = /^(\*?[a-z]?\))|\[\s*\]|\[\*\]|\^ /; - - let replaceCount = 0; - const text = input - .replace(startingQuestionPattern, (m) => (replaceCount++ === 0 ? "" : m)) - .trim(); - - const answer: LocalQuizQuestionAnswer = { - correct: isCorrect, - text: text, - }; - return answer; - }, -}; diff --git a/nextjs-pages/src/models/local/quiz/utils/quizQuestionMarkdownUtils.ts b/nextjs-pages/src/models/local/quiz/utils/quizQuestionMarkdownUtils.ts deleted file mode 100644 index 880dcb4..0000000 --- a/nextjs-pages/src/models/local/quiz/utils/quizQuestionMarkdownUtils.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { LocalQuiz } from "../localQuiz"; -import { LocalQuizQuestion, QuestionType } from "../localQuizQuestion"; -import { LocalQuizQuestionAnswer } from "../localQuizQuestionAnswer"; -import { quizQuestionAnswerMarkdownUtils } from "./quizQuestionAnswerMarkdownUtils"; - -const _validFirstAnswerDelimiters = ["*a)", "a)", "*)", ")", "[ ]", "[*]", "^"]; - -const getAnswerStringsWithMultilineSupport = ( - linesWithoutPoints: string[], - questionIndex: number -) => { - const indexOfAnswerStart = linesWithoutPoints.findIndex((l) => - _validFirstAnswerDelimiters.some((prefix) => - l.trimStart().startsWith(prefix) - ) - ); - if (indexOfAnswerStart === -1) { - const debugLine = linesWithoutPoints.find((l) => l.trim().length > 0); - throw Error( - `question ${ - questionIndex + 1 - }: no answers when detecting question type on ${debugLine}` - ); - } - - const answerLinesRaw = linesWithoutPoints.slice(indexOfAnswerStart); - - const answerStartPattern = /^(\*?[a-z]?\))|(? { - const isNewAnswer = answerStartPattern.test(line); - if (isNewAnswer) { - acc.push(line); - } else if (acc.length !== 0) { - acc[acc.length - 1] += "\n" + line; - } else { - acc.push(line); - } - return acc; - }, []); - return answerLines; -}; -const getQuestionType = ( - linesWithoutPoints: string[], - questionIndex: number -): QuestionType => { - if (linesWithoutPoints.length === 0) return QuestionType.NONE; - if ( - linesWithoutPoints[linesWithoutPoints.length - 1].toLowerCase() === "essay" - ) - return QuestionType.ESSAY; - if ( - linesWithoutPoints[linesWithoutPoints.length - 1].toLowerCase() === - "short answer" - ) - return QuestionType.SHORT_ANSWER; - if ( - linesWithoutPoints[linesWithoutPoints.length - 1].toLowerCase() === - "short_answer" - ) - return QuestionType.SHORT_ANSWER; - - const answerLines = getAnswerStringsWithMultilineSupport( - linesWithoutPoints, - questionIndex - ); - const firstAnswerLine = answerLines[0]; - const isMultipleChoice = ["a)", "*a)", "*)", ")"].some((prefix) => - firstAnswerLine.startsWith(prefix) - ); - - if (isMultipleChoice) return QuestionType.MULTIPLE_CHOICE; - - const isMultipleAnswer = ["[ ]", "[*]"].some((prefix) => - firstAnswerLine.startsWith(prefix) - ); - if (isMultipleAnswer) return QuestionType.MULTIPLE_ANSWERS; - - const isMatching = firstAnswerLine.startsWith("^"); - if (isMatching) return QuestionType.MATCHING; - - return QuestionType.NONE; -}; - -const getAnswers = ( - linesWithoutPoints: string[], - questionIndex: number, - questionType: string -): LocalQuizQuestionAnswer[] => { - const answerLines = getAnswerStringsWithMultilineSupport( - linesWithoutPoints, - questionIndex - ); - - const answers = answerLines.map((a, i) => - quizQuestionAnswerMarkdownUtils.parseMarkdown(a, questionType) - ); - return answers; -}; -const getAnswerMarkdown = ( - question: LocalQuizQuestion, - answer: LocalQuizQuestionAnswer, - index: number -): string => { - const multilineMarkdownCompatibleText = answer.text.startsWith("```") - ? "\n" + answer.text - : answer.text; - - if (question.questionType === "multiple_answers") { - const correctIndicator = answer.correct ? "*" : " "; - const questionTypeIndicator = `[${correctIndicator}] `; - - return `${questionTypeIndicator}${multilineMarkdownCompatibleText}`; - } else if (question.questionType === "matching") { - return `^ ${answer.text} - ${answer.matchedText}`; - } else { - const questionLetter = String.fromCharCode(97 + index); - const correctIndicator = answer.correct ? "*" : ""; - const questionTypeIndicator = `${correctIndicator}${questionLetter}) `; - - return `${questionTypeIndicator}${multilineMarkdownCompatibleText}`; - } -}; - -export const quizQuestionMarkdownUtils = { - toMarkdown(question: LocalQuizQuestion): string { - const answerArray = question.answers.map((a, i) => - getAnswerMarkdown(question, a, i) - ); - - const distractorText = - question.questionType === QuestionType.MATCHING - ? question.matchDistractors?.map((d) => `\n^ - ${d}`).join("") ?? "" - : ""; - - const answersText = answerArray.join("\n"); - const questionTypeIndicator = - question.questionType === "essay" || - question.questionType === "short_answer" - ? question.questionType - : ""; - - return `Points: ${question.points}\n${question.text}\n${answersText}${distractorText}${questionTypeIndicator}`; - }, - - parseMarkdown(input: string, questionIndex: number): LocalQuizQuestion { - const lines = input.trim().split("\n"); - const firstLineIsPoints = lines[0].toLowerCase().includes("points: "); - - const textHasPoints = - lines.length > 0 && - lines[0].includes(": ") && - lines[0].split(": ").length > 1 && - !isNaN(parseFloat(lines[0].split(": ")[1])); - - const points = - firstLineIsPoints && textHasPoints - ? parseFloat(lines[0].split(": ")[1]) - : 1; - - const linesWithoutPoints = firstLineIsPoints ? lines.slice(1) : lines; - - const { linesWithoutAnswers } = linesWithoutPoints.reduce( - ({ linesWithoutAnswers, taking }, currentLine) => { - if (!taking) - return { linesWithoutAnswers: linesWithoutAnswers, taking: false }; - - const lineIsAnswer = _validFirstAnswerDelimiters.some((prefix) => - currentLine.trimStart().startsWith(prefix) - ); - if (lineIsAnswer) - return { linesWithoutAnswers: linesWithoutAnswers, taking: false }; - - return { - linesWithoutAnswers: [...linesWithoutAnswers, currentLine], - taking: true, - }; - }, - { linesWithoutAnswers: [] as string[], taking: true } - ); - const questionType = getQuestionType(linesWithoutPoints, questionIndex); - - const questionTypesWithoutAnswers = [ - "essay", - "short answer", - "short_answer", - ]; - - const descriptionLines = questionTypesWithoutAnswers.includes( - questionType.toLowerCase() - ) - ? linesWithoutAnswers - .slice(0, linesWithoutPoints.length) - .filter( - (line, index) => - !questionTypesWithoutAnswers.includes(line.toLowerCase()) - ) - : linesWithoutAnswers; - - const description = descriptionLines.join("\n"); - - const typesWithAnswers = [ - "multiple_choice", - "multiple_answers", - "matching", - ]; - const answers = typesWithAnswers.includes(questionType) - ? getAnswers(linesWithoutPoints, questionIndex, questionType) - : []; - - const answersWithoutDistractors = - questionType === QuestionType.MATCHING - ? answers.filter((a) => a.text) - : answers; - - const distractors = - questionType === QuestionType.MATCHING - ? answers.filter((a) => !a.text).map((a) => a.matchedText ?? "") - : []; - - const question: LocalQuizQuestion = { - text: description, - questionType, - points, - answers: answersWithoutDistractors, - matchDistractors: distractors, - }; - return question; - }, -}; diff --git a/nextjs-pages/src/models/local/tests/assignmentMarkdown.test.ts b/nextjs-pages/src/models/local/tests/assignmentMarkdown.test.ts deleted file mode 100644 index be92620..0000000 --- a/nextjs-pages/src/models/local/tests/assignmentMarkdown.test.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { LocalAssignment } from "../assignment/localAssignment"; -import { AssignmentSubmissionType } from "../assignment/assignmentSubmissionType"; -import { assignmentMarkdownSerializer } from "../assignment/utils/assignmentMarkdownSerializer"; -import { assignmentMarkdownParser } from "../assignment/utils/assignmentMarkdownParser"; - -describe("AssignmentMarkdownTests", () => { - it("can parse assignment settings", () => { - const assignment: LocalAssignment = { - name: "test assignment", - description: "here is the description", - dueAt: "08/21/2023 23:59:00", - lockAt: "08/21/2023 23:59:00", - submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], - localAssignmentGroupName: "Final Project", - rubric: [ - { points: 4, label: "do task 1" }, - { points: 2, label: "do task 2" }, - ], - allowedFileUploadExtensions: [], - }; - - const assignmentMarkdown = - assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown); - - expect(parsedAssignment).toEqual(assignment); - }); - - it("assignment with empty rubric can be parsed", () => { - const assignment: LocalAssignment = { - name: "test assignment", - description: "here is the description", - dueAt: "08/21/2023 23:59:00", - lockAt: "08/21/2023 23:59:00", - submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], - localAssignmentGroupName: "Final Project", - rubric: [], - allowedFileUploadExtensions: [], - }; - - const assignmentMarkdown = - assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown); - - expect(parsedAssignment).toEqual(assignment); - }); - - it("assignment with empty submission types can be parsed", () => { - const assignment: LocalAssignment = { - name: "test assignment", - description: "here is the description", - dueAt: "08/21/2023 23:59:00", - lockAt: "08/21/2023 23:59:00", - submissionTypes: [], - localAssignmentGroupName: "Final Project", - rubric: [ - { points: 4, label: "do task 1" }, - { points: 2, label: "do task 2" }, - ], - allowedFileUploadExtensions: [], - }; - - const assignmentMarkdown = - assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown); - - expect(parsedAssignment).toEqual(assignment); - }); - - it("assignment without lockAt date can be parsed", () => { - const assignment: LocalAssignment = { - name: "test assignment", - description: "here is the description", - dueAt: "08/21/2023 23:59:00", - lockAt: undefined, - submissionTypes: [], - localAssignmentGroupName: "Final Project", - rubric: [ - { points: 4, label: "do task 1" }, - { points: 2, label: "do task 2" }, - ], - allowedFileUploadExtensions: [], - }; - - const assignmentMarkdown = - assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown); - - expect(parsedAssignment).toEqual(assignment); - }); - - it("assignment without description can be parsed", () => { - const assignment: LocalAssignment = { - name: "test assignment", - description: "", - dueAt: "08/21/2023 23:59:00", - lockAt: "08/21/2023 23:59:00", - submissionTypes: [], - localAssignmentGroupName: "Final Project", - rubric: [ - { points: 4, label: "do task 1" }, - { points: 2, label: "do task 2" }, - ], - allowedFileUploadExtensions: [], - }; - - const assignmentMarkdown = - assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown); - - expect(parsedAssignment).toEqual(assignment); - }); - - it("assignments can have three dashes", () => { - const assignment: LocalAssignment = { - name: "test assignment", - description: "test assignment\n---\nsomestuff", - dueAt: "08/21/2023 23:59:00", - lockAt: "08/21/2023 23:59:00", - submissionTypes: [], - localAssignmentGroupName: "Final Project", - rubric: [], - allowedFileUploadExtensions: [], - }; - - const assignmentMarkdown = - assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown); - - expect(parsedAssignment).toEqual(assignment); - }); - - it("assignments can restrict upload types", () => { - const assignment: LocalAssignment = { - name: "test assignment", - description: "here is the description", - dueAt: "08/21/2023 23:59:00", - lockAt: "08/21/2023 23:59:00", - submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], - allowedFileUploadExtensions: ["pdf", "txt"], - localAssignmentGroupName: "Final Project", - rubric: [], - }; - - const assignmentMarkdown = - assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown); - - expect(parsedAssignment).toEqual(assignment); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/pageMarkdown.test.ts b/nextjs-pages/src/models/local/tests/pageMarkdown.test.ts deleted file mode 100644 index 20611b7..0000000 --- a/nextjs-pages/src/models/local/tests/pageMarkdown.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { LocalCoursePage, localPageMarkdownUtils } from "../page/localCoursePage"; - -describe("PageMarkdownTests", () => { - it("can parse page", () => { - const page: LocalCoursePage = { - name: "test title", - text: "test text content", - dueAt: "07/09/2024 23:59:00", - }; - - const pageMarkdownString = localPageMarkdownUtils.toMarkdown(page); - - const parsedPage = localPageMarkdownUtils.parseMarkdown(pageMarkdownString); - - expect(parsedPage).toEqual(page); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/quizMarkdown/matchingAnswers.test.ts b/nextjs-pages/src/models/local/tests/quizMarkdown/matchingAnswers.test.ts deleted file mode 100644 index 821c7dc..0000000 --- a/nextjs-pages/src/models/local/tests/quizMarkdown/matchingAnswers.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { QuestionType } from "../../quiz/localQuizQuestion"; -import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; -import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; - -describe("MatchingTests", () => { - it("can parse matching question", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: ---- -Match the following terms & definitions - -^ statement - a single command to be executed -^ identifier - name of a variable -^ keyword - reserved word that has special meaning in a program (e.g. class, void, static, etc.) -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - - expect(firstQuestion.questionType).toBe(QuestionType.MATCHING); - expect(firstQuestion.text).not.toContain("statement"); - expect(firstQuestion.answers[0].matchedText).toBe( - "a single command to be executed" - ); - }); - - it("can create markdown for matching question", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: ---- -Match the following terms & definitions - -^ statement - a single command to be executed -^ identifier - name of a variable -^ keyword - reserved word that has special meaning in a program (e.g. class, void, static, etc.) -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const questionMarkdown = quizQuestionMarkdownUtils.toMarkdown( - quiz.questions[0] - ); - const expectedMarkdown = `Points: 1 -Match the following terms & definitions - -^ statement - a single command to be executed -^ identifier - name of a variable -^ keyword - reserved word that has special meaning in a program (e.g. class, void, static, etc.)`; - - expect(questionMarkdown).toContain(expectedMarkdown); - }); - - it("whitespace is optional", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: ---- -Match the following terms & definitions - -^statement - a single command to be executed -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - expect(quiz.questions[0].answers[0].text).toBe("statement"); - }); - - it("can have distractors", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: ---- -Match the following terms & definitions - -^ statement - a single command to be executed -^ - this is the distractor -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - expect(quiz.questions[0].matchDistractors).toEqual([ - "this is the distractor", - ]); - }); - - it("can have distractors and be persisted", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: ---- -Match the following terms & definitions - -^ statement - a single command to be executed -^ - this is the distractor -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - - expect(quizMarkdown).toContain( - "^ statement - a single command to be executed\n^ - this is the distractor" - ); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/quizMarkdown/multipleAnswers.test.ts b/nextjs-pages/src/models/local/tests/quizMarkdown/multipleAnswers.test.ts deleted file mode 100644 index 2693b4a..0000000 --- a/nextjs-pages/src/models/local/tests/quizMarkdown/multipleAnswers.test.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { LocalQuiz } from "../../quiz/localQuiz"; -import { QuestionType } from "../../quiz/localQuizQuestion"; -import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; -import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; - -describe("MultipleAnswersTests", () => { - it("quiz markdown includes multiple answer question", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "desc", - dueAt: "08/21/2023 23:59:00", - lockAt: "08/21/2023 23:59:00", - shuffleAnswers: true, - oneQuestionAtATime: false, - showCorrectAnswers: false, - localAssignmentGroupName: "someId", - allowedAttempts: -1, - questions: [ - { - text: "oneline question", - points: 1, - questionType: QuestionType.MULTIPLE_ANSWERS, - answers: [ - { correct: true, text: "true" }, - { correct: true, text: "false" }, - { correct: false, text: "neither" }, - ], - matchDistractors: [], - }, - ], - }; - - const markdown = quizMarkdownUtils.toMarkdown(quiz); - const expectedQuestionString = `Points: 1 -oneline question -[*] true -[*] false -[ ] neither`; - expect(markdown).toContain(expectedQuestionString); - }); - - it("can parse question with multiple answers", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Which events are triggered when the user clicks on an input field? -[*] click -[*] focus -[*] mousedown -[ ] submit -[ ] change -[ ] mouseout -[ ] keydown ---- -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - - expect(firstQuestion.points).toBe(1); - expect(firstQuestion.questionType).toBe(QuestionType.MULTIPLE_ANSWERS); - expect(firstQuestion.text).toContain( - "Which events are triggered when the user clicks on an input field?" - ); - expect(firstQuestion.answers[0].text).toBe("click"); - expect(firstQuestion.answers[0].correct).toBe(true); - expect(firstQuestion.answers[3].correct).toBe(false); - expect(firstQuestion.answers[3].text).toBe("submit"); - }); - - it("can use braces in answer for multiple answer", () => { - const rawMarkdownQuestion = ` -Which events are triggered when the user clicks on an input field? -[*] \`int[] theThing()\` -[ ] keydown -`; - - const question = quizQuestionMarkdownUtils.parseMarkdown( - rawMarkdownQuestion, - 0 - ); - - expect(question.answers[0].text).toBe("`int[] theThing()`"); - expect(question.answers.length).toBe(2); - }); - - it("can use braces in answer for multiple answer with multiline", () => { - const rawMarkdownQuestion = ` -Which events are triggered when the user clicks on an input field? -[*] -\`\`\` -int[] myNumbers = new int[] { }; -DoSomething(ref myNumbers); -static void DoSomething(ref int[] numbers) -{ - // do something -} -\`\`\` -`; - - const question = quizQuestionMarkdownUtils.parseMarkdown( - rawMarkdownQuestion, - 0 - ); - - expect(question.answers[0].text).toBe(`\`\`\` -int[] myNumbers = new int[] { }; -DoSomething(ref myNumbers); -static void DoSomething(ref int[] numbers) -{ - // do something -} -\`\`\``); - expect(question.answers.length).toBe(1); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/quizMarkdown/multipleChoice.test.ts b/nextjs-pages/src/models/local/tests/quizMarkdown/multipleChoice.test.ts deleted file mode 100644 index 2d4936f..0000000 --- a/nextjs-pages/src/models/local/tests/quizMarkdown/multipleChoice.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { LocalQuiz } from "../../quiz/localQuiz"; -import { LocalQuizQuestion, QuestionType } from "../../quiz/localQuizQuestion"; -import { LocalQuizQuestionAnswer } from "../../quiz/localQuizQuestionAnswer"; -import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; -import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; - -describe("MultipleChoiceTests", () => { - it("quiz markdown includes multiple choice question", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "desc", - dueAt: "08/21/2023 23:59:00", - lockAt: "08/21/2023 23:59:00", - shuffleAnswers: true, - oneQuestionAtATime: false, - showCorrectAnswers: false, - localAssignmentGroupName: "someId", - allowedAttempts: -1, - questions: [ - { - points: 2, - text: ` -\`some type\` of question - -with many - -\`\`\` -lines -\`\`\` -`, - questionType: QuestionType.MULTIPLE_CHOICE, - answers: [ - { correct: true, text: "true" }, - { correct: false, text: "false\n\nendline" }, - ], - matchDistractors: [], - }, - ], - }; - - const markdown = quizMarkdownUtils.toMarkdown(quiz); - const expectedQuestionString = ` -Points: 2 - -\`some type\` of question - -with many - -\`\`\` -lines -\`\`\` - -*a) true -b) false - -endline`; - expect(markdown).toContain(expectedQuestionString); - }); - - it("letter optional for multiple choice", () => { - const questionMarkdown = ` -Points: 2 -\`some type\` of question -*) true -) false -`; - - const question = quizQuestionMarkdownUtils.parseMarkdown( - questionMarkdown, - 0 - ); - expect(question.answers.length).toBe(2); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/quizMarkdown/quizDeterministicChecks.test.ts b/nextjs-pages/src/models/local/tests/quizMarkdown/quizDeterministicChecks.test.ts deleted file mode 100644 index 01b62f5..0000000 --- a/nextjs-pages/src/models/local/tests/quizMarkdown/quizDeterministicChecks.test.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { LocalQuiz } from "../../quiz/localQuiz"; -import { quizMarkdownUtils } from "../../quiz/utils/quizMarkdownUtils"; -import { QuestionType } from "@/models/local/quiz/localQuizQuestion"; - -// Test suite for deterministic checks on LocalQuiz -describe("QuizDeterministicChecks", () => { - it("SerializationIsDeterministic_EmptyQuiz", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "quiz description", - lockAt: "08/21/2023 23:59:00", - dueAt: "08/21/2023 23:59:00", - shuffleAnswers: true, - oneQuestionAtATime: true, - localAssignmentGroupName: "Assignments", - questions: [], - allowedAttempts: -1, - showCorrectAnswers: true, - }; - - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - const parsedQuiz = quizMarkdownUtils.parseMarkdown(quizMarkdown); - - expect(parsedQuiz).toEqual(quiz); - }); - - it("SerializationIsDeterministic_ShowCorrectAnswers", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "quiz description", - lockAt: "08/21/2023 23:59:00", - dueAt: "08/21/2023 23:59:00", - showCorrectAnswers: false, - shuffleAnswers: true, - oneQuestionAtATime: true, - localAssignmentGroupName: "Assignments", - questions: [], - allowedAttempts: -1, - }; - - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - const parsedQuiz = quizMarkdownUtils.parseMarkdown(quizMarkdown); - - expect(parsedQuiz).toEqual(quiz); - }); - - it("SerializationIsDeterministic_ShortAnswer", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "quiz description", - lockAt: "08/21/2023 23:59:00", - dueAt: "08/21/2023 23:59:00", - shuffleAnswers: true, - oneQuestionAtATime: true, - localAssignmentGroupName: "Assignments", - questions: [ - { - text: "test short answer", - questionType: QuestionType.SHORT_ANSWER, - points: 1, - answers: [], - matchDistractors: [], - }, - ], - allowedAttempts: -1, - showCorrectAnswers: true, - }; - - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - const parsedQuiz = quizMarkdownUtils.parseMarkdown(quizMarkdown); - - expect(parsedQuiz).toEqual(quiz); - }); - - it("SerializationIsDeterministic_Essay", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "quiz description", - lockAt: "08/21/2023 23:59:00", - dueAt: "08/21/2023 23:59:00", - shuffleAnswers: true, - oneQuestionAtATime: true, - localAssignmentGroupName: "Assignments", - questions: [ - { - text: "test essay", - questionType: QuestionType.ESSAY, - points: 1, - matchDistractors: [], - answers: [], - }, - ], - allowedAttempts: -1, - showCorrectAnswers: true, - }; - - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - const parsedQuiz = quizMarkdownUtils.parseMarkdown(quizMarkdown); - - expect(parsedQuiz).toEqual(quiz); - }); - - it("SerializationIsDeterministic_MultipleAnswer", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "quiz description", - lockAt: "08/21/2023 23:59:00", - dueAt: "08/21/2023 23:59:00", - shuffleAnswers: true, - oneQuestionAtATime: true, - localAssignmentGroupName: "Assignments", - questions: [ - { - text: "test multiple answer", - questionType: QuestionType.MULTIPLE_ANSWERS, - points: 1, - matchDistractors: [], - answers: [ - { text: "yes", correct: true }, - { text: "no", correct: true }, - ], - }, - ], - allowedAttempts: -1, - showCorrectAnswers: true, - }; - - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - const parsedQuiz = quizMarkdownUtils.parseMarkdown(quizMarkdown); - - expect(parsedQuiz).toEqual(quiz); - }); - - it("SerializationIsDeterministic_MultipleChoice", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "quiz description", - lockAt: "08/21/2023 23:59:00", - dueAt: "08/21/2023 23:59:00", - shuffleAnswers: true, - oneQuestionAtATime: true, - password: undefined, - localAssignmentGroupName: "Assignments", - questions: [ - { - text: "test multiple choice", - questionType: QuestionType.MULTIPLE_CHOICE, - points: 1, - matchDistractors: [], - answers: [ - { text: "yes", correct: true }, - { text: "no", correct: false }, - ], - }, - ], - allowedAttempts: -1, - showCorrectAnswers: true, - }; - - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - const parsedQuiz = quizMarkdownUtils.parseMarkdown(quizMarkdown); - - expect(parsedQuiz).toEqual(quiz); - }); - - it("SerializationIsDeterministic_Matching", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: "quiz description", - lockAt: "08/21/2023 23:59:00", - dueAt: "08/21/2023 23:59:00", - shuffleAnswers: true, - oneQuestionAtATime: true, - password: undefined, - localAssignmentGroupName: "Assignments", - questions: [ - { - text: "test matching", - questionType: QuestionType.MATCHING, - points: 1, - matchDistractors: [], - answers: [ - { text: "yes", correct: true, matchedText: "testing yes" }, - { text: "no", correct: true, matchedText: "testing no" }, - ], - }, - ], - allowedAttempts: -1, - showCorrectAnswers: true, - }; - - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - const parsedQuiz = quizMarkdownUtils.parseMarkdown(quizMarkdown); - - expect(parsedQuiz).toEqual(quiz); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/quizMarkdown/quizMarkdown.test.ts b/nextjs-pages/src/models/local/tests/quizMarkdown/quizMarkdown.test.ts deleted file mode 100644 index 79d35f7..0000000 --- a/nextjs-pages/src/models/local/tests/quizMarkdown/quizMarkdown.test.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { LocalQuiz } from "../../quiz/localQuiz"; -import { quizMarkdownUtils } from "../../quiz/utils/quizMarkdownUtils"; -import { QuestionType } from "@/models/local/quiz/localQuizQuestion"; -import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; - -// Test suite for QuizMarkdown -describe("QuizMarkdownTests", () => { - it("can serialize quiz to markdown", () => { - const quiz: LocalQuiz = { - name: "Test Quiz", - description: ` -# quiz description - -this is my description in markdown - -\`here is code\` -`, - lockAt: new Date(8640000000000000).toISOString(), // DateTime.MaxValue equivalent in TypeScript - dueAt: new Date(8640000000000000).toISOString(), - shuffleAnswers: true, - oneQuestionAtATime: false, - localAssignmentGroupName: "someId", - allowedAttempts: -1, - showCorrectAnswers: false, - questions: [], - }; - - const markdown = quizMarkdownUtils.toMarkdown(quiz); - - expect(markdown).toContain("Name: Test Quiz"); - expect(markdown).toContain(quiz.description); - expect(markdown).toContain("ShuffleAnswers: true"); - expect(markdown).toContain("OneQuestionAtATime: false"); - expect(markdown).toContain("AssignmentGroup: someId"); - expect(markdown).toContain("AllowedAttempts: -1"); - }); - - it("can parse markdown quiz with no questions", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - - const expectedDescription = ` -this is the -multi line -description`; - - expect(quiz.name).toBe("Test Quiz"); - expect(quiz.shuffleAnswers).toBe(true); - expect(quiz.oneQuestionAtATime).toBe(false); - expect(quiz.allowedAttempts).toBe(-1); - expect(quiz.description.trim()).toBe(expectedDescription.trim()); - }); - - it("can parse markdown quiz with password", () => { - const password = "this-is-the-password"; - const rawMarkdownQuiz = ` -Name: Test Quiz -Password: ${password} -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - - expect(quiz.password).toBe(password); - }); - - it("can parse markdown quiz and configure to show correct answers", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -ShowCorrectAnswers: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - - expect(quiz.showCorrectAnswers).toBe(false); - }); - - it("can parse quiz with questions", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Points: 2 -\`some type\` of question - -with many - -\`\`\` -lines -\`\`\` - -*a) true -b) false - - endline`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - - expect(firstQuestion.questionType).toBe(QuestionType.MULTIPLE_CHOICE); - expect(firstQuestion.points).toBe(2); - expect(firstQuestion.text).toContain("```"); - expect(firstQuestion.text).toContain("`some type` of question"); - expect(firstQuestion.answers[0].text).toBe("true"); - expect(firstQuestion.answers[0].correct).toBe(true); - expect(firstQuestion.answers[1].correct).toBe(false); - expect(firstQuestion.answers[1].text).toContain("endline"); - }); - - it("can parse multiple questions", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Which events are triggered when the user clicks on an input field? -[*] click ---- -Points: 2 -\`some type\` of question -*a) true -b) false -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - expect(firstQuestion.points).toBe(1); - expect(firstQuestion.questionType).toBe(QuestionType.MULTIPLE_ANSWERS); - - const secondQuestion = quiz.questions[1]; - expect(secondQuestion.points).toBe(2); - expect(secondQuestion.questionType).toBe(QuestionType.MULTIPLE_CHOICE); - }); - - it("short answer to markdown is correct", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Which events are triggered when the user clicks on an input field? -short answer -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - - const questionMarkdown = - quizQuestionMarkdownUtils.toMarkdown(firstQuestion); - const expectedMarkdown = `Points: 1 -Which events are triggered when the user clicks on an input field? -short_answer`; - expect(questionMarkdown).toContain(expectedMarkdown); - }); - - it("negative points is allowed", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Points: -4 -Which events are triggered when the user clicks on an input field? -short answer -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - expect(firstQuestion.points).toBe(-4); - }); - - it("floating point points is allowed", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Points: 4.56 -Which events are triggered when the user clicks on an input field? -short answer -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - expect(firstQuestion.points).toBe(4.56); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/quizMarkdown/testAnswer.test.ts b/nextjs-pages/src/models/local/tests/quizMarkdown/testAnswer.test.ts deleted file mode 100644 index 3f3e270..0000000 --- a/nextjs-pages/src/models/local/tests/quizMarkdown/testAnswer.test.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { QuestionType } from "../../quiz/localQuizQuestion"; -import { quizMarkdownUtils } from "../../quiz/utils/quizMarkdownUtils"; -import { quizQuestionMarkdownUtils } from "../../quiz/utils/quizQuestionMarkdownUtils"; -import { describe, it, expect } from "vitest"; - -describe("TextAnswerTests", () => { - it("can parse essay", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Which events are triggered when the user clicks on an input field? -essay -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - - expect(firstQuestion.points).toBe(1); - expect(firstQuestion.questionType).toBe(QuestionType.ESSAY); - expect(firstQuestion.text).not.toContain("essay"); - }); - - it("can parse short answer", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Which events are triggered when the user clicks on an input field? -short answer -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - - expect(firstQuestion.points).toBe(1); - expect(firstQuestion.questionType).toBe(QuestionType.SHORT_ANSWER); - expect(firstQuestion.text).not.toContain("short answer"); - }); - - it("short answer to markdown is correct", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Which events are triggered when the user clicks on an input field? -short answer -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - - const questionMarkdown = - quizQuestionMarkdownUtils.toMarkdown(firstQuestion); - const expectedMarkdown = `Points: 1 -Which events are triggered when the user clicks on an input field? -short_answer`; - expect(questionMarkdown).toContain(expectedMarkdown); - }); - - it("essay question to markdown is correct", () => { - const rawMarkdownQuiz = ` -Name: Test Quiz -ShuffleAnswers: true -OneQuestionAtATime: false -DueAt: 08/21/2023 23:59:00 -LockAt: 08/21/2023 23:59:00 -AssignmentGroup: Assignments -AllowedAttempts: -1 -Description: this is the -multi line -description ---- -Which events are triggered when the user clicks on an input field? -essay -`; - - const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz); - const firstQuestion = quiz.questions[0]; - - const questionMarkdown = - quizQuestionMarkdownUtils.toMarkdown(firstQuestion); - const expectedMarkdown = `Points: 1 -Which events are triggered when the user clicks on an input field? -essay`; - expect(questionMarkdown).toContain(expectedMarkdown); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/rubricMarkdown.test.ts b/nextjs-pages/src/models/local/tests/rubricMarkdown.test.ts deleted file mode 100644 index 5e6e2f5..0000000 --- a/nextjs-pages/src/models/local/tests/rubricMarkdown.test.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { RubricItem, rubricItemIsExtraCredit } from "../assignment/rubricItem"; -import { assignmentMarkdownParser } from "../assignment/utils/assignmentMarkdownParser"; - -describe("RubricMarkdownTests", () => { - it("can parse one item", () => { - const rawRubric = ` - - 2pts: this is the task - `; - - const rubric: RubricItem[] = - assignmentMarkdownParser.parseRubricMarkdown(rawRubric); - expect(rubric.length).toBe(1); - expect(rubricItemIsExtraCredit(rubric[0])).toBe(false); - expect(rubric[0].label).toBe("this is the task"); - expect(rubric[0].points).toBe(2); - }); - - it("can parse multiple items", () => { - const rawRubric = ` - - 2pts: this is the task - - 3pts: this is the other task - `; - - const rubric: RubricItem[] = - assignmentMarkdownParser.parseRubricMarkdown(rawRubric); - expect(rubric.length).toBe(2); - expect(rubricItemIsExtraCredit(rubric[0])).toBe(false); - expect(rubric[1].label).toBe("this is the other task"); - expect(rubric[1].points).toBe(3); - }); - - it("can parse single point", () => { - const rawRubric = ` - - 1pt: this is the task - `; - - const rubric: RubricItem[] = - assignmentMarkdownParser.parseRubricMarkdown(rawRubric); - - expect(rubricItemIsExtraCredit(rubric[0])).toBe(false); - expect(rubric[0].label).toBe("this is the task"); - expect(rubric[0].points).toBe(1); - }); - - it("can parse single extra credit (lower case)", () => { - const rawRubric = ` - - 1pt: (extra credit) this is the task - `; - - const rubric: RubricItem[] = - assignmentMarkdownParser.parseRubricMarkdown(rawRubric); - expect(rubricItemIsExtraCredit(rubric[0])).toBe(true); - expect(rubric[0].label).toBe("(extra credit) this is the task"); - }); - - it("can parse single extra credit (upper case)", () => { - const rawRubric = ` - - 1pt: (Extra Credit) this is the task - `; - - const rubric: RubricItem[] = - assignmentMarkdownParser.parseRubricMarkdown(rawRubric); - expect(rubricItemIsExtraCredit(rubric[0])).toBe(true); - expect(rubric[0].label).toBe("(Extra Credit) this is the task"); - }); - - it("can parse floating point numbers", () => { - const rawRubric = ` - - 1.5pt: this is the task - `; - - const rubric: RubricItem[] = - assignmentMarkdownParser.parseRubricMarkdown(rawRubric); - expect(rubric[0].points).toBe(1.5); - }); - - it("can parse negative numbers", () => { - const rawRubric = ` - - -2pt: this is the task - `; - - const rubric: RubricItem[] = - assignmentMarkdownParser.parseRubricMarkdown(rawRubric); - expect(rubric[0].points).toBe(-2); - }); - - it("can parse negative floating point numbers", () => { - const rawRubric = ` - - -2895.00053pt: this is the task - `; - - const rubric: RubricItem[] = - assignmentMarkdownParser.parseRubricMarkdown(rawRubric); - expect(rubric[0].points).toBe(-2895.00053); - }); -}); diff --git a/nextjs-pages/src/models/local/tests/timeUtils.test.ts b/nextjs-pages/src/models/local/tests/timeUtils.test.ts deleted file mode 100644 index 7308cfd..0000000 --- a/nextjs-pages/src/models/local/tests/timeUtils.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { dateToMarkdownString, getDateFromString } from "../timeUtils"; - -describe("Can properly handle expected date formats", () => { - it("can use AM/PM dates", () => { - const dateString = "8/27/2024 1:00:00 AM"; - const dateObject = getDateFromString(dateString); - expect(dateObject).not.toBeUndefined(); - }); - it("can use 24 hour dates", () => { - const dateString = "8/27/2024 23:95:00"; - const dateObject = getDateFromString(dateString); - expect(dateObject).not.toBeUndefined(); - }); - it("can use ISO format", () => { - const dateString = "2024-08-26T00:00:00.0000000"; - const dateObject = getDateFromString(dateString); - expect(dateObject).not.toBeUndefined(); - }); - it("can get correct time from format", () => { - const dateString = "08/28/2024 23:59:00"; - const dateObject = getDateFromString(dateString); - - expect(dateObject?.getDate()).toBe(28); - expect(dateObject?.getMonth()).toBe(8 - 1); // 0 based - expect(dateObject?.getFullYear()).toBe(2024); - expect(dateObject?.getMinutes()).toBe(59); - expect(dateObject?.getHours()).toBe(23); - expect(dateObject?.getSeconds()).toBe(0); - }); - it("can get correct time from format", () => { - const dateString = "8/27/2024 1:00:00 AM"; - const dateObject = getDateFromString(dateString); - - expect(dateObject?.getDate()).toBe(27); - expect(dateObject?.getMonth()).toBe(8 - 1); // 0 based - expect(dateObject?.getFullYear()).toBe(2024); - expect(dateObject?.getMinutes()).toBe(0); - expect(dateObject?.getHours()).toBe(1); - expect(dateObject?.getSeconds()).toBe(0); - }); - it("can get correct time from format", () => { - const dateString = "08/27/2024 23:59:00"; - const dateObject = getDateFromString(dateString); - - expect(dateObject).not.toBeUndefined() - const updatedString = dateToMarkdownString(dateObject!) - expect(updatedString).toBe(dateString) - }); -}); diff --git a/nextjs-pages/src/models/local/timeUtils.ts b/nextjs-pages/src/models/local/timeUtils.ts deleted file mode 100644 index c32b936..0000000 --- a/nextjs-pages/src/models/local/timeUtils.ts +++ /dev/null @@ -1,93 +0,0 @@ -const _getDateFromAMPM = ( - datePart: string, - timePartWithMeridian: string -): Date | undefined => { - const [month, day, year] = datePart.split("/").map(Number); - const [timePart, meridian] = timePartWithMeridian.split(" "); - const [hours, minutes, seconds] = timePart.split(":").map(Number); - - let adjustedHours = hours; - if (meridian) { - const upperMeridian = meridian.toUpperCase(); - if (upperMeridian === "PM" && hours < 12) { - adjustedHours += 12; - } else if (upperMeridian === "AM" && hours === 12) { - adjustedHours = 0; - } - } - - const date = new Date(year, month - 1, day, adjustedHours, minutes, seconds); - return isNaN(date.getTime()) ? undefined : date; -}; - -const _getDateFromMilitary = ( - datePart: string, - timePart: string -): Date | undefined => { - const [month, day, year] = datePart.split("/").map(Number); - const [hours, minutes, seconds] = timePart.split(":").map(Number); - - const date = new Date(year, month - 1, day, hours, minutes, seconds); - return isNaN(date.getTime()) ? undefined : date; -}; - -const _getDateFromISO = (value: string): Date | undefined => { - const date = new Date(value); - return isNaN(date.getTime()) ? undefined : date; -}; - -export const getDateFromString = (value: string): Date | undefined => { - const ampmDateRegex = - /^\d{1,2}\/\d{1,2}\/\d{4} \d{1,2}:\d{2}:\d{2}\s{1}[APap][Mm]$/; //"M/D/YYYY h:mm:ss AM/PM" - const militaryDateRegex = /^\d{1,2}\/\d{1,2}\/\d{4} \d{1,2}:\d{2}:\d{2}$/; //"MM/DD/YYYY HH:mm:ss" - const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)$/; //"2024-08-26T00:00:00.0000000" - - if (isoDateRegex.test(value)) { - return _getDateFromISO(value); - } else if (ampmDateRegex.test(value)) { - const [datePart, timePartWithMeridian] = value.split(/[\s\u202F]+/); - return _getDateFromAMPM(datePart, timePartWithMeridian); - } else if (militaryDateRegex.test(value)) { - const [datePart, timePart] = value.split(" "); - return _getDateFromMilitary(datePart, timePart); - } else { - console.log("invalid date format", value); - return undefined; - } -}; - -export const getDateFromStringOrThrow = ( - value: string, - labelForError: string -): Date => { - const d = getDateFromString(value); - if (!d) throw Error(`Invalid date format for ${labelForError}, ${value}`); - return d; -}; - -export const verifyDateStringOrUndefined = ( - value: string -): string | undefined => { - const date = getDateFromString(value); - return date ? dateToMarkdownString(date) : undefined; -}; - -export const verifyDateOrThrow = ( - value: string, - labelForError: string -): string => { - const myDate = getDateFromString(value); - if (!myDate) throw new Error(`Invalid format for ${labelForError}: ${value}`); - return dateToMarkdownString(myDate); -}; - -export const dateToMarkdownString = (date: Date) => { - const stringDay = String(date.getDate()).padStart(2, "0"); - const stringMonth = String(date.getMonth() + 1).padStart(2, "0"); // Months are zero-based - const stringYear = date.getFullYear(); - const stringHours = String(date.getHours()).padStart(2, "0"); - const stringMinutes = String(date.getMinutes()).padStart(2, "0"); - const stringSeconds = String(date.getSeconds()).padStart(2, "0"); - - return `${stringMonth}/${stringDay}/${stringYear} ${stringHours}:${stringMinutes}:${stringSeconds}`; -}; diff --git a/nextjs-pages/src/pages/_app.tsx b/nextjs-pages/src/pages/_app.tsx deleted file mode 100644 index 7b059eb..0000000 --- a/nextjs-pages/src/pages/_app.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import Providers from "@/components/providers"; -import "@/styles/globals.css"; -import type { AppProps } from "next/app"; -import { Suspense } from "react"; - -export default function App({ Component, pageProps }: AppProps) { - return ( - - - - - - ); -} diff --git a/nextjs-pages/src/pages/_document.tsx b/nextjs-pages/src/pages/_document.tsx deleted file mode 100644 index a9af0d1..0000000 --- a/nextjs-pages/src/pages/_document.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Html, Head, Main, NextScript } from "next/document"; - -export default function Document() { - return ( - - - -
    - - - - ); -} diff --git a/nextjs-pages/src/pages/api/hello.ts b/nextjs-pages/src/pages/api/hello.ts deleted file mode 100644 index ea77e8f..0000000 --- a/nextjs-pages/src/pages/api/hello.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from "next"; - -type Data = { - name: string; -}; - -export default function handler( - req: NextApiRequest, - res: NextApiResponse, -) { - res.status(200).json({ name: "John Doe" }); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/index.tsx b/nextjs-pages/src/pages/course/[courseName]/index.tsx deleted file mode 100644 index 91aeb62..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/index.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import CourseContextProvider from "@/components/contexts/CourseContextProvider"; -import DraggingContextProvider from "@/components/contexts/DraggingContextProvider"; -import CourseCalendar from "@/components/courses/calendar/CourseCalendar"; -import CourseSettings from "@/components/courses/CourseSettings"; -import ModuleList from "@/components/modules/ModuleList"; -import { getQueryClient } from "@/components/providersQueryClientUtils"; -import { undefinedWithNull } from "@/components/undefinedToNull"; -import { hydrateCourse } from "@/hooks/hookHydration"; -import { - dehydrate, - DehydratedState, - HydrationBoundary, -} from "@tanstack/react-query"; -import { useRouter } from "next/router"; -import { GetServerSideProps } from "next/types"; -import React, { Suspense } from "react"; - -export const getServerSideProps: GetServerSideProps< - { dehydratedState: DehydratedState }, - { - courseName: string; - } -> = async ({ params }) => { - const queryClient = getQueryClient(); - if (!params) { - const dehydratedState = undefinedWithNull(dehydrate(queryClient)); - return { props: { dehydratedState } }; - } - const courseName = params?.courseName; - const decodedCourseName = decodeURIComponent(courseName); - await hydrateCourse(queryClient, decodedCourseName); - const dehydratedState = undefinedWithNull(dehydrate(queryClient)); - - return { props: { dehydratedState } }; -}; - -export default function CourseDetails({ - dehydratedState, -}: { - dehydratedState: DehydratedState; -}) { - const router = useRouter(); - const decodedCourseName = decodeURIComponent( - router.query?.courseName as string - ); - if (decodedCourseName.includes(".js.map")) { - console.log("cannot load course that is .js.map " + decodedCourseName); - return
    ; - } - - return ( - - - -
    - -
    - -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    - ); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/index.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/index.tsx deleted file mode 100644 index fec4b8b..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import EditAssignment from "@/components/modules/assignments/EditAssignment"; -import { useRouter } from "next/router"; -import React from "react"; - -export default function Page() { - const router = useRouter(); - const decodedAssignmentName = decodeURIComponent( - router.query?.assignmentName as string - ); - const decodedModuleName = decodeURIComponent( - router.query?.moduleName as string - ); - - return ( - - ); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/EditPage.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/EditPage.tsx deleted file mode 100644 index 136b9a1..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/EditPage.tsx +++ /dev/null @@ -1,40 +0,0 @@ -"use client"; - -import { MonacoEditor } from "@/components/editor/MonacoEditor"; -import { usePageQuery } from "@/hooks/localCourse/pageHooks"; -import { localPageMarkdownUtils } from "@/models/local/page/localCoursePage"; -import { useState } from "react"; -import PagePreview from "./PagePreview"; - -export default function EditPage({ - moduleName, - pageName, -}: { - pageName: string; - moduleName: string; -}) { - const { data: page } = usePageQuery(moduleName, pageName); - const [pageText, setPageText] = useState( - localPageMarkdownUtils.toMarkdown(page) - ); - const [error, setError] = useState(""); - - return ( -
    -
    -
    - -
    -
    -
    {error && error}
    - -
    -
    -
    - -
    -
    - ); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/PagePreview.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/PagePreview.tsx deleted file mode 100644 index 8f06b50..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/PagePreview.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { LocalCoursePage } from "@/models/local/page/localCoursePage"; -import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils"; -import React from "react"; - -export default function PagePreview({ page }: { page: LocalCoursePage }) { - return ( -
    - ); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/layout.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/layout.tsx deleted file mode 100644 index 1736e6e..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/layout.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import React, { ReactNode, Suspense } from "react"; - -export default function layout({ children }: { children: ReactNode }) { - return {children}; -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/loading.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/loading.tsx deleted file mode 100644 index 858e083..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/loading.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { Spinner } from "@/components/Spinner"; -import React from "react"; - -export default function Loading() { - return ( -
    - -
    - ); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/page.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/page.tsx deleted file mode 100644 index aaa1205..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/page/[pageName]/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; -import EditPage from "./EditPage"; - -export default async function Page({ - params: { moduleName, pageName }, -}: { - params: { pageName: string; moduleName: string }; -}) { - const decodedPageName = decodeURIComponent(pageName); - const decodedModuleName = decodeURIComponent(moduleName); - return ; -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/EditQuiz.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/EditQuiz.tsx deleted file mode 100644 index 3bbc3d6..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/EditQuiz.tsx +++ /dev/null @@ -1,66 +0,0 @@ -"use client"; -import { MonacoEditor } from "@/components/editor/MonacoEditor"; -import { - useQuizQuery, - useUpdateQuizMutation, -} from "@/hooks/localCourse/quizHooks"; -import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; -import { useEffect, useState } from "react"; -import QuizPreview from "./QuizPreview"; - -export default function EditQuiz({ - moduleName, - quizName, -}: { - quizName: string; - moduleName: string; -}) { - const { data: quiz } = useQuizQuery(moduleName, quizName); - const updateQuizMutation = useUpdateQuizMutation(); - const [quizText, setQuizText] = useState(quizMarkdownUtils.toMarkdown(quiz)); - const [error, setError] = useState(""); - - useEffect(() => { - const delay = 500; - const handler = setTimeout(() => { - if ( - quizMarkdownUtils.toMarkdown(quiz) !== - quizMarkdownUtils.toMarkdown(quizMarkdownUtils.parseMarkdown(quizText)) - ) { - try { - const updatedQuiz = quizMarkdownUtils.parseMarkdown(quizText); - updateQuizMutation.mutate({ - quiz: updatedQuiz, - moduleName, - quizName, - }); - } catch (e: any) { - setError(e.toString()); - } - } - }, delay); - - return () => { - clearTimeout(handler); - }; - }, [moduleName, quiz, quizName, quizText, updateQuizMutation]); - - return ( -
    -
    -
    - -
    -
    -
    {error && error}
    - -
    -
    -
    - -
    -
    - ); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/QuizPreview.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/QuizPreview.tsx deleted file mode 100644 index d398ac3..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/QuizPreview.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import { LocalQuiz } from "@/models/local/quiz/localQuiz"; -import { - LocalQuizQuestion, - QuestionType, -} from "@/models/local/quiz/localQuizQuestion"; -import { quizQuestionMarkdownUtils } from "@/models/local/quiz/utils/quizQuestionMarkdownUtils"; -import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils"; - -export default function QuizPreview({ quiz }: { quiz: LocalQuiz }) { - return ( -
    -
    -
    Name
    -
    {quiz.name}
    -
    -
    -
    Due Date
    -
    {quiz.dueAt}
    -
    -
    -
    Lock At
    -
    {quiz.lockAt}
    -
    -
    -
    Shuffle Answers
    -
    {quiz.shuffleAnswers}
    -
    -
    -
    Allowed Attempts
    -
    {quiz.allowedAttempts}
    -
    -
    -
    One Question at a Time
    -
    {quiz.oneQuestionAtATime}
    -
    -
    -
    Assignment Group Name
    -
    {quiz.localAssignmentGroupName}
    -
    -
    - {quiz.description} -
    -
    - {quiz.questions.map((question, i) => ( - - ))} -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - ); -} - -function QuizQuestionPreview({ question }: { question: LocalQuizQuestion }) { - return ( -
    -
    Points: {question.points}
    -
    Type: {question.questionType}
    -
    - {question.questionType === QuestionType.MATCHING && ( -
    - {question.answers.map((answer) => ( -
    -
    {answer.text} -
    -
    {answer.matchedText}
    -
    - ))} - {question.matchDistractors.map((distractor) => ( -
    - DISTRACTOR: {distractor} -
    - ))} -
    - )} - {question.questionType !== QuestionType.MATCHING && ( -
    - {question.answers.map((answer) => ( -
    - {answer.correct ? ( - - - - ) : ( -
    - {question.questionType === QuestionType.MULTIPLE_ANSWERS && ( - [ ] - )} -
    - )} -
    -
    - ))} -
    - )} -
    - ); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/layout.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/layout.tsx deleted file mode 100644 index 1736e6e..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/layout.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import React, { ReactNode, Suspense } from "react"; - -export default function layout({ children }: { children: ReactNode }) { - return {children}; -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/loading.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/loading.tsx deleted file mode 100644 index 858e083..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/loading.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { Spinner } from "@/components/Spinner"; -import React from "react"; - -export default function Loading() { - return ( -
    - -
    - ); -} diff --git a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/page.tsx b/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/page.tsx deleted file mode 100644 index 7781cb2..0000000 --- a/nextjs-pages/src/pages/course/[courseName]/modules/[moduleName]/quiz/[quizName]/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; -import EditQuiz from "./EditQuiz"; - -export default async function Page({ - params: { moduleName, quizName }, -}: { - params: { quizName: string; moduleName: string }; -}) { - const decodedQuizName = decodeURIComponent(quizName) - const decodedModuleName = decodeURIComponent(moduleName) - return ; -} diff --git a/nextjs-pages/src/pages/index.tsx b/nextjs-pages/src/pages/index.tsx deleted file mode 100644 index 4390967..0000000 --- a/nextjs-pages/src/pages/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { - dehydrate, - DehydratedState, - HydrationBoundary, -} from "@tanstack/react-query"; -import CourseList from "../components/courses/CourseList"; -import { getQueryClient } from "../components/providersQueryClientUtils"; -import { hydrateCourses } from "@/hooks/hookHydration"; -import { undefinedWithNull } from "@/components/undefinedToNull"; - -export async function getServerSideProps() { - const queryClient = getQueryClient(); - await hydrateCourses(queryClient); - const dehydratedState = undefinedWithNull(dehydrate(queryClient)); - - return { props: { dehydratedState } }; -} - -export default function Home({ - dehydratedState, -}: { - dehydratedState: DehydratedState; -}) { - return ( -
    - - - -
    - ); -} diff --git a/nextjs-pages/src/services/canvas/canvasAssignmentService.ts b/nextjs-pages/src/services/canvas/canvasAssignmentService.ts deleted file mode 100644 index 73e6b23..0000000 --- a/nextjs-pages/src/services/canvas/canvasAssignmentService.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CanvasAssignment } from "@/models/canvas/assignments/canvasAssignment"; -import { canvasServiceUtils } from "./canvasServiceUtils"; - -export const canvasAssignmentService = { - async getAll(courseId: number): Promise { - const url = `courses/${courseId}/assignments`; - const assignments = await canvasServiceUtils.paginatedRequest< - CanvasAssignment[] - >({ url }); - return assignments.flatMap((assignments) => - assignments.map((a) => ({ - ...a, - due_at: a.due_at ? new Date(a.due_at).toLocaleString() : undefined, // timezones? - lock_at: a.lock_at ? new Date(a.lock_at).toLocaleString() : undefined, // timezones? - })) - ); - }, -}; diff --git a/nextjs-pages/src/services/canvas/canvasService.ts b/nextjs-pages/src/services/canvas/canvasService.ts deleted file mode 100644 index c972664..0000000 --- a/nextjs-pages/src/services/canvas/canvasService.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel"; -import { canvasServiceUtils } from "./canvasServiceUtils"; -import { webRequestor } from "./webRequestor"; -import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel"; -import { CanvasModuleItem } from "@/models/canvas/modules/canvasModuleItems"; -import { CanvasPage } from "@/models/canvas/pages/canvasPageModel"; -import { CanvasEnrollmentModel } from "@/models/canvas/enrollments/canvasEnrollmentModel"; - -const getTerms = async () => { - const url = `accounts/10/terms`; - const data = await canvasServiceUtils.paginatedRequest<{ - enrollment_terms: CanvasEnrollmentTermModel[]; - }>({ url }); - const terms = data.flatMap((r) => r.enrollment_terms); - return terms; -}; - -export const canvasService = { - getTerms, - async getCourses(termId: number) { - const url = `courses`; - const coursesResponse = - await canvasServiceUtils.paginatedRequest({ url }); - return coursesResponse - .flat() - .filter((c) => c.enrollment_term_id === termId); - }, - - async getCourse(courseId: number): Promise { - const url = `courses/${courseId}`; - const { data, response } = await webRequestor.get(url); - - if (!data) { - console.error((await response?.text()) ?? ""); - console.error(response?.url ?? ""); - throw new Error("Error getting course from Canvas"); - } - - return data; - }, - - async getCurrentTermsFor(queryDate: Date = new Date()) { - const terms = await getTerms(); - const currentTerms = terms - .filter( - (t) => - t.end_at && - new Date(t.end_at) > queryDate && - new Date(t.end_at) < - new Date(queryDate.setFullYear(queryDate.getFullYear() + 1)) - ) - .sort( - (a, b) => - new Date(a.start_at ?? "").getTime() - - new Date(b.start_at ?? "").getTime() - ) - .slice(0, 3); - - return currentTerms; - }, - - async updateModuleItem( - canvasCourseId: number, - canvasModuleId: number, - item: CanvasModuleItem - ) { - console.log(`Updating module item ${item.title}`); - const url = `courses/${canvasCourseId}/modules/${canvasModuleId}/items/${item.id}`; - const body = { - module_item: { title: item.title, position: item.position }, - }; - const { data, response } = - await webRequestor.putWithDeserialize(url, body); - - if (!data) throw new Error("Something went wrong updating module item"); - }, - - async createModuleItem( - canvasCourseId: number, - canvasModuleId: number, - title: string, - type: string, - contentId: number | string - ): Promise { - console.log(`Creating new module item ${title}`); - const url = `courses/${canvasCourseId}/modules/${canvasModuleId}/items`; - const body = { module_item: { title, type, content_id: contentId } }; - const response = await webRequestor.post(url, body); - - if (!response.ok) - throw new Error("Something went wrong creating module item"); - }, - - async createPageModuleItem( - canvasCourseId: number, - canvasModuleId: number, - title: string, - canvasPage: CanvasPage - ): Promise { - console.log(`Creating new module item ${title}`); - const url = `courses/${canvasCourseId}/modules/${canvasModuleId}/items`; - const body = { - module_item: { title, type: "Page", page_url: canvasPage.url }, - }; - const { data, response } = - await webRequestor.postWithDeserialize(url, body); - - if (!response.ok) - throw new Error("Something went wrong creating page module item"); - }, - - async getEnrolledStudents(canvasCourseId: number) { - console.log(`Getting students for course ${canvasCourseId}`); - const url = `courses/${canvasCourseId}/enrollments?enrollment_type=student`; - const { data, response } = - await webRequestor.getMany(url); - - if (!data) - throw new Error( - `Something went wrong getting enrollments for ${canvasCourseId}` - ); - - return data; - }, -}; diff --git a/nextjs-pages/src/services/canvas/canvasServiceUtils.ts b/nextjs-pages/src/services/canvas/canvasServiceUtils.ts deleted file mode 100644 index f0444d1..0000000 --- a/nextjs-pages/src/services/canvas/canvasServiceUtils.ts +++ /dev/null @@ -1,58 +0,0 @@ -// services/canvasServiceUtils.ts - -import { webRequestor } from "./webRequestor"; - -const BASE_URL = "https://snow.instructure.com/api/v1/"; - -const getNextUrl = (headers: Headers): string | undefined => { - const linkHeader = headers.get("Link"); - if (!linkHeader) return undefined; - - const links = linkHeader.split(",").map((link) => link.trim()); - const nextLink = links.find((link) => link.includes('rel="next"')); - - if (!nextLink) return undefined; - - const nextUrl = nextLink.split(";")[0].trim().slice(1, -1); - return nextUrl.replace(BASE_URL, "").trim(); -}; - -export const canvasServiceUtils = { - async paginatedRequest(request: { url: string }): Promise { - var requestCount = 1; - const url = new URL(request.url!, BASE_URL); - url.searchParams.set("per_page", "100"); - - const { data: firstData, response: firstResponse } = - await webRequestor.get(url.toString()); - - if (!firstResponse.ok) { - console.error( - "error in response", - firstResponse.statusText, - firstResponse.body - ); - throw new Error("error in response"); - } - - var returnData: T[] = firstData ? [firstData] : []; - var nextUrl = getNextUrl(firstResponse.headers); - - while (nextUrl) { - requestCount += 1; - const {data, response} = await webRequestor.get(nextUrl); - if (data) { - returnData = [...returnData, data]; - } - nextUrl = getNextUrl(response.headers); - } - - if (requestCount > 1) { - console.log( - `Requesting ${typeof returnData} took ${requestCount} requests` - ); - } - - return returnData; - }, -}; diff --git a/nextjs-pages/src/services/canvas/webRequestor.ts b/nextjs-pages/src/services/canvas/webRequestor.ts deleted file mode 100644 index 0df88aa..0000000 --- a/nextjs-pages/src/services/canvas/webRequestor.ts +++ /dev/null @@ -1,177 +0,0 @@ -type FetchOptions = Omit; - -const token = process.env.CANVAS_TOKEN; -if (!token) { - throw new Error("CANVAS_TOKEN not in environment"); -} - -const baseUrl = `${process.env.CANVAS_URL}/api/v1/`; -const rateLimitRetryCount = 6; -const rateLimitSleepInterval = 1000; - -const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); - -const isRateLimited = async (response: Response): Promise => { - const content = await response.text(); - return ( - response.status === 403 && - content.includes("403 Forbidden (Rate Limit Exceeded)") - ); -}; - -const deserialize = async (response: Response): Promise => { - if (!response.ok) { - console.error(`Error with response to ${response.url} ${response.status}`); - throw new Error( - `Error with response to ${response.url} ${response.status}` - ); - } - try { - return (await response.json()) as T; - } catch (e) { - console.error(`An error occurred during deserialization: ${e}`); - throw e; - } -}; - -const rateLimitAwarePost = async ( - url: string, - body: any, - retryCount = 0 -): Promise => { - const response = await fetch(url, { - method: "POST", - body: JSON.stringify(body), - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - }); - - if (await isRateLimited(response)) { - if (retryCount < rateLimitRetryCount) { - console.info( - `Hit rate limit on post, retry count is ${retryCount} / ${rateLimitRetryCount}, retrying` - ); - await sleep(rateLimitSleepInterval); - return await rateLimitAwarePost(url, body, retryCount + 1); - } - } - - if (!response.ok) { - const content = await response.text(); - console.error(`Error with response, response content: ${content}`); - throw new Error( - `Error post response, retrycount: ${retryCount}, ratelimited: ${await isRateLimited( - response - )}, code: ${response.status}, response content: ${content}` - ); - } - return response; -}; - -const recursiveDelete = async ( - url: string, - options: FetchOptions, - retryCount = 0 -): Promise => { - try { - const response = await fetch(url, { - ...options, - method: "DELETE", - headers: { - ...options.headers, - Authorization: `Bearer ${token}`, - }, - }); - - if (await isRateLimited(response)) { - console.info("After delete response in rate limited"); - await sleep(rateLimitSleepInterval); - return await recursiveDelete(url, options, retryCount + 1); - } - - return response; - } catch (e) { - const error = e as Error & { response?: Response }; - if (error.response?.status === 403) { - if (retryCount < rateLimitRetryCount) { - console.info( - `Hit rate limit in delete, retry count is ${retryCount} / ${rateLimitRetryCount}, retrying` - ); - await sleep(rateLimitSleepInterval); - return await recursiveDelete(url, options, retryCount + 1); - } else { - console.info( - `Hit rate limit in delete, ${rateLimitRetryCount} retries did not fix it` - ); - } - } - throw e; - } -}; -export const webRequestor = { - getMany: async (url: string, options: FetchOptions = {}) => { - const response = await fetch(url, { - ...options, - method: "GET", - headers: { - ...options.headers, - Authorization: `Bearer ${token}`, - }, - }); - return { data: await deserialize(response), response }; - }, - - get: async (url: string, options: FetchOptions = {}) => { - const response = await fetch(url, { - ...options, - method: "GET", - headers: { - ...options.headers, - Authorization: `Bearer ${token}`, - }, - }); - return { data: await deserialize(response), response }; - }, - - post: async (url: string, body: any) => { - return await rateLimitAwarePost(url, body); - }, - - postWithDeserialize: async (url: string, body: any) => { - const response = await rateLimitAwarePost(url, body); - return { data: await deserialize(response), response }; - }, - - put: async (url: string, body: any = {}) => { - const response = await fetch(url, { - method: "PUT", - body: JSON.stringify(body), - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - }); - return response; - }, - - putWithDeserialize: async (url: string, body: any = {}) => { - const response = await fetch(url, { - body: JSON.stringify(body), - method: "PUT", - headers: { - Authorization: `Bearer ${token}`, - "Content-Type": "application/json", - }, - }); - return { data: await deserialize(response), response }; - }, - - delete: async ( - url: string, - options: FetchOptions = {} - ): Promise => { - return await recursiveDelete(url, options); - }, -}; diff --git a/nextjs-pages/src/services/fileStorage/fileStorageService.ts b/nextjs-pages/src/services/fileStorage/fileStorageService.ts deleted file mode 100644 index ae60fa1..0000000 --- a/nextjs-pages/src/services/fileStorage/fileStorageService.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { promises as fs } from "fs"; -import path from "path"; -import { - LocalCourse, - LocalCourseSettings, - localCourseYamlUtils, -} from "@/models/local/localCourse"; -import { - directoryOrFileExists, - hasFileSystemEntries, -} from "./utils/fileSystemUtils"; -import { LocalAssignment, localAssignmentMarkdown } from "@/models/local/assignment/localAssignment"; -import { LocalQuiz, localQuizMarkdownUtils } from "@/models/local/quiz/localQuiz"; -import { LocalCoursePage, localPageMarkdownUtils } from "@/models/local/page/localCoursePage"; -import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; -import { assignmentMarkdownSerializer } from "@/models/local/assignment/utils/assignmentMarkdownSerializer"; - -const basePath = process.env.STORAGE_DIRECTORY ?? "./storage"; -console.log("base path", basePath); - -export const fileStorageService = { - // async saveCourseAsync( - // course: LocalCourse, - // previouslyStoredCourse?: LocalCourse - // ) { - // await courseMarkdownSaver.save(course, previouslyStoredCourse); - // }, - - // async loadSavedCourses(): Promise { - // console.log("loading pages from file system"); - // return (await courseMarkdownLoader.loadSavedCourses()) || []; - // }, - - async getCourseNames() { - console.log("loading course ids"); - const courseDirectories = await fs.readdir(basePath, { - withFileTypes: true, - }); - const coursePromises = courseDirectories - .filter((dirent) => dirent.isDirectory()) - .filter(async (dirent) => { - const coursePath = path.join(basePath, dirent.name); - const settingsPath = path.join(coursePath, "settings.yml"); - return await directoryOrFileExists(settingsPath); - }); - const courseNamesFromDirectories = (await Promise.all(coursePromises)).map( - (c) => c.name - ); - - return courseNamesFromDirectories; - }, - - async getCourseSettings(courseName: string): Promise { - const courseDirectory = path.join(basePath, courseName); - const settingsPath = path.join(courseDirectory, "settings.yml"); - if (!(await directoryOrFileExists(settingsPath))) { - const errorMessage = `Error loading settings for ${courseName}, settings file ${settingsPath}`; - console.log(errorMessage); - throw new Error(errorMessage); - } - - const settingsString = await fs.readFile(settingsPath, "utf-8"); - const settings = localCourseYamlUtils.parseSettingYaml(settingsString); - - const folderName = path.basename(courseDirectory); - return { ...settings, name: folderName }; - }, - - async getModuleNames(courseName: string) { - const courseDirectory = path.join(basePath, courseName); - const moduleDirectories = await fs.readdir(courseDirectory, { - withFileTypes: true, - }); - - const modulePromises = moduleDirectories - .filter((dirent) => dirent.isDirectory()) - .map((dirent) => dirent.name); - - const modules = await Promise.all(modulePromises); - return modules.sort((a, b) => a.localeCompare(b)); - }, - - async getAssignmentNames(courseName: string, moduleName: string) { - const filePath = path.join(basePath, courseName, moduleName, "assignments"); - if (!(await directoryOrFileExists(filePath))) { - console.log( - `Error loading course by name, assignments folder does not exist in ${filePath}` - ); - await fs.mkdir(filePath); - } - - const assignmentFiles = await fs.readdir(filePath); - return assignmentFiles.map(f => f.replace(/\.md$/, '')); - }, - - async getQuizNames(courseName: string, moduleName: string) { - const filePath = path.join(basePath, courseName, moduleName, "quizzes"); - if (!(await directoryOrFileExists(filePath))) { - console.log( - `Error loading course by name, quiz folder does not exist in ${filePath}` - ); - await fs.mkdir(filePath); - } - - const files = await fs.readdir(filePath); - return files.map(f => f.replace(/\.md$/, '')); - }, - - async getPageNames(courseName: string, moduleName: string) { - const filePath = path.join(basePath, courseName, moduleName, "pages"); - if (!(await directoryOrFileExists(filePath))) { - console.log( - `Error loading course by name, pages folder does not exist in ${filePath}` - ); - await fs.mkdir(filePath); - } - - const files = await fs.readdir(filePath); - return files.map(f => f.replace(/\.md$/, '')); - }, - - async getAssignment( - courseName: string, - moduleName: string, - assignmentName: string - ) { - const filePath = path.join( - basePath, - courseName, - moduleName, - "assignments", - assignmentName + ".md" - ); - const rawFile = (await fs.readFile(filePath, "utf-8")).replace( - /\r\n/g, - "\n" - ); - return localAssignmentMarkdown.parseMarkdown(rawFile); - }, - async updateAssignment(courseName: string, moduleName: string, assignmentName: string, assignment: LocalAssignment) { - const filePath = path.join( - basePath, - courseName, - moduleName, - "assignments", - assignmentName+".md" - ); - - const assignmentMarkdown = assignmentMarkdownSerializer.toMarkdown(assignment); - console.log(`Saving assignment ${filePath}`); - await fs.writeFile(filePath, assignmentMarkdown); - }, - - async getQuiz(courseName: string, moduleName: string, quizName: string) { - const filePath = path.join( - basePath, - courseName, - moduleName, - "quizzes", - quizName + ".md" - ); - const rawFile = (await fs.readFile(filePath, "utf-8")).replace( - /\r\n/g, - "\n" - ); - return localQuizMarkdownUtils.parseMarkdown(rawFile); - }, - - async updateQuiz(courseName: string, moduleName: string, quizName: string, quiz: LocalQuiz) { - const filePath = path.join( - basePath, - courseName, - moduleName, - "quizzes", - quizName+".md" - ); - - const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); - console.log(`Saving quiz ${filePath}`); - await fs.writeFile(filePath, quizMarkdown); - }, - - async getPage(courseName: string, moduleName: string, pageName: string) { - const filePath = path.join( - basePath, - courseName, - moduleName, - "pages", - pageName + ".md" - ); - const rawFile = (await fs.readFile(filePath, "utf-8")).replace( - /\r\n/g, - "\n" - ); - return localPageMarkdownUtils.parseMarkdown(rawFile); - }, - async updatePage(courseName: string, moduleName: string, pageName: string, page: LocalCoursePage) { - const filePath = path.join( - basePath, - courseName, - moduleName, - "pages", - pageName+".md" - ); - - const pageMarkdown = localPageMarkdownUtils.toMarkdown(page); - console.log(`Saving page ${filePath}`); - await fs.writeFile(filePath, pageMarkdown); - }, - - async getEmptyDirectories(): Promise { - if (!(await directoryOrFileExists(basePath))) { - throw new Error( - `Cannot get empty directories, ${basePath} does not exist` - ); - } - - const directories = await fs.readdir(basePath, { withFileTypes: true }); - const emptyDirectories = directories - .filter((dirent) => dirent.isDirectory()) - .map((dirent) => path.join(basePath, dirent.name)) - .filter(async (dir) => !(await hasFileSystemEntries(dir))); - - return emptyDirectories; - }, -}; diff --git a/nextjs-pages/src/services/fileStorage/utils/courseDifferences.ts b/nextjs-pages/src/services/fileStorage/utils/courseDifferences.ts deleted file mode 100644 index b572975..0000000 --- a/nextjs-pages/src/services/fileStorage/utils/courseDifferences.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { LocalCourse, LocalCourseSettings } from "@/models/local/localCourse"; -import { LocalModule } from "@/models/local/localModules"; - -export const CourseDifferences = { - getDeletedChanges( - newCourse: LocalCourse, - oldCourse: LocalCourse - ): DeleteCourseChanges { - if (newCourse === oldCourse) { - const emptyDeletes: DeleteCourseChanges = { - namesOfModulesToDeleteCompletely: [], - deleteContentsOfModule: [], - }; - return emptyDeletes; - } - - const moduleNamesNoLongerReferenced = oldCourse.modules - .filter( - (oldModule) => - !newCourse.modules.some( - (newModule) => newModule.name === oldModule.name - ) - ) - .map((oldModule) => oldModule.name); - - const modulesWithDeletions = oldCourse.modules - .filter( - (oldModule) => - !newCourse.modules.some( - (newModule) => - JSON.stringify(newModule) === JSON.stringify(oldModule) - ) - ) - .map((oldModule) => { - const newModule = newCourse.modules.find( - (m) => m.name === oldModule.name - ); - if (!newModule) return oldModule; - - const unreferencedAssignments = oldModule.assignments.filter( - (oldAssignment) => - !newModule.assignments.some( - (newAssignment) => newAssignment.name === oldAssignment.name - ) - ); - const unreferencedQuizzes = oldModule.quizzes.filter( - (oldQuiz) => - !newModule.quizzes.some((newQuiz) => newQuiz.name === oldQuiz.name) - ); - const unreferencedPages = oldModule.pages.filter( - (oldPage) => - !newModule.pages.some((newPage) => newPage.name === oldPage.name) - ); - - return { - ...oldModule, - assignments: unreferencedAssignments, - quizzes: unreferencedQuizzes, - pages: unreferencedPages, - }; - }); - - return { - namesOfModulesToDeleteCompletely: moduleNamesNoLongerReferenced, - deleteContentsOfModule: modulesWithDeletions, - }; - }, - - getNewChanges( - newCourse: LocalCourse, - oldCourse: LocalCourse - ): NewCourseChanges { - if (newCourse === oldCourse) { - const emptyChanges: NewCourseChanges = { - modules: [], - }; - return emptyChanges; - } - - const differentModules = newCourse.modules - .filter( - (newModule) => - !oldCourse.modules.some( - (oldModule) => - JSON.stringify(oldModule) === JSON.stringify(newModule) - ) - ) - .map((newModule) => { - const oldModule = oldCourse.modules.find( - (m) => m.name === newModule.name - ); - if (!oldModule) return newModule; - - const newAssignments = newModule.assignments.filter( - (newAssignment) => - !oldModule.assignments.some( - (oldAssignment) => - JSON.stringify(newAssignment) === JSON.stringify(oldAssignment) - ) - ); - const newQuizzes = newModule.quizzes.filter( - (newQuiz) => - !oldModule.quizzes.some( - (oldQuiz) => JSON.stringify(newQuiz) === JSON.stringify(oldQuiz) - ) - ); - const newPages = newModule.pages.filter( - (newPage) => - !oldModule.pages.some( - (oldPage) => JSON.stringify(newPage) === JSON.stringify(oldPage) - ) - ); - - return { - ...newModule, - assignments: newAssignments, - quizzes: newQuizzes, - pages: newPages, - }; - }); - - return { - settings: newCourse.settings, - modules: differentModules, - }; - }, -}; - -export interface DeleteCourseChanges { - namesOfModulesToDeleteCompletely: string[]; - deleteContentsOfModule: LocalModule[]; -} - -export interface NewCourseChanges { - modules: LocalModule[]; - settings?: LocalCourseSettings; -} - -// Default values for DeleteCourseChanges and NewCourseChanges -// export const createDeleteCourseChanges = ( -// init?: Partial -// ): DeleteCourseChanges => ({ -// namesOfModulesToDeleteCompletely: init?.namesOfModulesToDeleteCompletely ?? [], -// deleteContentsOfModule: init?.deleteContentsOfModule ?? [], -// }); - -// export const createNewCourseChanges = ( -// init?: Partial -// ): NewCourseChanges => ({ -// modules: init?.modules ?? [], -// settings: init?.settings, -// }); diff --git a/nextjs-pages/src/services/fileStorage/utils/courseMarkdownLoader.ts b/nextjs-pages/src/services/fileStorage/utils/courseMarkdownLoader.ts deleted file mode 100644 index be472b1..0000000 --- a/nextjs-pages/src/services/fileStorage/utils/courseMarkdownLoader.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { - LocalAssignment, - localAssignmentMarkdown, -} from "@/models/local/assignment/localAssignment"; -import { - LocalCourse, - LocalCourseSettings, - localCourseYamlUtils, -} from "@/models/local/localCourse"; -import { LocalModule } from "@/models/local/localModules"; -import { - LocalCoursePage, - localPageMarkdownUtils, -} from "@/models/local/page/localCoursePage"; -import { - LocalQuiz, - localQuizMarkdownUtils, -} from "@/models/local/quiz/localQuiz"; -import { promises as fs } from "fs"; -import path from "path"; -import { directoryOrFileExists } from "./fileSystemUtils"; - -const basePath = process.env.STORAGE_DIRECTORY ?? "./storage"; - -export const courseMarkdownLoader = { - // async loadSavedCourses(): Promise { - // const courseDirectories = await fs.readdir(basePath, { - // withFileTypes: true, - // }); - // const coursePromises = courseDirectories - // .filter((dirent) => dirent.isDirectory()) - // .map(async (dirent) => { - // const coursePath = path.join(basePath, dirent.name); - // const settingsPath = path.join(coursePath, "settings.yml"); - // if (await directoryOrFileExists(settingsPath)) { - // return this.loadCourseByPath(coursePath); - // } - // return null; - // }); - - // const courses = (await Promise.all(coursePromises)).filter( - // (course) => course !== null - // ) as LocalCourse[]; - // return courses.sort((a, b) => - // a.settings.name.localeCompare(b.settings.name) - // ); - // }, - - // async loadCourseByPath(courseDirectory: string): Promise { - // if (!(await directoryOrFileExists(courseDirectory))) { - // const errorMessage = `Error loading course by name, could not find folder ${courseDirectory}`; - // console.log(errorMessage); - // throw new Error(errorMessage); - // } - - // const settings = await this.loadCourseSettings(courseDirectory); - // const modules = await this.loadCourseModules(courseDirectory); - - // return { - // settings, - // modules, - // }; - // }, - - // async loadCourseSettings( - // courseDirectory: string - // ): Promise { - // const settingsPath = path.join(courseDirectory, "settings.yml"); - // if (!(await directoryOrFileExists(settingsPath))) { - // const errorMessage = `Error loading course by name, settings file ${settingsPath}`; - // console.log(errorMessage); - // throw new Error(errorMessage); - // } - - // const settingsString = await fs.readFile(settingsPath, "utf-8"); - // const settings = localCourseYamlUtils.parseSettingYaml(settingsString); - - // const folderName = path.basename(courseDirectory); - // return { ...settings, name: folderName }; - // }, - - // async loadCourseModules(courseDirectory: string): Promise { - // const moduleDirectories = await fs.readdir(courseDirectory, { - // withFileTypes: true, - // }); - // const modulePromises = moduleDirectories - // .filter((dirent) => dirent.isDirectory()) - // .map((dirent) => - // this.loadModuleFromPath(path.join(courseDirectory, dirent.name)) - // ); - - // const modules = await Promise.all(modulePromises); - // return modules.sort((a, b) => a.name.localeCompare(b.name)); - // }, - - // async loadModuleFromPath(modulePath: string): Promise { - // const moduleName = path.basename(modulePath); - // const assignments = await this.loadAssignmentsFromPath(modulePath); - // const quizzes = await this.loadQuizzesFromPath(modulePath); - // const pages = await this.loadModulePagesFromPath(modulePath); - - // return { - // name: moduleName, - // assignments, - // quizzes, - // pages, - // }; - // }, - - // async loadAssignmentsFromPath( - // modulePath: string - // ): Promise { - // const assignmentsPath = path.join(modulePath, "assignments"); - // if (!(await directoryOrFileExists(assignmentsPath))) { - // console.log( - // `Error loading course by name, assignments folder does not exist in ${modulePath}` - // ); - // await fs.mkdir(assignmentsPath); - // } - - // const assignmentFiles = await fs.readdir(assignmentsPath); - // const assignmentPromises = assignmentFiles.map(async (file) => { - // const filePath = path.join(assignmentsPath, file); - // const rawFile = (await fs.readFile(filePath, "utf-8")).replace( - // /\r\n/g, - // "\n" - // ); - // return localAssignmentMarkdown.parseMarkdown(rawFile); - // }); - - // return await Promise.all(assignmentPromises); - // }, - - // async loadQuizzesFromPath(modulePath: string): Promise { - // const quizzesPath = path.join(modulePath, "quizzes"); - // if (!(await directoryOrFileExists(quizzesPath))) { - // console.log( - // `Quizzes folder does not exist in ${modulePath}, creating now` - // ); - // await fs.mkdir(quizzesPath); - // } - - // const quizFiles = await fs.readdir(quizzesPath); - // const quizPromises = quizFiles.map(async (file) => { - // const filePath = path.join(quizzesPath, file); - // const rawQuiz = (await fs.readFile(filePath, "utf-8")).replace( - // /\r\n/g, - // "\n" - // ); - // return localQuizMarkdownUtils.parseMarkdown(rawQuiz); - // }); - - // return await Promise.all(quizPromises); - // }, - - // async loadModulePagesFromPath( - // modulePath: string - // ): Promise { - // const pagesPath = path.join(modulePath, "pages"); - // if (!(await directoryOrFileExists(pagesPath))) { - // console.log(`Pages folder does not exist in ${modulePath}, creating now`); - // await fs.mkdir(pagesPath); - // } - - // const pageFiles = await fs.readdir(pagesPath); - // const pagePromises = pageFiles.map(async (file) => { - // const filePath = path.join(pagesPath, file); - // const rawPage = (await fs.readFile(filePath, "utf-8")).replace( - // /\r\n/g, - // "\n" - // ); - // return localPageMarkdownUtils.parseMarkdown(rawPage); - // }); - - // return await Promise.all(pagePromises); - // }, -}; diff --git a/nextjs-pages/src/services/fileStorage/utils/courseMarkdownSaver.ts b/nextjs-pages/src/services/fileStorage/utils/courseMarkdownSaver.ts deleted file mode 100644 index cd24710..0000000 --- a/nextjs-pages/src/services/fileStorage/utils/courseMarkdownSaver.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { localAssignmentMarkdown } from "@/models/local/assignment/localAssignment"; -import { LocalCourse, localCourseYamlUtils } from "@/models/local/localCourse"; -import { LocalModule } from "@/models/local/localModules"; -import { localPageMarkdownUtils } from "@/models/local/page/localCoursePage"; -import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils"; -import { promises as fs } from "fs"; -import path from "path"; - -const basePath = process.env.STORAGE_DIRECTORY ?? "./storage"; - -const directoryExists = async (directoryPath: string): Promise => { - try { - await fs.access(directoryPath); - return true; - } catch { - return false; - } -}; - -const saveSettings = async (course: LocalCourse, courseDirectory: string) => { - const settingsFilePath = path.join(courseDirectory, "settings.yml"); - const settingsYaml = localCourseYamlUtils.settingsToYaml(course.settings); - await fs.writeFile(settingsFilePath, settingsYaml); -}; - -// const saveModules = async ( -// course: LocalCourse, -// courseDirectory: string, -// previouslyStoredCourse?: LocalCourse -// ) => { -// for (const localModule of course.modules) { -// const moduleDirectory = path.join(courseDirectory, localModule.name); -// if (!(await directoryExists(moduleDirectory))) { -// await fs.mkdir(moduleDirectory, { recursive: true }); -// } - -// await saveQuizzes(course, localModule, previouslyStoredCourse); -// await saveAssignments(course, localModule, previouslyStoredCourse); -// await savePages(course, localModule, previouslyStoredCourse); -// } - -// const moduleNames = course.modules.map((m) => m.name); -// const moduleDirectories = await fs.readdir(courseDirectory, { -// withFileTypes: true, -// }); - -// for (const dirent of moduleDirectories) { -// if (dirent.isDirectory() && !moduleNames.includes(dirent.name)) { -// const moduleDirPath = path.join(courseDirectory, dirent.name); -// console.log( -// `Deleting extra module directory, it was probably renamed ${moduleDirPath}` -// ); -// await fs.rmdir(moduleDirPath, { recursive: true }); -// } -// } -// }; - -// const saveQuizzes = async ( -// course: LocalCourse, -// module: LocalModule, -// previouslyStoredCourse?: LocalCourse -// ) => { -// const quizzesDirectory = path.join( -// basePath, -// course.settings.name, -// module.name, -// "quizzes" -// ); -// if (!(await directoryExists(quizzesDirectory))) { -// await fs.mkdir(quizzesDirectory, { recursive: true }); -// } - -// for (const quiz of module.quizzes) { -// const previousModule = previouslyStoredCourse?.modules.find( -// (m) => m.name === module.name -// ); -// const previousQuiz = previousModule?.quizzes.find((q) => q === quiz); - -// if (!previousQuiz) { -// const markdownPath = path.join(quizzesDirectory, `${quiz.name}.md`); -// const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz); -// console.log(`Saving quiz ${markdownPath}`); -// await fs.writeFile(markdownPath, quizMarkdown); -// } -// } - -// await removeOldQuizzes(quizzesDirectory, module); -// }; - -const saveAssignments = async ( - course: LocalCourse, - module: LocalModule, - previouslyStoredCourse?: LocalCourse -) => { - const assignmentsDirectory = path.join( - basePath, - course.settings.name, - module.name, - "assignments" - ); - if (!(await directoryExists(assignmentsDirectory))) { - await fs.mkdir(assignmentsDirectory, { recursive: true }); - } - - for (const assignment of module.assignments) { - const previousModule = previouslyStoredCourse?.modules.find( - (m) => m.name === module.name - ); - const previousAssignment = previousModule?.assignments.find( - (a) => a === assignment - ); - - if (!previousAssignment) { - const assignmentMarkdown = localAssignmentMarkdown.toMarkdown(assignment); - const filePath = path.join(assignmentsDirectory, `${assignment.name}.md`); - console.log(`Saving assignment ${filePath}`); - await fs.writeFile(filePath, assignmentMarkdown); - } - } - - await removeOldAssignments(assignmentsDirectory, module); -}; - -const savePages = async ( - course: LocalCourse, - module: LocalModule, - previouslyStoredCourse?: LocalCourse -) => { - const pagesDirectory = path.join( - basePath, - course.settings.name, - module.name, - "pages" - ); - if (!(await directoryExists(pagesDirectory))) { - await fs.mkdir(pagesDirectory, { recursive: true }); - } - - for (const page of module.pages) { - const previousModule = previouslyStoredCourse?.modules.find( - (m) => m.name === module.name - ); - const previousPage = previousModule?.pages.find((p) => p === page); - - if (!previousPage) { - const pageMarkdown = localPageMarkdownUtils.toMarkdown(page); - const filePath = path.join(pagesDirectory, `${page.name}.md`); - console.log(`Saving page ${filePath}`); - await fs.writeFile(filePath, pageMarkdown); - } - } - - await removeOldPages(pagesDirectory, module); -}; - -const removeOldQuizzes = async ( - quizzesDirectory: string, - module: LocalModule -) => { - const existingFiles = await fs.readdir(quizzesDirectory); - const quizFilesToDelete = existingFiles.filter((file) => { - const quizMarkdownPath = path.join( - quizzesDirectory, - `${file.replace(".md", "")}.md` - ); - return !module.quizzes.some( - (quiz) => - path.join(quizzesDirectory, `${quiz.name}.md`) === quizMarkdownPath - ); - }); - - for (const file of quizFilesToDelete) { - console.log( - `Removing old quiz, it has probably been renamed ${path.join( - quizzesDirectory, - file - )}` - ); - await fs.unlink(path.join(quizzesDirectory, file)); - } -}; - -const removeOldAssignments = async ( - assignmentsDirectory: string, - module: LocalModule -) => { - const existingFiles = await fs.readdir(assignmentsDirectory); - const assignmentFilesToDelete = existingFiles.filter((file) => { - const assignmentMarkdownPath = path.join( - assignmentsDirectory, - `${file.replace(".md", "")}.md` - ); - return !module.assignments.some( - (assignment) => - path.join(assignmentsDirectory, `${assignment.name}.md`) === - assignmentMarkdownPath - ); - }); - - for (const file of assignmentFilesToDelete) { - console.log( - `Removing old assignment, it has probably been renamed ${path.join( - assignmentsDirectory, - file - )}` - ); - await fs.unlink(path.join(assignmentsDirectory, file)); - } -}; - -const removeOldPages = async (pagesDirectory: string, module: LocalModule) => { - const existingFiles = await fs.readdir(pagesDirectory); - const pageFilesToDelete = existingFiles.filter((file) => { - const pageMarkdownPath = path.join( - pagesDirectory, - `${file.replace(".md", "")}.md` - ); - return !module.pages.some( - (page) => - path.join(pagesDirectory, `${page.name}.md`) === pageMarkdownPath - ); - }); - - for (const file of pageFilesToDelete) { - console.log( - `Removing old page, it has probably been renamed ${path.join( - pagesDirectory, - file - )}` - ); - await fs.unlink(path.join(pagesDirectory, file)); - } -}; - -// export const courseMarkdownSaver = { -// async save(course: LocalCourse, previouslyStoredCourse?: LocalCourse) { -// const courseDirectory = path.join(basePath, course.settings.name); -// if (!(await directoryExists(courseDirectory))) { -// await fs.mkdir(courseDirectory, { recursive: true }); -// } - -// await saveSettings(course, courseDirectory); -// await saveModules(course, courseDirectory, previouslyStoredCourse); -// }, -// }; diff --git a/nextjs-pages/src/services/fileStorage/utils/fileSystemUtils.ts b/nextjs-pages/src/services/fileStorage/utils/fileSystemUtils.ts deleted file mode 100644 index 7b13925..0000000 --- a/nextjs-pages/src/services/fileStorage/utils/fileSystemUtils.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { promises as fs } from "fs"; - -export const hasFileSystemEntries = async ( - directoryPath: string -): Promise => { - try { - const entries = await fs.readdir(directoryPath); - return entries.length > 0; - } catch { - return false; - } -}; -export const directoryOrFileExists = async (directoryPath: string): Promise => { - try { - await fs.access(directoryPath); - return true; - } catch { - return false; - } -}; \ No newline at end of file diff --git a/nextjs-pages/src/services/htmlMarkdownUtils.ts b/nextjs-pages/src/services/htmlMarkdownUtils.ts deleted file mode 100644 index cd22c54..0000000 --- a/nextjs-pages/src/services/htmlMarkdownUtils.ts +++ /dev/null @@ -1,10 +0,0 @@ -"use client"; -import { marked } from "marked"; -import * as DOMPurify from "isomorphic-dompurify"; - -export function markdownToHTMLSafe(markdownString: string) { - const clean = DOMPurify.sanitize( - marked.parse(markdownString, { async: false, pedantic: false, gfm: true }) - ); - return clean; -} diff --git a/nextjs-pages/src/services/tests/courseDifferenceChanges.test.ts b/nextjs-pages/src/services/tests/courseDifferenceChanges.test.ts deleted file mode 100644 index adfc604..0000000 --- a/nextjs-pages/src/services/tests/courseDifferenceChanges.test.ts +++ /dev/null @@ -1,587 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { LocalCourse } from "@/models/local/localCourse"; -import { CourseDifferences } from "../fileStorage/utils/courseDifferences"; -import { AssignmentSubmissionType } from "@/models/local/assignment/assignmentSubmissionType"; - -describe("CourseDifferencesChangesTests", () => { - it("can detect new settings", () => { - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [], - }; - const newCourse: LocalCourse = { - ...oldCourse, - settings: { - ...oldCourse.settings, - name: "new course name", - }, - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(0); - expect(differences.settings).not.toBeNull(); - expect(differences.settings?.name).toBe("new course name"); - }); - - it("can detect new module", () => { - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).not.toBeNull(); - expect(differences.modules).toHaveLength(1); - expect(differences.modules?.[0].name).toBe("new module"); - }); - - it("can detect changed assignment", () => { - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [ - { - name: "test assignment", - description: "", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "new module", - assignments: [ - { - name: "test assignment", - description: "new description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).not.toBeNull(); - expect(differences.modules).toHaveLength(1); - expect(differences.modules?.[0].assignments?.[0].description).toBe( - "new description" - ); - }); - - it("can properly ignore unchanged modules", () => { - const commonDate = "07/09/2024 23:59:00"; - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: commonDate, - endDate: commonDate, - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [ - { - name: "test assignment", - description: "", - dueAt: commonDate, - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(0); - }); - - it("only changed assignment represented", () => { - const commonDate = "07/09/2024 23:59:00"; - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: commonDate, - endDate: commonDate, - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [ - { - name: "test assignment", - description: "", - dueAt: commonDate, - submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], - allowedFileUploadExtensions: [], - rubric: [{ points: 1, label: "rubric" }], - }, - { - name: "test assignment 2", - description: "", - dueAt: commonDate, - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "new module", - assignments: [ - { - name: "test assignment", - description: "", - dueAt: commonDate, - submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], - allowedFileUploadExtensions: [], - rubric: [{ points: 1, label: "rubric" }], - }, - { - name: "test assignment 2 with a new name", - description: "", - dueAt: commonDate, - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(1); - expect(differences.modules?.[0].assignments).toHaveLength(1); - expect(differences.modules?.[0].assignments?.[0].name).toBe( - "test assignment 2 with a new name" - ); - }); - - it("identical quizzes ignored", () => { - const commonDate = "07/09/2024 23:59:00"; - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: commonDate, - endDate: commonDate, - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [ - { - name: "Test Quiz", - description: "this is my description", - dueAt: commonDate, - shuffleAnswers: true, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: -1, - questions: [], - }, - ], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(0); - }); - - it("can detect different quiz", () => { - const commonDate = "07/09/2024 23:59:00"; - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: commonDate, - endDate: commonDate, - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [ - { - name: "Test Quiz", - description: "this is my description", - dueAt: commonDate, - shuffleAnswers: true, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: -1, - questions: [], - }, - ], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [ - { - name: "Test Quiz", - description: "this is my description", - dueAt: commonDate, - shuffleAnswers: true, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: -1, - questions: [], - lockAt: "12/31/9999 23:59:59", - }, - ], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(1); - expect(differences.modules?.[0].quizzes).toHaveLength(1); - expect(differences.modules?.[0].quizzes?.[0].lockAt).toBe( - "12/31/9999 23:59:59" - ); - }); - - it("can detect only different quiz when other quizzes stay", () => { - const commonDate = "07/09/2024 23:59:00"; - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: commonDate, - endDate: commonDate, - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [ - { - name: "Test Quiz", - description: "this is my description", - dueAt: commonDate, - shuffleAnswers: true, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: -1, - questions: [], - }, - ], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [ - { - name: "Test Quiz", - description: "this is my description", - dueAt: commonDate, - shuffleAnswers: true, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: -1, - questions: [], - }, - { - name: "Test Quiz 2", - description: "this is my description", - dueAt: commonDate, - shuffleAnswers: true, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: -1, - questions: [], - }, - ], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(1); - expect(differences.modules?.[0].quizzes).toHaveLength(1); - expect(differences.modules?.[0].quizzes?.[0].name).toBe("Test Quiz 2"); - }); - - it("same pages not detected", () => { - const commonDate = "07/09/2024 23:59:00"; - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: commonDate, - endDate: commonDate, - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [], - pages: [ - { - name: "test page", - text: "test description", - dueAt: commonDate, - }, - ], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(0); - }); - - it("different page detected", () => { - const commonDate = "07/09/2024 23:59:00"; - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: commonDate, - endDate: commonDate, - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [], - pages: [ - { - name: "test page", - text: "test description", - dueAt: commonDate, - }, - ], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [], - pages: [ - { - name: "test page", - text: "test description changed", - dueAt: commonDate, - }, - ], - }, - ], - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(1); - expect(differences.modules?.[0].pages).toHaveLength(1); - expect(differences.modules?.[0].pages?.[0].text).toBe( - "test description changed" - ); - }); - - it("different page detected but not same page", () => { - const commonDate = "07/09/2024 23:59:00"; - const oldCourse: LocalCourse = { - settings: { - name: "Test Course", - assignmentGroups: [], - daysOfWeek: [], - startDate: commonDate, - endDate: commonDate, - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [], - pages: [ - { - name: "test page", - text: "test description", - dueAt: commonDate, - }, - ], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "new module", - assignments: [], - quizzes: [], - pages: [ - { - name: "test page", - text: "test description", - dueAt: commonDate, - }, - { - name: "test page 2", - text: "test description", - dueAt: commonDate, - }, - ], - }, - ], - }; - - const differences = CourseDifferences.getNewChanges(newCourse, oldCourse); - - expect(differences.modules).toHaveLength(1); - expect(differences.modules?.[0].pages).toHaveLength(1); - expect(differences.modules?.[0].pages?.[0].name).toBe("test page 2"); - }); -}); diff --git a/nextjs-pages/src/services/tests/courseDifferencesDeletions.test.ts b/nextjs-pages/src/services/tests/courseDifferencesDeletions.test.ts deleted file mode 100644 index d816fbf..0000000 --- a/nextjs-pages/src/services/tests/courseDifferencesDeletions.test.ts +++ /dev/null @@ -1,451 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { LocalCourse } from "@/models/local/localCourse"; -import { CourseDifferences } from "../fileStorage/utils/courseDifferences"; - -describe("CourseDifferencesDeletionsTests", () => { - it("same module does not get deleted", () => { - const oldCourse: LocalCourse = { - settings: { - name: "test course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "test module", - assignments: [], - quizzes: [], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "test module", - assignments: [], - quizzes: [], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getDeletedChanges( - newCourse, - oldCourse - ); - - expect(differences.namesOfModulesToDeleteCompletely).toHaveLength(0); - }); - - it("changed module - old one gets deleted", () => { - const oldCourse: LocalCourse = { - settings: { - name: "test course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "test module", - assignments: [], - quizzes: [], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "test module 2", - assignments: [], - quizzes: [], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getDeletedChanges( - newCourse, - oldCourse - ); - - expect(differences.namesOfModulesToDeleteCompletely).toHaveLength(1); - expect(differences.namesOfModulesToDeleteCompletely[0]).toBe("test module"); - }); - - it("new assignment name gets deleted", () => { - const oldCourse: LocalCourse = { - settings: { - name: "test course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "test module", - assignments: [ - { - name: "test assignment", - description: "test description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "test module", - assignments: [ - { - name: "test assignment changed name", - description: "test description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getDeletedChanges( - newCourse, - oldCourse - ); - - expect(differences.namesOfModulesToDeleteCompletely).toHaveLength(0); - expect(differences.deleteContentsOfModule).toHaveLength(1); - expect(differences.deleteContentsOfModule[0].assignments).toHaveLength(1); - expect(differences.deleteContentsOfModule[0].assignments[0].name).toBe( - "test assignment" - ); - }); - - it("assignments with changed descriptions do not get deleted", () => { - const oldCourse: LocalCourse = { - settings: { - name: "test course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "test module", - assignments: [ - { - name: "test assignment", - description: "test description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "test module", - assignments: [ - { - name: "test assignment", - description: "test description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getDeletedChanges( - newCourse, - oldCourse - ); - - expect(differences.deleteContentsOfModule).toHaveLength(0); - }); - - it("can detect changed and unchanged assignments", () => { - const oldCourse: LocalCourse = { - settings: { - name: "test course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "test module", - assignments: [ - { - name: "test assignment", - description: "test description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - { - name: "test assignment 2", - description: "test description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "test module", - assignments: [ - { - name: "test assignment", - description: "test description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - { - name: "test assignment 2 changed", - description: "test description", - dueAt: "07/09/2024 23:59:00", - submissionTypes: [], - allowedFileUploadExtensions: [], - rubric: [], - }, - ], - quizzes: [], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getDeletedChanges( - newCourse, - oldCourse - ); - - expect(differences.deleteContentsOfModule).toHaveLength(1); - expect(differences.deleteContentsOfModule[0].assignments).toHaveLength(1); - expect(differences.deleteContentsOfModule[0].assignments[0].name).toBe( - "test assignment 2" - ); - }); - - it("changed quizzes get deleted", () => { - const oldCourse: LocalCourse = { - settings: { - name: "test course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "test module", - assignments: [], - quizzes: [ - { - name: "Test Quiz", - description: "test description", - dueAt: "07/09/2024 23:59:00", - shuffleAnswers: false, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: 0, - questions: [], - }, - { - name: "Test Quiz 2", - description: "test description", - dueAt: "07/09/2024 23:59:00", - shuffleAnswers: false, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: 0, - questions: [], - }, - ], - pages: [], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "test module", - assignments: [], - quizzes: [ - { - name: "Test Quiz", - description: "test description", - dueAt: "07/09/2024 23:59:00", - shuffleAnswers: false, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: 0, - questions: [], - }, - { - name: "Test Quiz 3", - description: "test description", - dueAt: "07/09/2024 23:59:00", - shuffleAnswers: false, - showCorrectAnswers: false, - oneQuestionAtATime: false, - allowedAttempts: 0, - questions: [], - }, - ], - pages: [], - }, - ], - }; - - const differences = CourseDifferences.getDeletedChanges( - newCourse, - oldCourse - ); - - expect(differences.deleteContentsOfModule).toHaveLength(1); - expect(differences.deleteContentsOfModule[0].quizzes).toHaveLength(1); - expect(differences.deleteContentsOfModule[0].quizzes[0].name).toBe( - "Test Quiz 2" - ); - }); - - it("changed pages get deleted", () => { - const oldCourse: LocalCourse = { - settings: { - name: "test course", - assignmentGroups: [], - daysOfWeek: [], - startDate: "07/09/2024 23:59:00", - endDate: "07/09/2024 23:59:00", - defaultDueTime: { - hour: 23, - minute: 59, - }, - }, - modules: [ - { - name: "test module", - assignments: [], - quizzes: [], - pages: [ - { - name: "Test Page", - text: "test contents", - dueAt: "07/09/2024 23:59:00", - }, - { - name: "Test Page 2", - text: "test contents", - dueAt: "07/09/2024 23:59:00", - }, - ], - }, - ], - }; - const newCourse: LocalCourse = { - ...oldCourse, - modules: [ - { - name: "test module", - assignments: [], - quizzes: [], - pages: [ - { - name: "Test Page", - text: "test contents", - dueAt: "07/09/2024 23:59:00", - }, - { - name: "Test Page 3", - text: "test contents", - dueAt: "07/09/2024 23:59:00", - }, - ], - }, - ], - }; - - const differences = CourseDifferences.getDeletedChanges( - newCourse, - oldCourse - ); - - expect(differences.deleteContentsOfModule).toHaveLength(1); - expect(differences.deleteContentsOfModule[0].pages).toHaveLength(1); - expect(differences.deleteContentsOfModule[0].pages[0].name).toBe( - "Test Page 2" - ); - }); -}); diff --git a/nextjs-pages/src/services/tests/fileStorage.test.ts b/nextjs-pages/src/services/tests/fileStorage.test.ts deleted file mode 100644 index 1143b16..0000000 --- a/nextjs-pages/src/services/tests/fileStorage.test.ts +++ /dev/null @@ -1,293 +0,0 @@ -// import path from "path"; -// import { describe, it, expect, beforeEach } from "vitest"; -// import fs from "fs"; -// import { DayOfWeek, LocalCourse } from "@/models/local/localCourse"; -// import { AssignmentSubmissionType } from "@/models/local/assignmnet/assignmentSubmissionType"; -// import { QuestionType } from "@/models/local/quiz/localQuizQuestion"; -// import { fileStorageService } from "../fileStorage/fileStorageService"; - -// describe("FileStorageTests", () => { -// beforeEach(() => { -// const storageDirectory = process.env.STORAGE_DIRECTORY ?? "/tmp/canvasManagerTests"; -// if (fs.existsSync(storageDirectory)) { -// fs.rmdirSync(storageDirectory, { recursive: true }); -// } -// fs.mkdirSync(storageDirectory, { recursive: true }); -// }); - -// it("empty course can be saved and loaded", async () => { -// const testCourse: LocalCourse = { -// settings: { -// name: "test empty course", -// assignmentGroups: [], -// daysOfWeek: [], -// startDate: "07/09/2024 23:59:00", -// endDate: "07/09/2024 23:59:00", -// defaultDueTime: { hour: 1, minute: 59 }, -// }, -// modules: [], -// }; - -// await fileStorageService.saveCourseAsync(testCourse); - -// const loadedCourses = await fileStorageService.loadSavedCourses(); -// const loadedCourse = loadedCourses.find( -// (c) => c.settings.name === testCourse.settings.name -// ); - -// expect(loadedCourse).toEqual(testCourse); -// }); - -// it("course settings can be saved and loaded", async () => { -// const testCourse: LocalCourse = { -// settings: { -// assignmentGroups: [], -// name: "Test Course with settings", -// daysOfWeek: [DayOfWeek.Monday, DayOfWeek.Wednesday], -// startDate: "07/09/2024 23:59:00", -// endDate: "07/09/2024 23:59:00", -// defaultDueTime: { hour: 1, minute: 59 }, -// }, -// modules: [], -// }; - -// await fileStorageService.saveCourseAsync(testCourse); - -// const loadedCourses = await fileStorageService.loadSavedCourses(); -// const loadedCourse = loadedCourses.find( -// (c) => c.settings.name === testCourse.settings.name -// ); - -// expect(loadedCourse?.settings).toEqual(testCourse.settings); -// }); - -// it("empty course modules can be saved and loaded", async () => { -// const testCourse: LocalCourse = { -// settings: { -// name: "Test Course with modules", -// assignmentGroups: [], -// daysOfWeek: [], -// startDate: "07/09/2024 23:59:00", -// endDate: "07/09/2024 23:59:00", -// defaultDueTime: { hour: 1, minute: 59 }, -// }, -// modules: [ -// { -// name: "test module 1", -// assignments: [], -// quizzes: [], -// pages: [], -// }, -// ], -// }; - -// await fileStorageService.saveCourseAsync(testCourse); - -// const loadedCourses = await fileStorageService.loadSavedCourses(); -// const loadedCourse = loadedCourses.find( -// (c) => c.settings.name === testCourse.settings.name -// ); - -// expect(loadedCourse?.modules).toEqual(testCourse.modules); -// }); - -// it("course modules with assignments can be saved and loaded", async () => { -// const testCourse: LocalCourse = { -// settings: { -// name: "Test Course with modules and assignments", -// assignmentGroups: [], -// daysOfWeek: [], -// startDate: "07/09/2024 23:59:00", -// endDate: "07/09/2024 23:59:00", -// defaultDueTime: { hour: 1, minute: 59 }, -// }, -// modules: [ -// { -// name: "test module 1 with assignments", -// assignments: [ -// { -// name: "test assignment", -// description: "here is the description", -// dueAt: "07/09/2024 23:59:00", -// lockAt: "07/09/2024 23:59:00", -// submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], -// localAssignmentGroupName: "Final Project", -// rubric: [ -// { points: 4, label: "do task 1" }, -// { points: 2, label: "do task 2" }, -// ], -// allowedFileUploadExtensions: [], -// }, -// ], -// quizzes: [], -// pages: [], -// }, -// ], -// }; - -// await fileStorageService.saveCourseAsync(testCourse); - -// const loadedCourses = await fileStorageService.loadSavedCourses(); -// const loadedCourse = loadedCourses.find( -// (c) => c.settings.name === testCourse.settings.name -// ); - -// expect(loadedCourse?.modules[0].assignments).toEqual( -// testCourse.modules[0].assignments -// ); -// }); - -// it("course modules with quizzes can be saved and loaded", async () => { -// const testCourse: LocalCourse = { -// settings: { -// name: "Test Course with modules and quiz", -// assignmentGroups: [], -// daysOfWeek: [], -// startDate: "07/09/2024 23:59:00", -// endDate: "07/09/2024 23:59:00", -// defaultDueTime: { hour: 1, minute: 59 }, -// }, -// modules: [ -// { -// name: "test module 1 with quiz", -// assignments: [], -// quizzes: [ -// { -// name: "Test Quiz", -// description: "quiz description", -// lockAt: "07/09/2024 12:05:00", -// dueAt: "07/09/2024 12:05:00", -// shuffleAnswers: true, -// oneQuestionAtATime: true, -// localAssignmentGroupName: "Assignments", -// questions: [ -// { -// text: "test essay", -// questionType: QuestionType.ESSAY, -// points: 1, -// answers: [], -// matchDistractors: [], -// }, -// ], -// showCorrectAnswers: false, -// allowedAttempts: 0, -// }, -// ], -// pages: [], -// }, -// ], -// }; - -// await fileStorageService.saveCourseAsync(testCourse); - -// const loadedCourses = await fileStorageService.loadSavedCourses(); -// const loadedCourse = loadedCourses.find( -// (c) => c.settings.name === testCourse.settings.name -// ); - -// expect(loadedCourse?.modules[0].quizzes).toEqual( -// testCourse.modules[0].quizzes -// ); -// }); - -// it("markdown storage fully populated does not lose data", async () => { -// const testCourse: LocalCourse = { -// settings: { -// name: "Test Course with lots of data", -// assignmentGroups: [], -// daysOfWeek: [DayOfWeek.Monday, DayOfWeek.Wednesday], -// startDate: "07/09/2024 23:59:00", -// endDate: "07/09/2024 23:59:00", -// defaultDueTime: { hour: 1, minute: 59 }, -// }, -// modules: [ -// { -// name: "new test module", -// assignments: [ -// { -// name: "test assignment", -// description: "here is the description", -// dueAt: "07/09/2024 23:59:00", -// lockAt: "07/09/2024 23:59:00", -// submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], -// localAssignmentGroupName: "Final Project", -// rubric: [ -// { points: 4, label: "do task 1" }, -// { points: 2, label: "do task 2" }, -// ], -// allowedFileUploadExtensions: [], -// }, -// ], -// quizzes: [ -// { -// name: "Test Quiz", -// description: "quiz description", -// lockAt: "07/09/2024 23:59:00", -// dueAt: "07/09/2024 23:59:00", -// shuffleAnswers: true, -// oneQuestionAtATime: false, -// localAssignmentGroupName: "someId", -// allowedAttempts: -1, -// questions: [ -// { -// text: "test short answer", -// questionType: QuestionType.SHORT_ANSWER, -// points: 1, -// answers: [], -// matchDistractors: [], -// }, -// ], -// showCorrectAnswers: false, -// }, -// ], -// pages: [], -// }, -// ], -// }; - -// await fileStorageService.saveCourseAsync(testCourse); - -// const loadedCourses = await fileStorageService.loadSavedCourses(); -// const loadedCourse = loadedCourses.find( -// (c) => c.settings.name === testCourse.settings.name -// ); - -// expect(loadedCourse).toEqual(testCourse); -// }); - -// it("markdown storage can persist pages", async () => { -// const testCourse: LocalCourse = { -// settings: { -// name: "Test Course with page", -// assignmentGroups: [], -// daysOfWeek: [DayOfWeek.Monday, DayOfWeek.Wednesday], -// startDate: "07/09/2024 23:59:00", -// endDate: "07/09/2024 23:59:00", -// defaultDueTime: { hour: 1, minute: 59 }, -// }, -// modules: [ -// { -// name: "page test module", -// assignments: [], -// quizzes: [], -// pages: [ -// { -// name: "test page persistence", -// dueAt: "07/09/2024 23:59:00", -// text: "this is some\n## markdown\n", -// }, -// ], -// }, -// ], -// }; - -// await fileStorageService.saveCourseAsync(testCourse); - -// const loadedCourses = await fileStorageService.loadSavedCourses(); -// const loadedCourse = loadedCourses.find( -// (c) => c.settings.name === testCourse.settings.name -// ); - -// expect(loadedCourse).toEqual(testCourse); -// }); -// }); diff --git a/nextjs-pages/src/services/utils/queryClient.tsx b/nextjs-pages/src/services/utils/queryClient.tsx deleted file mode 100644 index 269cf20..0000000 --- a/nextjs-pages/src/services/utils/queryClient.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import toast, { ErrorIcon, CheckmarkIcon } from "react-hot-toast"; -import { ReactNode } from "react"; -import { MutationCache, QueryCache, QueryClient } from "@tanstack/react-query"; - -const addErrorAsToast = async (error: any) => { - console.error("error from toast", error); - const message = getErrorMessage(error); - - toast( - (t: any) => ( -
    -
    - -
    -
    -
    {message}
    - -
    -
    - -
    -
    - ), - { - duration: Infinity, - } - ); -}; - -export function getErrorMessage(error: any) { - if (error?.response?.status === 422) { - console.log(error.response.data.detail); - const serializationMessages = error.response.data.detail.map( - (d: any) => `${d.type} - ${d.loc[1]}` - ); - return `Deserialization error on request:\n${serializationMessages.join( - "\n" - )}`; - } - if (typeof error === "string") { - return error; - } - if (error.response?.data.detail) { - if (typeof error.response?.data.detail === "string") { - return error.response?.data.detail; - } else return JSON.stringify(error.response?.data.detail); - } - console.log(error); - return "Error With Request"; -} - -export function createInfoToast( - children: ReactNode, - onClose: () => void = () => {} -) { - const closeHandler = (t: any) => { - toast.dismiss(t.id); - onClose(); - }; - toast( - (t: any) => ( -
    -
    - -
    -
    {children}
    -
    - -
    -
    - ), - { - duration: Infinity, - style: { - maxWidth: "75em", - }, - } - ); -} - -export function createSuccessToast(message: string) { - toast( - (t: any) => ( -
    -
    - -
    -
    {message}
    -
    - -
    -
    - ), - { - duration: Infinity, - style: { - maxWidth: "75em", - }, - } - ); -} - -// export function createQueryClient() { -// return new QueryClient({ -// defaultOptions: { -// queries: { -// refetchOnWindowFocus: false, -// retry: 0, -// }, -// mutations: { -// onError: addErrorAsToast, -// retry: 0, -// }, -// }, -// queryCache: new QueryCache({ -// onError: addErrorAsToast, -// }), -// mutationCache: new MutationCache({ -// onError: addErrorAsToast, -// }), -// }); -// } diff --git a/nextjs-pages/src/styles/globals.css b/nextjs-pages/src/styles/globals.css deleted file mode 100644 index 65ac91e..0000000 --- a/nextjs-pages/src/styles/globals.css +++ /dev/null @@ -1,60 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer utilities { - .text-balance { - text-wrap: balance; - } -} - -/* monaco editor */ -.monaco-editor-background, -.monaco-editor .margin { - background-color: black !important; -} - -h1 { - @apply text-4xl font-bold; -} - -h2 { - @apply text-3xl font-semibold; -} - -h3 { - @apply text-2xl font-semibold; -} - -h4 { - @apply text-xl font-medium; -} - -h5 { - @apply text-lg font-medium; -} - -h6 { - @apply text-base font-medium; -} - -strong { - @apply font-semibold; -} - -ul { - list-style-type: disc; - padding-left: 1.5rem; -} - -ol { - list-style-type: decimal; - padding-left: 1.5rem; -} -hr { - @apply border-t border-gray-200 my-4; -} - -blockquote { - @apply border-l-4 border-gray-300 pl-4 italic text-gray-700; -} diff --git a/nextjs-pages/tailwind.config.ts b/nextjs-pages/tailwind.config.ts deleted file mode 100644 index 7a42052..0000000 --- a/nextjs-pages/tailwind.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Config } from "tailwindcss"; -import { borderRadius } from "tailwindcss/defaultTheme"; - - -const config: Config = { - content: [ - "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", - "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - borderRadius: { - ...borderRadius, - xl: "24px", - }, - extend: { - }, - }, - plugins: [], -}; -export default config; diff --git a/nextjs-pages/tsconfig.json b/nextjs-pages/tsconfig.json deleted file mode 100644 index fb68dc1..0000000 --- a/nextjs-pages/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "paths": { - "@/*": ["./src/*"] - } - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] -} diff --git a/nextjs-pages/vitest.config.ts b/nextjs-pages/vitest.config.ts deleted file mode 100644 index 860c858..0000000 --- a/nextjs-pages/vitest.config.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { loadEnvConfig } from "@next/env"; -import { defineConfig } from "vitest/config"; -import react from "@vitejs/plugin-react"; - -loadEnvConfig(process.cwd()); - -export default defineConfig({ - plugins: [react()], - resolve: { - alias: { - "@": "/src", - }, - }, - test: { - environment: "jsdom", - }, -});